zinkee 0.1.34 → 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,55 +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
- ]
2658
+ "values": {
2659
+ "contact-name": "Ada Lovelace",
2660
+ "contact-email": "ada@example.com"
2661
+ }
2844
2662
  }`,
2845
2663
  response: `{
2846
- "created": [
2847
- "550e8400-e29b-41d4-a716-446655440000"
2848
- ],
2849
- "errors": []
2664
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
2665
+ "values": {
2666
+ "contact-name": "Ada Lovelace",
2667
+ "contact-email": "ada@example.com"
2668
+ }
2850
2669
  }`
2851
2670
  },
2852
2671
  {
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 must match the target's current targetDisplayField.",
2854
- command: `zinkee --json records create contacts --records-file ./records.json`,
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`,
2855
2674
  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
- ]
2871
- }`,
2872
- 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
- ]
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
+ }
2884
2684
  }`
2885
2685
  }
2886
2686
  ]),
@@ -3063,10 +2863,11 @@ var specificExamples = {
3063
2863
  ]),
3064
2864
  "navigation resources move": buildCommandExamples([
3065
2865
  {
3066
- description: "Move a schema into a navigation folder. Only schemas can be moved; the navigation menu holds databases.",
3067
- 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",
3068
2868
  raw: `{
3069
2869
  "resourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
2870
+ "resourceType": "SCHEMA",
3070
2871
  "targetFolderId": "84a0fca4-37ef-4c83-a8ed-9ef67ad9324a"
3071
2872
  }`,
3072
2873
  response: `{
@@ -3075,11 +2876,39 @@ var specificExamples = {
3075
2876
  }`
3076
2877
  },
3077
2878
  {
3078
- description: "Move a schema back to the root folder (root is always UUID 00000000-0000-0000-0000-000000000000).",
3079
- 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",
3080
2899
  raw: `{
3081
2900
  "resourceId": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
2901
+ "resourceType": "SCHEMA",
3082
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"
3083
2912
  }`
3084
2913
  }
3085
2914
  ]),
@@ -3477,12 +3306,12 @@ var specificExamples = {
3477
3306
  }`
3478
3307
  },
3479
3308
  {
3480
- description: "Change a DATE variable to use last12Months.",
3481
- 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",
3482
3311
  raw: `{
3483
3312
  "date": {
3484
3313
  "mode": "dynamic",
3485
- "dynamicOption": "last12Months"
3314
+ "dynamicOption": "lastWeek"
3486
3315
  }
3487
3316
  }`
3488
3317
  }
@@ -3490,7 +3319,7 @@ var specificExamples = {
3490
3319
  "displays widgets create": buildCommandExamples([
3491
3320
  {
3492
3321
  description: "Create a TABLE widget (CLI normalises --type table to TABLE_OR_SUBTABLE).",
3493
- 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"}'`,
3494
3323
  raw: `{
3495
3324
  "type": "TABLE_OR_SUBTABLE",
3496
3325
  "source": {
@@ -3505,11 +3334,11 @@ var specificExamples = {
3505
3334
  },
3506
3335
  "query": {
3507
3336
  "sorts": [
3508
- { "fieldId": "contact-name", "direction": "ASC" }
3337
+ { "fieldId": "id", "direction": "DESC" }
3509
3338
  ]
3510
3339
  },
3511
3340
  "view": {
3512
- "fields": ["contact-name", "status", "amount"]
3341
+ "fields": ["id", "contact-name", "status"]
3513
3342
  }
3514
3343
  }`,
3515
3344
  response: `{
@@ -3558,38 +3387,8 @@ var specificExamples = {
3558
3387
  }`
3559
3388
  },
3560
3389
  {
3561
- description: "Create a CHART widget with a daily time-serie x-axis.",
3562
- 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"}'`,
3563
- raw: `{
3564
- "type": "CHART",
3565
- "source": {
3566
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3567
- "isOriginSubSchema": false
3568
- },
3569
- "placement": {
3570
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3571
- },
3572
- "presentation": { "name": "Revenue by day" },
3573
- "chart": {
3574
- "chartType": "lines",
3575
- "xAxisFieldId": "due-date",
3576
- "xAxisDateFormat": "DATE",
3577
- "xAxisAsTimeSerie": true,
3578
- "yAxisSeries": [
3579
- {
3580
- "typeCalc": "SUM",
3581
- "fieldCalc": "amount",
3582
- "color": "#4B9CD3",
3583
- "axisType": "PRIMARY"
3584
- }
3585
- ],
3586
- "legend": { "position": "bottom" }
3587
- }
3588
- }`
3589
- },
3590
- {
3591
- description: "Create a bars CHART widget with a monthly time-serie x-axis and two y-axis series.",
3592
- 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"}'`,
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"}'`,
3593
3392
  raw: `{
3594
3393
  "type": "CHART",
3595
3394
  "source": {
@@ -3603,7 +3402,7 @@ var specificExamples = {
3603
3402
  "chart": {
3604
3403
  "chartType": "bars",
3605
3404
  "xAxisFieldId": "due-date",
3606
- "xAxisDateFormat": "MONTH_YEAR",
3405
+ "xAxisDateFormat": "MONTH",
3607
3406
  "xAxisAsTimeSerie": true,
3608
3407
  "yAxisSeries": [
3609
3408
  {
@@ -3614,7 +3413,7 @@ var specificExamples = {
3614
3413
  },
3615
3414
  {
3616
3415
  "typeCalc": "COUNT",
3617
- "fieldCalc": "contact-name",
3416
+ "fieldCalc": "id",
3618
3417
  "color": "#E57373",
3619
3418
  "axisType": "SECONDARY"
3620
3419
  }
@@ -3624,70 +3423,59 @@ var specificExamples = {
3624
3423
  }`
3625
3424
  },
3626
3425
  {
3627
- description: "Create a bars CHART widget with a quarterly time-serie x-axis.",
3628
- 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"}'`,
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`,
3629
3428
  raw: `{
3630
- "type": "CHART",
3429
+ "type": "TIMELINE",
3631
3430
  "source": {
3632
3431
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3633
3432
  "isOriginSubSchema": false
3634
3433
  },
3635
3434
  "placement": {
3636
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3435
+ "layout": { "x": 0, "y": 0, "w": 12, "h": 6 }
3637
3436
  },
3638
- "presentation": { "name": "Revenue by quarter" },
3639
- "chart": {
3640
- "chartType": "bars",
3641
- "xAxisFieldId": "due-date",
3642
- "xAxisDateFormat": "QUARTER_YEAR",
3643
- "xAxisAsTimeSerie": true,
3644
- "yAxisSeries": [
3645
- {
3646
- "typeCalc": "SUM",
3647
- "fieldCalc": "amount",
3648
- "color": "#4B9CD3",
3649
- "axisType": "PRIMARY"
3650
- }
3651
- ],
3652
- "legend": { "position": "bottom" }
3437
+ "presentation": { "name": "Customer schedule" },
3438
+ "view": {
3439
+ "fields": ["contact-name", "due-date"]
3653
3440
  }
3654
3441
  }`
3655
3442
  },
3656
3443
  {
3657
- description: "Create a CHART widget with a yearly time-serie x-axis.",
3658
- 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"}'`,
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}}}'`,
3659
3446
  raw: `{
3660
- "type": "CHART",
3447
+ "type": "KANBAN",
3661
3448
  "source": {
3662
3449
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3663
3450
  "isOriginSubSchema": false
3664
3451
  },
3665
3452
  "placement": {
3666
- "layout": { "x": 0, "y": 0, "w": 8, "h": 6 }
3453
+ "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
3667
3454
  },
3668
- "presentation": { "name": "Revenue by year" },
3669
- "chart": {
3670
- "chartType": "lines",
3671
- "xAxisFieldId": "due-date",
3672
- "xAxisDateFormat": "YEAR",
3673
- "xAxisAsTimeSerie": true,
3674
- "yAxisSeries": [
3455
+ "presentation": { "name": "Status board" },
3456
+ "query": {
3457
+ "filters": [
3675
3458
  {
3676
- "typeCalc": "SUM",
3677
- "fieldCalc": "amount",
3678
- "color": "#4B9CD3",
3679
- "axisType": "PRIMARY"
3459
+ "origin": {
3460
+ "schemaId": "contacts",
3461
+ "fieldId": "status"
3462
+ },
3463
+ "comparisonOperator": "ANY_OF",
3464
+ "values": ["1", "2", "3"]
3680
3465
  }
3681
- ],
3682
- "legend": { "position": "bottom" }
3466
+ ]
3467
+ },
3468
+ "view": {
3469
+ "fields": ["contact-name", "status", "amount"],
3470
+ "groupsExpanded": { "1": true, "2": true, "3": false }
3683
3471
  }
3684
3472
  }`
3685
3473
  },
3686
3474
  {
3687
- 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* ...).",
3688
- 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}'`,
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"}}}'`,
3689
3477
  raw: `{
3690
- "type": "TIMELINE",
3478
+ "type": "HIERARCHY",
3691
3479
  "source": {
3692
3480
  "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3693
3481
  "isOriginSubSchema": false
@@ -3695,154 +3483,26 @@ var specificExamples = {
3695
3483
  "placement": {
3696
3484
  "layout": { "x": 0, "y": 0, "w": 12, "h": 6 }
3697
3485
  },
3698
- "presentation": { "name": "Customer schedule" },
3486
+ "presentation": { "name": "Org tree" },
3699
3487
  "view": {
3700
- "fields": [
3701
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3702
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3703
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3704
- "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3705
- ],
3706
- "viewAdditionalProperties": {
3707
- "viewState": {
3708
- "granularity": "month",
3709
- "sidebarWidth": 300,
3710
- "showUngroupedEvents": true,
3711
- "showUnsubgroupedEvents": true,
3712
- "fieldMapping": {
3713
- "startDateField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3714
- "endDateField": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012",
3715
- "labelField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3716
- "groupField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3717
- "subgroupField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3718
- "progressField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3719
- "cardConfig": {
3720
- "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3721
- "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3722
- "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3723
- "category4Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3724
- "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3725
- }
3726
- }
3727
- }
3488
+ "fields": ["contact-name", "status"],
3489
+ "hierarchyConfig": {
3490
+ "parentFieldId": "contact-name"
3728
3491
  }
3729
3492
  }
3730
3493
  }`
3731
- },
3494
+ }
3495
+ ]),
3496
+ "displays widgets update": buildCommandExamples([
3732
3497
  {
3733
- 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.",
3734
- 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}'`,
3735
- raw: `{
3736
- "type": "KANBAN",
3737
- "source": {
3738
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3739
- "isOriginSubSchema": false
3740
- },
3741
- "placement": {
3742
- "layout": { "x": 0, "y": 0, "w": 12, "h": 8 }
3743
- },
3744
- "presentation": { "name": "Status board" },
3745
- "view": {
3746
- "fields": [
3747
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3748
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3749
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3750
- "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
3751
- ],
3752
- "viewAdditionalProperties": {
3753
- "viewState": {
3754
- "hideEmptyColumns": false,
3755
- "showNoValueColumn": true,
3756
- "showNoValueSwimlane": true,
3757
- "fieldMapping": {
3758
- "columnField": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3759
- "swimlaneField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3760
- "cardConfig": {
3761
- "titleField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3762
- "category1Field": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3763
- "category2Field": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3764
- "category3Field": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
3765
- "descriptionField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
3766
- },
3767
- "aggregationConfig": {
3768
- "method": "sum",
3769
- "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3770
- }
3771
- }
3772
- }
3773
- }
3774
- }
3775
- }`
3776
- },
3777
- {
3778
- 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.",
3779
- 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"}]}'`,
3780
- raw: `{
3781
- "type": "HIERARCHY",
3782
- "source": {
3783
- "originResourceId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3784
- "isOriginSubSchema": false
3785
- },
3786
- "placement": {
3787
- "layout": { "x": 0, "y": 0, "w": 12, "h": 6 }
3788
- },
3789
- "presentation": { "name": "Org tree" },
3790
- "view": {
3791
- "fields": [
3792
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3793
- "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3794
- "c52efe3f-2825-4c60-a7e3-34dd4c1ce043"
3795
- ],
3796
- "hierarchyConfig": {
3797
- "columns": {
3798
- "label": "Name",
3799
- "infos": [
3800
- { "id": "col_1779975207355_zfndknslw", "name": "Status" },
3801
- { "id": "col_1779975243018_qm4t7xb2pa", "name": "Description" }
3802
- ],
3803
- "numbers": [
3804
- { "id": "col_1779975261490_h8kd3nv9ws", "name": "Total amount", "aggregation": "SUM" }
3805
- ]
3806
- },
3807
- "rootLevel": {
3808
- "name": "Customers",
3809
- "labelFieldId": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3810
- "infoMappings": [
3811
- { "columnId": "col_1779975207355_zfndknslw", "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890" }
3812
- ],
3813
- "numberMappings": [
3814
- { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043" }
3815
- ]
3816
- },
3817
- "childLevels": [
3818
- {
3819
- "name": "Projects",
3820
- "schemaId": "3ec9cdef-7e0a-4cdd-8019-8fb9281f5d6f",
3821
- "childFieldId": "80deefae-af3d-4000-b322-bfe1594f8073",
3822
- "labelFieldId": "50dbef0b-7e0a-4fdd-8019-8fb9281f5d70",
3823
- "infoMappings": [
3824
- { "columnId": "col_1779975243018_qm4t7xb2pa", "fieldId": "60dcef0c-8f1b-4eee-9120-9fc0392f6e71" }
3825
- ],
3826
- "numberMappings": [
3827
- { "columnId": "col_1779975261490_h8kd3nv9ws", "fieldId": "70ddef0d-9f2c-4fff-a221-afd0493f7f72" }
3828
- ]
3829
- }
3830
- ]
3831
- }
3832
- }
3833
- }`
3834
- }
3835
- ]),
3836
- "displays widgets update": buildCommandExamples([
3837
- {
3838
- description: "Move placement, update view columns, rename the widget and lock it.",
3839
- 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`,
3498
+ description: "Move placement, update view columns, rename the widget and lock it.",
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`,
3840
3500
  raw: `{
3841
3501
  "placement": {
3842
3502
  "layout": { "x": 1, "y": 2, "w": 8, "h": 4 }
3843
3503
  },
3844
3504
  "view": {
3845
- "fields": ["contact-name", "status", "amount"]
3505
+ "fields": ["id", "contact-name", "status"]
3846
3506
  },
3847
3507
  "presentation": { "name": "Revenue Updated" },
3848
3508
  "behavior": { "readOnly": true }
@@ -3853,38 +3513,29 @@ var specificExamples = {
3853
3513
  }`
3854
3514
  },
3855
3515
  {
3856
- description: "Add query filters with --filter. The CLI parses the expression and emits the structured comparisonOperator payload the API expects.",
3857
- 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"]}]}}'`,
3858
3518
  raw: `{
3859
3519
  "query": {
3860
3520
  "filters": [
3861
3521
  {
3862
- "origin": { "fieldId": "status" },
3522
+ "origin": {
3523
+ "schemaId": "contacts",
3524
+ "fieldId": "status"
3525
+ },
3863
3526
  "comparisonOperator": "EQUAL",
3864
3527
  "values": ["2"]
3865
3528
  },
3866
3529
  {
3867
- "origin": { "fieldId": "amount" },
3530
+ "origin": {
3531
+ "schemaId": "contacts",
3532
+ "fieldId": "amount"
3533
+ },
3868
3534
  "comparisonOperator": "GREATER_OR_EQUAL",
3869
3535
  "values": ["500"]
3870
3536
  }
3871
3537
  ]
3872
3538
  }
3873
- }`
3874
- },
3875
- {
3876
- description: "Fall back to --raw for comparators the parser does not cover yet (e.g. NOT_CONTAINS, RANGE).",
3877
- 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"]}]}}'`,
3878
- raw: `{
3879
- "query": {
3880
- "filters": [
3881
- {
3882
- "origin": { "fieldId": "due-date" },
3883
- "comparisonOperator": "RANGE",
3884
- "values": ["2025-01-01", "2025-12-31"]
3885
- }
3886
- ]
3887
- }
3888
3539
  }`
3889
3540
  },
3890
3541
  {
@@ -3910,13 +3561,13 @@ var specificExamples = {
3910
3561
  }`
3911
3562
  },
3912
3563
  {
3913
- description: "Replace the chart series with quarterly lines.",
3914
- 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"}'`,
3915
3566
  raw: `{
3916
3567
  "chart": {
3917
3568
  "chartType": "lines",
3918
3569
  "xAxisFieldId": "due-date",
3919
- "xAxisDateFormat": "QUARTER_YEAR",
3570
+ "xAxisDateFormat": "WEEK",
3920
3571
  "xAxisAsTimeSerie": true,
3921
3572
  "yAxisSeries": [
3922
3573
  {
@@ -4082,7 +3733,6 @@ var specificExamples = {
4082
3733
  },
4083
3734
  "auditable": true,
4084
3735
  "commentable": true,
4085
- "highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4086
3736
  "fields": [
4087
3737
  {
4088
3738
  "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
@@ -4391,10 +4041,6 @@ var specificExamples = {
4391
4041
  "conditionalFormatting": []
4392
4042
  }
4393
4043
  }
4394
- ],
4395
- "uniqueFields": [
4396
- "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4397
- "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
4398
4044
  ]
4399
4045
  }`
4400
4046
  }
@@ -4553,24 +4199,10 @@ var specificExamples = {
4553
4199
  ]),
4554
4200
  "records delete": buildCommandExamples([
4555
4201
  {
4556
- description: "Delete one or more records by id (--record is repeatable).",
4557
- command: `zinkee --json records delete contacts --record 550e8400-e29b-41d4-a716-446655440000 --record 6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
4558
- response: `{
4559
- "recordIds": [
4560
- "550e8400-e29b-41d4-a716-446655440000",
4561
- "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
4562
- ],
4563
- "deleted": true
4564
- }`
4565
- },
4566
- {
4567
- description: "Delete many records listing one uuid per line in a file (merged with any --record flags and de-duplicated).",
4568
- 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}`,
4569
4204
  response: `{
4570
- "recordIds": [
4571
- "550e8400-e29b-41d4-a716-446655440000",
4572
- "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
4573
- ],
4205
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
4574
4206
  "deleted": true
4575
4207
  }`
4576
4208
  }
@@ -4666,7 +4298,7 @@ var specificExamples = {
4666
4298
  "resources": [
4667
4299
  {
4668
4300
  "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4669
- "name": "Customer records",
4301
+ "name": "Contacts",
4670
4302
  "type": "SCHEMA",
4671
4303
  "isInSpace": false,
4672
4304
  "additionalProperties": {}
@@ -4690,10 +4322,19 @@ var specificExamples = {
4690
4322
  "resources": [
4691
4323
  {
4692
4324
  "id": "3f8a2c1b-9d4e-4a5b-8c6d-7e8f90123456",
4693
- "name": "Shipments",
4694
- "type": "SCHEMA",
4325
+ "name": "Quote approval",
4326
+ "type": "WORKFLOW",
4695
4327
  "isInSpace": false,
4696
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
+ }
4697
4338
  }
4698
4339
  ],
4699
4340
  "additionalProperties": {
@@ -4740,13 +4381,8 @@ var specificExamples = {
4740
4381
  "name": "Shared Dashboards",
4741
4382
  "order": 1,
4742
4383
  "isRoot": false,
4743
- "resourceCount": 2,
4384
+ "resourceCount": 1,
4744
4385
  "resources": [
4745
- {
4746
- "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4747
- "name": "Customer records",
4748
- "type": "SCHEMA"
4749
- },
4750
4386
  {
4751
4387
  "id": "0f6f062f-1478-4df2-96a1-c495d037d260",
4752
4388
  "name": "Executive Revenue",
@@ -4918,7 +4554,7 @@ var specificExamples = {
4918
4554
  "hideDeleteButton": false
4919
4555
  },
4920
4556
  "view": {
4921
- "fields": ["contact-name", "status", "amount"],
4557
+ "fields": ["id", "contact-name", "status", "amount"],
4922
4558
  "columnSize": { "contact-name": 240 }
4923
4559
  }
4924
4560
  }
@@ -4965,83 +4601,6 @@ var specificExamples = {
4965
4601
  command: "zinkee --json displays delete 0f6f062f-1478-4df2-96a1-c495d037d260"
4966
4602
  }
4967
4603
  ]),
4968
- "displays folders list": buildCommandExamples([
4969
- {
4970
- description: "List flat display folders (non-root folders plus the root bucket).",
4971
- command: "zinkee --json displays folders list",
4972
- response: `[
4973
- {
4974
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
4975
- "name": "Executive Dashboards",
4976
- "isRoot": false,
4977
- "displayCount": 2
4978
- },
4979
- {
4980
- "id": "8b22282b-3db3-4dd7-87f7-b29365dcf3f6",
4981
- "name": null,
4982
- "isRoot": true,
4983
- "displayCount": 4
4984
- }
4985
- ]`
4986
- }
4987
- ]),
4988
- "displays folders create": buildCommandExamples([
4989
- {
4990
- description: "Create one flat display folder.",
4991
- command: 'zinkee --json displays folders create --name "Executive Dashboards"',
4992
- raw: `{
4993
- "name": "Executive Dashboards"
4994
- }`,
4995
- response: `{
4996
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
4997
- "name": "Executive Dashboards",
4998
- "isRoot": false,
4999
- "displayCount": 0
5000
- }`
5001
- }
5002
- ]),
5003
- "displays folders update": buildCommandExamples([
5004
- {
5005
- description: "Rename a display folder. The folder argument accepts a UUID or an exact name.",
5006
- command: 'zinkee --json displays folders update "Executive Dashboards" --name "Executive Dashboards (2026)"',
5007
- raw: `{
5008
- "name": "Executive Dashboards (2026)"
5009
- }`,
5010
- response: `{
5011
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5012
- "name": "Executive Dashboards (2026)",
5013
- "isRoot": false,
5014
- "displayCount": 2
5015
- }`
5016
- }
5017
- ]),
5018
- "displays folders delete": buildCommandExamples([
5019
- {
5020
- description: "Delete a non-root display folder. Its displays move back to the root folder.",
5021
- command: 'zinkee --json displays folders delete "Executive Dashboards"',
5022
- response: `{
5023
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5024
- "name": "Executive Dashboards",
5025
- "isRoot": false,
5026
- "displayCount": 2
5027
- }`
5028
- }
5029
- ]),
5030
- "displays folders move": buildCommandExamples([
5031
- {
5032
- description: "Move one display into a target folder by exact folder name.",
5033
- command: 'zinkee --json displays folders move 0f6f062f-1478-4df2-96a1-c495d037d260 --to "Executive Dashboards"',
5034
- raw: `{
5035
- "displayId": "0f6f062f-1478-4df2-96a1-c495d037d260",
5036
- "targetFolderId": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e"
5037
- }`,
5038
- response: `{
5039
- "id": "e7a1c3d2-5f4b-4a6c-9d8e-1f2a3b4c5d6e",
5040
- "name": "Executive Dashboards",
5041
- "isRoot": false
5042
- }`
5043
- }
5044
- ]),
5045
4604
  "displays layout get": buildCommandExamples([
5046
4605
  {
5047
4606
  description: "Get the layout block of a display (template + tabs/freeformLayouts/slots).",
@@ -5135,7 +4694,7 @@ var specificExamples = {
5135
4694
  "hideDeleteButton": false
5136
4695
  },
5137
4696
  "view": {
5138
- "fields": ["contact-name", "status", "amount"],
4697
+ "fields": ["id", "contact-name", "status", "amount"],
5139
4698
  "columnSize": { "contact-name": 240 }
5140
4699
  }
5141
4700
  }`
@@ -5792,43 +5351,6 @@ var specificExamples = {
5792
5351
  "steps": ["one", "two"]
5793
5352
  }
5794
5353
  }
5795
- }`
5796
- },
5797
- {
5798
- 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.",
5799
- 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."`,
5800
- raw: `{
5801
- "type": "send_message",
5802
- "name": "Notify customer",
5803
- "config": {
5804
- "fieldMapping": {
5805
- "recipients": {
5806
- "rawValue": "customer@example.com",
5807
- "source": null
5808
- },
5809
- "subject": {
5810
- "rawValue": "Your order status has changed",
5811
- "source": null
5812
- },
5813
- "body": {
5814
- "rawValue": "Hello, your order is now processed.",
5815
- "source": null
5816
- }
5817
- }
5818
- }
5819
- }`
5820
- },
5821
- {
5822
- 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.",
5823
- 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',
5824
- raw: `{
5825
- "type": "generate_document",
5826
- "name": "Generate invoice PDF",
5827
- "config": {
5828
- "documentTemplateId": "6c08673e-f8a6-44d2-8c91-d09eca911f8f",
5829
- "targetSchemaId": "68d2c7be-4392-42de-b5ae-625ad79cfc3c",
5830
- "targetFileFieldId": "c8edbde8-a361-4e9f-a39a-2e88971f21a7"
5831
- }
5832
5354
  }`
5833
5355
  }
5834
5356
  ]),
@@ -5879,30 +5401,6 @@ var specificExamples = {
5879
5401
  "authMode": "STORED",
5880
5402
  "connectionId": "connection-1"
5881
5403
  }
5882
- }`
5883
- },
5884
- {
5885
- description: "Replace a send-message action. --to maps to fieldMapping.recipients and --message maps to fieldMapping.body; values are wrapped in {rawValue, source}.",
5886
- 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."`,
5887
- raw: `{
5888
- "type": "send_message",
5889
- "name": "Notify customer",
5890
- "config": {
5891
- "fieldMapping": {
5892
- "recipients": {
5893
- "rawValue": "customer@example.com",
5894
- "source": null
5895
- },
5896
- "subject": {
5897
- "rawValue": "Your order status has changed",
5898
- "source": null
5899
- },
5900
- "body": {
5901
- "rawValue": "Hello, your order is now processed.",
5902
- "source": null
5903
- }
5904
- }
5905
- }
5906
5404
  }`
5907
5405
  }
5908
5406
  ]),
@@ -6055,8 +5553,7 @@ var specificExamples = {
6055
5553
  description: "Move one automation into a target folder by exact folder name.",
6056
5554
  command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
6057
5555
  raw: `{
6058
- "automationId": "automation-1",
6059
- "targetFolderId": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f"
5556
+ "automationId": "automation-1"
6060
5557
  }`,
6061
5558
  response: `{
6062
5559
  "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
@@ -6064,171 +5561,6 @@ var specificExamples = {
6064
5561
  "isRoot": false
6065
5562
  }`
6066
5563
  }
6067
- ]),
6068
- "document-templates list": buildCommandExamples([
6069
- {
6070
- 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.",
6071
- command: "zinkee --json document-templates list",
6072
- response: `[
6073
- {
6074
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6075
- "name": "Quarterly report",
6076
- "assets": [
6077
- {
6078
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6079
- "name": "Requirements.docx",
6080
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6081
- }
6082
- ],
6083
- "createdAt": "2026-01-15T10:00:00Z",
6084
- "updatedAt": "2026-01-20T14:30:00Z",
6085
- "createdBy": "creator@example.com",
6086
- "updatedBy": "updater@example.com"
6087
- }
6088
- ]`
6089
- }
6090
- ]),
6091
- "document-templates get": buildCommandExamples([
6092
- {
6093
- description: "Look up one template by UUID. The CLI filters the list endpoint locally (the backend does not expose a get-one route).",
6094
- command: "zinkee --json document-templates get 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6095
- response: `{
6096
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6097
- "name": "Quarterly report",
6098
- "assets": [
6099
- {
6100
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6101
- "name": "Requirements.docx",
6102
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6103
- }
6104
- ],
6105
- "createdAt": "2026-01-15T10:00:00Z",
6106
- "updatedAt": "2026-01-20T14:30:00Z",
6107
- "createdBy": "creator@example.com",
6108
- "updatedBy": "creator@example.com"
6109
- }`
6110
- },
6111
- {
6112
- description: "Look up by exact template name. Names are unique within the workspace; ambiguity is reported as an error.",
6113
- command: 'zinkee --json document-templates get "Quarterly report"'
6114
- }
6115
- ]),
6116
- "document-templates create": buildCommandExamples([
6117
- {
6118
- description: "Typical create: empty template by name. Assets are uploaded afterwards via document-templates assets add.",
6119
- command: 'zinkee --json document-templates create --name "Quarterly report"',
6120
- raw: `{
6121
- "name": "Quarterly report",
6122
- "assets": []
6123
- }`,
6124
- response: `{
6125
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6126
- "name": "Quarterly report",
6127
- "assets": [],
6128
- "createdAt": "2026-01-15T10:00:00Z",
6129
- "updatedAt": "2026-01-15T10:00:00Z",
6130
- "createdBy": "creator@example.com",
6131
- "updatedBy": "creator@example.com"
6132
- }`
6133
- },
6134
- {
6135
- 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.",
6136
- 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"}]}'`,
6137
- raw: `{
6138
- "name": "Annual report",
6139
- "assets": [
6140
- {
6141
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6142
- "name": "Cover.docx",
6143
- "link": "/existing/cover.docx"
6144
- },
6145
- {
6146
- "id": "3f2e1d0c-9b8a-7654-3210-fedcba987654",
6147
- "name": "Appendix.docx",
6148
- "link": "/existing/appendix.docx"
6149
- }
6150
- ]
6151
- }`
6152
- }
6153
- ]),
6154
- "document-templates update": buildCommandExamples([
6155
- {
6156
- 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.",
6157
- command: 'zinkee --json document-templates update "Quarterly report" --name "Annual report"',
6158
- raw: `{
6159
- "name": "Annual report"
6160
- }`,
6161
- response: `{
6162
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6163
- "name": "Annual report",
6164
- "assets": [
6165
- {
6166
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6167
- "name": "Requirements.docx",
6168
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6169
- }
6170
- ],
6171
- "createdAt": "2026-01-15T10:00:00Z",
6172
- "updatedAt": "2026-01-22T09:15:00Z",
6173
- "createdBy": "creator@example.com",
6174
- "updatedBy": "updater@example.com"
6175
- }`
6176
- }
6177
- ]),
6178
- "document-templates delete": buildCommandExamples([
6179
- {
6180
- description: "Delete a template and remove its asset files from storage. Record fields that reference previously generated documents are not modified.",
6181
- command: "zinkee --json document-templates delete 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6182
- response: `{
6183
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6184
- "deleted": true
6185
- }`
6186
- }
6187
- ]),
6188
- "document-templates assets add": buildCommandExamples([
6189
- {
6190
- 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.',
6191
- command: 'zinkee --json document-templates assets add "Quarterly report" ./contract.docx',
6192
- response: `{
6193
- "id": "7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e",
6194
- "name": "Quarterly report",
6195
- "assets": [
6196
- {
6197
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6198
- "name": "contract.docx",
6199
- "link": "/api/v2/document-templates/7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e/assets/9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f/download"
6200
- }
6201
- ],
6202
- "createdAt": "2026-01-15T10:00:00Z",
6203
- "updatedAt": "2026-01-22T09:15:00Z",
6204
- "createdBy": "creator@example.com",
6205
- "updatedBy": "updater@example.com"
6206
- }`
6207
- },
6208
- {
6209
- description: "Override the asset display name with --name (otherwise the uploaded filename is used).",
6210
- command: 'zinkee --json document-templates assets add "Quarterly report" ./contract.docx --name "Customer Contract"'
6211
- }
6212
- ]),
6213
- "document-templates assets delete": buildCommandExamples([
6214
- {
6215
- description: "Delete one asset from a template and remove its file from storage.",
6216
- command: "zinkee --json document-templates assets delete 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6217
- response: `{
6218
- "id": "9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
6219
- "deleted": true
6220
- }`
6221
- }
6222
- ]),
6223
- "document-templates assets download": buildCommandExamples([
6224
- {
6225
- 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.",
6226
- command: "zinkee --json document-templates assets download 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f --output ./contract.docx"
6227
- },
6228
- {
6229
- description: "Stream asset bytes to stdout (omit --json and --output). Useful for piping into other tools.",
6230
- command: "zinkee document-templates assets download 7c4a8d3f-1b2e-4a5c-9d6e-1f2a3b4c5d6e 9e8d7c6b-5a4f-3e2d-1c0b-9a8b7c6d5e4f > contract.docx"
6231
- }
6232
5564
  ])
6233
5565
  };
6234
5566
  function fallbackExamples(commandName) {
@@ -6348,7 +5680,7 @@ ${index + 1}. ${example.description}
6348
5680
 
6349
5681
  // src/program.ts
6350
5682
  import { createRequire } from "module";
6351
- import { Command as Command11 } from "commander";
5683
+ import { Command as Command10 } from "commander";
6352
5684
 
6353
5685
  // src/config.ts
6354
5686
  import { mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -6702,7 +6034,7 @@ var AutomationsApi = class {
6702
6034
  }
6703
6035
  moveAutomation(input) {
6704
6036
  return this.client.requestJson(
6705
- "/api/v2/automation-folders/automations:move",
6037
+ `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
6706
6038
  jsonOptions(input, "POST")
6707
6039
  );
6708
6040
  }
@@ -7109,11 +6441,11 @@ function hasSetPath(target, path) {
7109
6441
  return Object.hasOwn(target, path);
7110
6442
  }
7111
6443
  let current = target;
7112
- for (const segment4 of segments) {
7113
- if (!isJsonObject2(current) || !Object.hasOwn(current, segment4)) {
6444
+ for (const segment3 of segments) {
6445
+ if (!isJsonObject2(current) || !Object.hasOwn(current, segment3)) {
7114
6446
  return false;
7115
6447
  }
7116
- current = current[segment4];
6448
+ current = current[segment3];
7117
6449
  }
7118
6450
  return true;
7119
6451
  }
@@ -7576,15 +6908,6 @@ function buildActionInput(options, mode) {
7576
6908
  if (options.targetSchema !== void 0) {
7577
6909
  config.targetSchemaId = options.targetSchema;
7578
6910
  }
7579
- if (options.to !== void 0) {
7580
- mappings.recipients = options.to;
7581
- }
7582
- if (options.subject !== void 0) {
7583
- mappings.subject = options.subject;
7584
- }
7585
- if (options.message !== void 0) {
7586
- mappings.body = options.message;
7587
- }
7588
6911
  if (!isEmptyObject(mappings)) {
7589
6912
  config.fieldMapping = mappings;
7590
6913
  }
@@ -7628,12 +6951,6 @@ function buildActionInput(options, mode) {
7628
6951
  if (!isEmptyObject(args)) {
7629
6952
  config.pluginArgs = args;
7630
6953
  }
7631
- if (options.documentTemplate !== void 0) {
7632
- config.documentTemplateId = options.documentTemplate;
7633
- }
7634
- if (options.targetFileField !== void 0) {
7635
- config.targetFileFieldId = options.targetFileField;
7636
- }
7637
6954
  if (!isEmptyObject(config)) {
7638
6955
  if (isJsonObject2(config.fieldMapping)) {
7639
6956
  config.fieldMapping = normalizeAutomationFieldMapping(
@@ -7820,35 +7137,19 @@ function addTriggerPayloadOptions(command) {
7820
7137
  []
7821
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");
7822
7139
  }
7823
- var ACTION_TYPES_HELP = `
7824
- Action types and their flags:
7825
- create_record --target-schema, --map, --map-json
7826
- update_record --target-schema, --use-trigger-record, --map,
7827
- --condition, --condition-json
7828
- search_records --target-schema, --condition, --condition-json
7829
- send_message --to, --subject, --message
7830
- (--map / --map-json also accepted for extra keys)
7831
- http_request --method, --url, --header, --body, --content-type,
7832
- --timeout-ms, --var, --auth-mode, --connection
7833
- execute_plugin --plugin, --arg, --arg-json
7834
- generate_document --document-template, --target-schema, --target-file-field
7835
- `;
7836
7140
  function addActionPayloadOptions(command) {
7837
- return command.option(
7838
- "--type <type>",
7839
- "action type (create_record|update_record|search_records|send_message|http_request|execute_plugin|generate_document)"
7840
- ).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(
7841
7142
  "--timeout-ms <n>",
7842
7143
  "HTTP timeout in milliseconds",
7843
7144
  parseNonNegativeInteger
7844
- ).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");
7845
7146
  }
7846
7147
  function registerAutomationsCommands(program, options = {}) {
7847
7148
  const filePath = options.configPath ?? defaultConfigPath;
7848
7149
  const stdout = getCommandIo2(options.stdout);
7849
7150
  const automations = program.command("automations").description("Manage automations, triggers, actions, and connections");
7850
- const folders = automations.command("folders").description("Manage automation folders (flat: a folder only has a name, no order or properties)");
7851
- 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() {
7852
7153
  const { api, json } = createAutomationsApi(this, filePath);
7853
7154
  const data = await api.listFolders();
7854
7155
  if (json) {
@@ -7898,11 +7199,7 @@ function registerAutomationsCommands(program, options = {}) {
7898
7199
  }
7899
7200
  writeLine2(stdout, `Deleted automation folder "${folder.value}".`);
7900
7201
  });
7901
- folders.command("move").description("Move an automation into a folder").argument("<automation>", "automation UUID", parseUuidOrSlugSelector).requiredOption(
7902
- "--to <folder>",
7903
- "target folder UUID or exact name (use the root folder to move it out of any folder)",
7904
- parseUuidOrSlugSelector
7905
- ).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) {
7906
7203
  const { api, json, readOnly } = createAutomationsApi(this, filePath);
7907
7204
  ensureWritable("automations folders move", readOnly, "write");
7908
7205
  if (!commandOptions.to) {
@@ -8587,117 +7884,9 @@ var DisplaysApi = class {
8587
7884
  { method: "DELETE" }
8588
7885
  );
8589
7886
  }
8590
- listFolders() {
8591
- return this.client.getJson("/api/v2/display-folders");
8592
- }
8593
- createFolder(body) {
8594
- return this.client.requestJson(
8595
- "/api/v2/display-folders",
8596
- jsonOptions3(body, "POST")
8597
- );
8598
- }
8599
- updateFolder(folder, body) {
8600
- return this.client.requestJson(
8601
- `/api/v2/display-folders/${selectorValue3(folder)}`,
8602
- jsonOptions3(body, "PATCH")
8603
- );
8604
- }
8605
- deleteFolder(folder) {
8606
- return this.client.requestJson(
8607
- `/api/v2/display-folders/${selectorValue3(folder)}`,
8608
- { method: "DELETE" }
8609
- );
8610
- }
8611
- moveDisplay(input) {
8612
- return this.client.requestJson(
8613
- "/api/v2/display-folders/displays:move",
8614
- jsonOptions3(input, "POST")
8615
- );
8616
- }
8617
7887
  };
8618
7888
 
8619
- // src/parsers/expressions.ts
8620
- var supportedComparators = /* @__PURE__ */ new Set([
8621
- "eq",
8622
- "neq",
8623
- "gt",
8624
- "gte",
8625
- "lt",
8626
- "lte",
8627
- "contains",
8628
- "in",
8629
- "is_empty",
8630
- "is_not_empty"
8631
- ]);
8632
- var noValueComparators = /* @__PURE__ */ new Set(["is_empty", "is_not_empty"]);
8633
- function parseColonExpression(input) {
8634
- const parts = input.split(":");
8635
- if (parts.length < 2) {
8636
- throw new Error(`Expected a field:comparator[:value] expression, got "${input}".`);
8637
- }
8638
- const field = parts[0]?.trim();
8639
- const comparator = parts[1]?.trim();
8640
- if (!field) {
8641
- throw new Error(`Expected a field before ":", got "${input}".`);
8642
- }
8643
- if (!comparator) {
8644
- throw new Error(`Expected a comparator after "${field}:", got "${input}".`);
8645
- }
8646
- return [field, comparator, parts.slice(2).join(":").trim()];
8647
- }
8648
- function parseSpaceExpression(input) {
8649
- const parts = input.trim().split(/\s+/);
8650
- if (parts.length < 2) {
8651
- throw new Error(`Expected a field comparator expression, got "${input}".`);
8652
- }
8653
- const field = parts[0];
8654
- const comparator = parts[1];
8655
- if (!field) {
8656
- throw new Error(`Expected a field comparator expression, got "${input}".`);
8657
- }
8658
- if (!comparator) {
8659
- throw new Error(`Expected a comparator after "${field}", got "${input}".`);
8660
- }
8661
- return [field.trim(), comparator.trim(), parts.slice(2).join(" ").trim()];
8662
- }
8663
- function normalizeValue(comparator, rawValue) {
8664
- if (noValueComparators.has(comparator)) {
8665
- if (rawValue.length > 0) {
8666
- throw new Error(`Comparator "${comparator}" does not accept a value.`);
8667
- }
8668
- return null;
8669
- }
8670
- if (comparator === "in") {
8671
- const values = rawValue.split(",").map((value) => value.trim()).filter(Boolean);
8672
- if (values.length === 0) {
8673
- throw new Error(`Comparator "${comparator}" requires at least one value.`);
8674
- }
8675
- return values;
8676
- }
8677
- if (rawValue.length === 0) {
8678
- throw new Error(`Comparator "${comparator}" requires a value.`);
8679
- }
8680
- return rawValue;
8681
- }
8682
- function parseExpression(input) {
8683
- const trimmed = input.trim();
8684
- const [field, comparatorCandidate, rawValue] = trimmed.includes(":") && !trimmed.includes(" ") ? parseColonExpression(trimmed) : parseSpaceExpression(trimmed);
8685
- if (!supportedComparators.has(comparatorCandidate)) {
8686
- throw new Error(
8687
- `Unsupported comparator "${comparatorCandidate}" in expression "${input}".`
8688
- );
8689
- }
8690
- const comparator = comparatorCandidate;
8691
- return {
8692
- field,
8693
- comparator,
8694
- value: normalizeValue(comparator, rawValue),
8695
- raw: trimmed
8696
- };
8697
- }
8698
-
8699
7889
  // src/commands/displays.ts
8700
- var DATE_DYNAMIC_OPTIONS = "today, thisWeek, thisMonth, thisQuarter, thisSemester, thisYear, next7Days, next30Days, next6Months, next12Months, last12Months";
8701
7890
  function getCommandIo4(stdout) {
8702
7891
  return stdout ?? process.stdout;
8703
7892
  }
@@ -8761,37 +7950,6 @@ function parseUuidOrSlugSelector3(input) {
8761
7950
  throw new InvalidArgumentError3(message);
8762
7951
  }
8763
7952
  }
8764
- var COMPARATOR_TO_DISPLAY_OPERATOR = {
8765
- eq: "EQUAL",
8766
- neq: "NOT_EQUAL",
8767
- gt: "GREATER",
8768
- gte: "GREATER_OR_EQUAL",
8769
- lt: "LESS",
8770
- lte: "LESS_OR_EQUAL",
8771
- contains: "CONTAINS",
8772
- in: "ANY_OF",
8773
- is_empty: "IS_EMPTY",
8774
- is_not_empty: "IS_NOT_EMPTY"
8775
- };
8776
- function toDisplayFilter(parsed) {
8777
- const values = parsed.value === null ? [] : Array.isArray(parsed.value) ? [...parsed.value] : [parsed.value];
8778
- return {
8779
- origin: { fieldId: parsed.field },
8780
- comparisonOperator: COMPARATOR_TO_DISPLAY_OPERATOR[parsed.comparator],
8781
- values
8782
- };
8783
- }
8784
- function parseFilterExpression(input) {
8785
- try {
8786
- return parseExpression(input);
8787
- } catch (error) {
8788
- const message = error instanceof Error ? error.message : "Invalid filter expression.";
8789
- throw new InvalidArgumentError3(message);
8790
- }
8791
- }
8792
- function collectFilters(value, previous = []) {
8793
- return [...previous, parseFilterExpression(value)];
8794
- }
8795
7953
  function readRawObject2(raw, rawFile) {
8796
7954
  if (raw && rawFile) {
8797
7955
  throw new CliError("invalid_cli_usage", 'Use either "--raw" or "--raw-file", not both.');
@@ -8826,150 +7984,6 @@ function readNamedJsonOption(raw, rawFile, inlineFlag = "--option", fileFlag = "
8826
7984
  function isEmptyObject3(value) {
8827
7985
  return Object.keys(value).length === 0;
8828
7986
  }
8829
- function isPlainObject(value) {
8830
- return typeof value === "object" && value !== null && !Array.isArray(value);
8831
- }
8832
- function deepMerge(target, source) {
8833
- const out = { ...target };
8834
- for (const [key, value] of Object.entries(source)) {
8835
- const existing = out[key];
8836
- out[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
8837
- }
8838
- return out;
8839
- }
8840
- function assignDefined(target, key, value) {
8841
- if (value !== void 0) target[key] = value;
8842
- }
8843
- function readNamedJsonObject(raw, rawFile, inlineFlag, fileFlag) {
8844
- const parsed = readNamedJsonOption(raw, rawFile, inlineFlag, fileFlag);
8845
- if (parsed === void 0) return void 0;
8846
- if (!isPlainObject(parsed)) {
8847
- throw new CliError("invalid_cli_usage", `${inlineFlag} payload must be a JSON object.`);
8848
- }
8849
- return parsed;
8850
- }
8851
- var HIERARCHY_AGGREGATIONS = /* @__PURE__ */ new Set([
8852
- "SUM",
8853
- "AVERAGE",
8854
- "MINIMUM",
8855
- "MAXIMUM",
8856
- "COUNT",
8857
- "COUNT_DISTINCT"
8858
- ]);
8859
- function parseHierarchyInfo(value) {
8860
- const idx = value.indexOf(":");
8861
- if (idx <= 0 || idx === value.length - 1) {
8862
- throw new CliError("invalid_cli_usage", `--hierarchy-info "${value}" must use the format <id:name>.`);
8863
- }
8864
- return { id: value.slice(0, idx).trim(), name: value.slice(idx + 1).trim() };
8865
- }
8866
- function parseHierarchyNumber(value) {
8867
- const parts = value.split(":");
8868
- if (parts.length < 3) {
8869
- throw new CliError(
8870
- "invalid_cli_usage",
8871
- `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8872
- );
8873
- }
8874
- const id = parts[0]?.trim() ?? "";
8875
- const aggregation = (parts[parts.length - 1]?.trim() ?? "").toUpperCase();
8876
- const name = parts.slice(1, -1).join(":").trim();
8877
- if (!id || !name) {
8878
- throw new CliError(
8879
- "invalid_cli_usage",
8880
- `--hierarchy-number "${value}" must use the format <id:name:aggregation>.`
8881
- );
8882
- }
8883
- if (!HIERARCHY_AGGREGATIONS.has(aggregation)) {
8884
- throw new CliError(
8885
- "invalid_cli_usage",
8886
- `--hierarchy-number aggregation "${aggregation}" must be one of SUM, AVERAGE, MINIMUM, MAXIMUM, COUNT, COUNT_DISTINCT.`
8887
- );
8888
- }
8889
- return { id, name, aggregation };
8890
- }
8891
- function parseHierarchyMapping(value, flag) {
8892
- const idx = value.indexOf(":");
8893
- if (idx <= 0 || idx === value.length - 1) {
8894
- throw new CliError("invalid_cli_usage", `${flag} "${value}" must use the format <columnId:fieldId>.`);
8895
- }
8896
- return { columnId: value.slice(0, idx).trim(), fieldId: value.slice(idx + 1).trim() };
8897
- }
8898
- function buildWidgetFieldMapping(options) {
8899
- const mapping = {};
8900
- assignDefined(mapping, "columnField", options.columnField);
8901
- assignDefined(mapping, "swimlaneField", options.swimlaneField);
8902
- assignDefined(mapping, "startDateField", options.startDateField);
8903
- assignDefined(mapping, "endDateField", options.endDateField);
8904
- assignDefined(mapping, "labelField", options.labelField);
8905
- assignDefined(mapping, "groupField", options.groupField);
8906
- assignDefined(mapping, "subgroupField", options.subgroupField);
8907
- assignDefined(mapping, "progressField", options.progressField);
8908
- const cardConfig = {};
8909
- assignDefined(cardConfig, "titleField", options.cardTitleField);
8910
- assignDefined(cardConfig, "category1Field", options.cardCategory1Field);
8911
- assignDefined(cardConfig, "category2Field", options.cardCategory2Field);
8912
- assignDefined(cardConfig, "category3Field", options.cardCategory3Field);
8913
- assignDefined(cardConfig, "category4Field", options.cardCategory4Field);
8914
- assignDefined(cardConfig, "descriptionField", options.cardDescriptionField);
8915
- if (Object.keys(cardConfig).length > 0) mapping.cardConfig = cardConfig;
8916
- const aggregationConfig = {};
8917
- assignDefined(aggregationConfig, "method", options.aggregationMethod);
8918
- assignDefined(aggregationConfig, "fieldId", options.aggregationField);
8919
- if (Object.keys(aggregationConfig).length > 0) mapping.aggregationConfig = aggregationConfig;
8920
- return Object.keys(mapping).length > 0 ? mapping : void 0;
8921
- }
8922
- function buildHierarchyConfig(options) {
8923
- const base = readNamedJsonObject(
8924
- options.hierarchyConfig,
8925
- options.hierarchyConfigFile,
8926
- "--hierarchy-config",
8927
- "--hierarchy-config-file"
8928
- );
8929
- const patch = {};
8930
- const columns = {};
8931
- assignDefined(columns, "label", options.hierarchyLabel);
8932
- if (options.hierarchyInfo && options.hierarchyInfo.length > 0) {
8933
- columns.infos = options.hierarchyInfo.map(parseHierarchyInfo);
8934
- }
8935
- if (options.hierarchyNumber && options.hierarchyNumber.length > 0) {
8936
- columns.numbers = options.hierarchyNumber.map(parseHierarchyNumber);
8937
- }
8938
- if (Object.keys(columns).length > 0) patch.columns = columns;
8939
- const rootLevel = {};
8940
- assignDefined(rootLevel, "name", options.hierarchyRootName);
8941
- assignDefined(rootLevel, "labelFieldId", options.hierarchyRootLabelField);
8942
- if (options.hierarchyRootInfo && options.hierarchyRootInfo.length > 0) {
8943
- rootLevel.infoMappings = options.hierarchyRootInfo.map(
8944
- (entry) => parseHierarchyMapping(entry, "--hierarchy-root-info")
8945
- );
8946
- }
8947
- if (options.hierarchyRootNumber && options.hierarchyRootNumber.length > 0) {
8948
- rootLevel.numberMappings = options.hierarchyRootNumber.map(
8949
- (entry) => parseHierarchyMapping(entry, "--hierarchy-root-number")
8950
- );
8951
- }
8952
- if (Object.keys(rootLevel).length > 0) patch.rootLevel = rootLevel;
8953
- if (options.hierarchyChild && options.hierarchyChild.length > 0) {
8954
- patch.childLevels = options.hierarchyChild.map((entry, index) => {
8955
- let parsed;
8956
- try {
8957
- parsed = JSON.parse(entry);
8958
- } catch {
8959
- throw new CliError("invalid_cli_usage", `--hierarchy-child payload #${index + 1} is invalid JSON.`);
8960
- }
8961
- if (!isPlainObject(parsed)) {
8962
- throw new CliError(
8963
- "invalid_cli_usage",
8964
- `--hierarchy-child payload #${index + 1} must be a JSON object.`
8965
- );
8966
- }
8967
- return parsed;
8968
- });
8969
- }
8970
- if (base === void 0 && Object.keys(patch).length === 0) return void 0;
8971
- return deepMerge(base ?? {}, patch);
8972
- }
8973
7987
  function displayRows(displays) {
8974
7988
  return displays.map((display) => ({
8975
7989
  id: display.id,
@@ -8985,31 +7999,6 @@ function getDisplaySubresource(value) {
8985
7999
  }
8986
8000
  return value.filter((entry) => Boolean(entry) && typeof entry === "object");
8987
8001
  }
8988
- function displayFolderRows(folders) {
8989
- return folders.map((folder) => ({
8990
- id: folder.id ?? "",
8991
- name: folder.name ?? "",
8992
- isRoot: folder.isRoot ?? "",
8993
- displayCount: folder.displayCount ?? ""
8994
- }));
8995
- }
8996
- async function resolveDisplayFolderId(api, selector) {
8997
- if (selector.kind === "uuid") {
8998
- return selector.value;
8999
- }
9000
- const folders = await api.listFolders();
9001
- const matches = folders.filter((folder) => folder.name === selector.value);
9002
- if (matches.length === 1 && typeof matches[0]?.id === "string" && matches[0].id.length > 0) {
9003
- return matches[0].id;
9004
- }
9005
- if (matches.length > 1) {
9006
- throw new CliError(
9007
- "invalid_cli_usage",
9008
- `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9009
- );
9010
- }
9011
- throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
9012
- }
9013
8002
  function buildVariableBody(options) {
9014
8003
  const body = {
9015
8004
  ...readRawObject2(options.raw, options.rawFile)
@@ -9027,7 +8016,7 @@ function buildVariableBody(options) {
9027
8016
  };
9028
8017
  }
9029
8018
  if (options.filter && options.filter.length > 0) {
9030
- body.filters = options.filter.map(toDisplayFilter);
8019
+ body.filters = options.filter.map((entry) => ({ raw: entry }));
9031
8020
  }
9032
8021
  if (options.dateMode || options.dateDynamicOption || options.dateSpecific || options.dateRangeStart || options.dateRangeEnd) {
9033
8022
  body.date = {
@@ -9076,39 +8065,15 @@ function buildWidgetBody(options) {
9076
8065
  layout
9077
8066
  };
9078
8067
  }
9079
- const viewPatch = {};
9080
- if (options.field && options.field.length > 0) {
9081
- viewPatch.fields = options.field;
9082
- }
9083
- const fieldMapping = buildWidgetFieldMapping(options);
9084
- const viewStateBase = readNamedJsonObject(
9085
- options.viewState,
9086
- options.viewStateFile,
9087
- "--view-state",
9088
- "--view-state-file"
9089
- );
9090
- let viewState = viewStateBase ? { ...viewStateBase } : void 0;
9091
- if (fieldMapping) {
9092
- viewState = deepMerge(viewState ?? {}, { fieldMapping });
9093
- }
9094
- if (viewState !== void 0) {
9095
- viewPatch.viewAdditionalProperties = { viewState };
9096
- }
9097
- const hierarchyConfig = buildHierarchyConfig(options);
9098
- if (hierarchyConfig !== void 0) {
9099
- viewPatch.hierarchyConfig = hierarchyConfig;
9100
- }
9101
- if (Object.keys(viewPatch).length > 0) {
9102
- const existingView = typeof body.view === "object" && body.view ? body.view : {};
9103
- body.view = deepMerge(existingView, viewPatch);
9104
- }
9105
- const queryMerge = {};
9106
- if (options.sort && options.sort.length > 0) queryMerge.sorts = options.sort;
9107
- if (options.filter && options.filter.length > 0) queryMerge.filters = options.filter.map(toDisplayFilter);
9108
- 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
+ };
9109
8073
  body.query = {
9110
8074
  ...typeof body.query === "object" && body.query ? body.query : {},
9111
- ...queryMerge
8075
+ sorts: options.sort,
8076
+ filters: options.filter?.map((entry) => ({ raw: entry }))
9112
8077
  };
9113
8078
  }
9114
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) {
@@ -9235,72 +8200,6 @@ function registerDisplaysCommands(program, options = {}) {
9235
8200
  }
9236
8201
  writeLine4(stdout, `Deleted display "${display.value}".`);
9237
8202
  });
9238
- const folders = displays.command("folders").description("Manage display folders (flat: a folder only has a name, no order or properties)");
9239
- folders.command("list").description("List display folders (non-root folders plus the root bucket, whose name is null)").action(async function action() {
9240
- const { api, json } = createDisplaysApi(this, filePath);
9241
- const data = await api.listFolders();
9242
- if (json) {
9243
- emitJson4(stdout, "displays folders list", data);
9244
- return;
9245
- }
9246
- printTable(displayFolderRows(data), ["id", "name", "isRoot", "displayCount"], stdout);
9247
- });
9248
- folders.command("create").description("Create a display folder").requiredOption("--name <name>", "folder name").action(async function action(commandOptions) {
9249
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9250
- ensureWritable3("displays folders create", readOnly, "write");
9251
- if (commandOptions.name === void 0) {
9252
- throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
9253
- }
9254
- const data = await api.createFolder({ name: commandOptions.name });
9255
- if (json) {
9256
- emitJson4(stdout, "displays folders create", data);
9257
- return;
9258
- }
9259
- writeLine4(stdout, `Created display folder "${String(data.name ?? commandOptions.name)}".`);
9260
- });
9261
- 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) {
9262
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9263
- ensureWritable3("displays folders update", readOnly, "write");
9264
- if (commandOptions.name === void 0) {
9265
- throw new CliError("invalid_cli_usage", 'Provide folder name via "--name".');
9266
- }
9267
- const folderId = await resolveDisplayFolderId(api, folder);
9268
- const data = await api.updateFolder({ kind: "uuid", value: folderId }, { name: commandOptions.name });
9269
- if (json) {
9270
- emitJson4(stdout, "displays folders update", data);
9271
- return;
9272
- }
9273
- writeLine4(stdout, `Updated display folder "${String(data.name ?? folder.value)}".`);
9274
- });
9275
- 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) {
9276
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9277
- ensureWritable3("displays folders delete", readOnly, "destructive");
9278
- const folderId = await resolveDisplayFolderId(api, folder);
9279
- const data = await api.deleteFolder({ kind: "uuid", value: folderId });
9280
- if (json) {
9281
- emitJson4(stdout, "displays folders delete", data);
9282
- return;
9283
- }
9284
- writeLine4(stdout, `Deleted display folder "${folder.value}".`);
9285
- });
9286
- folders.command("move").description("Move a display into a folder").argument("<display>", "display UUID", parseUuidOrSlugSelector3).requiredOption(
9287
- "--to <folder>",
9288
- "target folder UUID or exact name (use the root folder to move it out of any folder)",
9289
- parseUuidOrSlugSelector3
9290
- ).action(async function action(display, commandOptions) {
9291
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9292
- ensureWritable3("displays folders move", readOnly, "write");
9293
- if (!commandOptions.to) {
9294
- throw new CliError("invalid_cli_usage", 'Provide target folder via "--to".');
9295
- }
9296
- const targetFolderId = await resolveDisplayFolderId(api, commandOptions.to);
9297
- const data = await api.moveDisplay({ displayId: display.value, targetFolderId });
9298
- if (json) {
9299
- emitJson4(stdout, "displays folders move", data);
9300
- return;
9301
- }
9302
- writeLine4(stdout, `Moved display "${display.value}" to folder "${targetFolderId}".`);
9303
- });
9304
8203
  const layout = displays.command("layout").description("Manage display layout");
9305
8204
  layout.command("get").description("Get display layout").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9306
8205
  const { api, json } = createDisplaysApi(this, filePath);
@@ -9389,7 +8288,7 @@ function registerDisplaysCommands(program, options = {}) {
9389
8288
  }
9390
8289
  printTable([match], void 0, stdout);
9391
8290
  });
9392
- 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) {
9393
8292
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9394
8293
  ensureWritable3("displays variables create", readOnly, "write");
9395
8294
  const data = await api.createVariable(display, buildVariableBody(commandOptions));
@@ -9399,7 +8298,7 @@ function registerDisplaysCommands(program, options = {}) {
9399
8298
  }
9400
8299
  writeLine4(stdout, `Created variable on display "${display.value}".`);
9401
8300
  });
9402
- 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) {
9403
8302
  const { api, json, readOnly } = createDisplaysApi(this, filePath);
9404
8303
  ensureWritable3("displays variables update", readOnly, "write");
9405
8304
  const data = await api.updateVariable(display, variableId, buildVariableBody(commandOptions));
@@ -9434,525 +8333,122 @@ function registerDisplaysCommands(program, options = {}) {
9434
8333
  const { api, json } = createDisplaysApi(this, filePath);
9435
8334
  const data = await api.getWidget(display, widgetId);
9436
8335
  if (json) {
9437
- emitJson4(stdout, "displays widgets get", data);
9438
- return;
9439
- }
9440
- printTable([data], void 0, stdout);
9441
- });
9442
- 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) {
9443
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9444
- ensureWritable3("displays widgets create", readOnly, "write");
9445
- const data = await api.createWidget(display, buildWidgetBody(commandOptions));
9446
- if (json) {
9447
- emitJson4(stdout, "displays widgets create", data);
9448
- return;
9449
- }
9450
- writeLine4(stdout, `Created widget on display "${display.value}".`);
9451
- });
9452
- 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) {
9453
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9454
- ensureWritable3("displays widgets update", readOnly, "write");
9455
- const data = await api.updateWidget(display, widgetId, buildWidgetBody(commandOptions));
9456
- if (json) {
9457
- emitJson4(stdout, "displays widgets update", data);
9458
- return;
9459
- }
9460
- writeLine4(stdout, `Updated widget "${widgetId}".`);
9461
- });
9462
- widgets.command("delete").description("Delete widget").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<widget>", "widget id").action(async function action(display, widgetId) {
9463
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9464
- ensureWritable3("displays widgets delete", readOnly, "destructive");
9465
- const data = await api.deleteWidget(display, widgetId);
9466
- if (json) {
9467
- emitJson4(stdout, "displays widgets delete", data);
9468
- return;
9469
- }
9470
- writeLine4(stdout, `Deleted widget "${widgetId}".`);
9471
- });
9472
- const targets = displays.command("navigation-targets").description("Manage navigation targets");
9473
- targets.command("list").description("List navigation targets").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9474
- const { api, json } = createDisplaysApi(this, filePath);
9475
- const data = await api.getDisplay(display);
9476
- const items = getDisplaySubresource(data.navigationTargets);
9477
- if (json) {
9478
- emitJson4(stdout, "displays navigation-targets list", items);
9479
- return;
9480
- }
9481
- printTable(items, void 0, stdout);
9482
- });
9483
- 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) {
9484
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9485
- ensureWritable3("displays navigation-targets create", readOnly, "write");
9486
- const data = await api.createNavigationTarget(display, buildNavigationTargetBody(commandOptions));
9487
- if (json) {
9488
- emitJson4(stdout, "displays navigation-targets create", data);
9489
- return;
9490
- }
9491
- writeLine4(stdout, `Created navigation target on display "${display.value}".`);
9492
- });
9493
- 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) {
9494
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9495
- ensureWritable3("displays navigation-targets update", readOnly, "write");
9496
- const data = await api.updateNavigationTarget(display, targetId, buildNavigationTargetBody(commandOptions));
9497
- if (json) {
9498
- emitJson4(stdout, "displays navigation-targets update", data);
9499
- return;
9500
- }
9501
- writeLine4(stdout, `Updated navigation target "${targetId}".`);
9502
- });
9503
- targets.command("delete").description("Delete navigation target").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).argument("<target>", "target id").action(async function action(display, targetId) {
9504
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9505
- ensureWritable3("displays navigation-targets delete", readOnly, "destructive");
9506
- const data = await api.deleteNavigationTarget(display, targetId);
9507
- if (json) {
9508
- emitJson4(stdout, "displays navigation-targets delete", data);
9509
- return;
9510
- }
9511
- writeLine4(stdout, `Deleted navigation target "${targetId}".`);
9512
- });
9513
- const cross = displays.command("cross-widget-filter").description("Manage cross widget filter");
9514
- cross.command("get").description("Get cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9515
- const { api, json } = createDisplaysApi(this, filePath);
9516
- const data = await api.getDisplay(display);
9517
- const item = data.crossWidgetFilter ?? null;
9518
- if (json) {
9519
- emitJson4(stdout, "displays cross-widget-filter get", item);
9520
- return;
9521
- }
9522
- printTable(item ? [item] : [], void 0, stdout);
9523
- });
9524
- 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) {
9525
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9526
- ensureWritable3("displays cross-widget-filter set", readOnly, "write");
9527
- const data = await api.setCrossWidgetFilter(display, buildCrossWidgetFilterBody(commandOptions));
9528
- if (json) {
9529
- emitJson4(stdout, "displays cross-widget-filter set", data);
9530
- return;
9531
- }
9532
- writeLine4(stdout, `Updated cross widget filter for display "${display.value}".`);
9533
- });
9534
- cross.command("delete").description("Delete cross widget filter").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9535
- const { api, json, readOnly } = createDisplaysApi(this, filePath);
9536
- ensureWritable3("displays cross-widget-filter delete", readOnly, "destructive");
9537
- const data = await api.deleteCrossWidgetFilter(display);
9538
- if (json) {
9539
- emitJson4(stdout, "displays cross-widget-filter delete", data);
9540
- return;
9541
- }
9542
- writeLine4(stdout, `Deleted cross widget filter for display "${display.value}".`);
9543
- });
9544
- }
9545
-
9546
- // src/commands/document-templates.ts
9547
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
9548
- import { basename } from "path";
9549
- import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
9550
-
9551
- // src/api/document-templates.ts
9552
- function jsonOptions4(body, method) {
9553
- return {
9554
- method,
9555
- headers: {
9556
- "content-type": "application/json"
9557
- },
9558
- body: JSON.stringify(body)
9559
- };
9560
- }
9561
- function selectorValue4(selector) {
9562
- return encodeURIComponent(selector.value);
9563
- }
9564
- function segment3(value) {
9565
- return encodeURIComponent(value);
9566
- }
9567
- var DocumentTemplatesApi = class {
9568
- constructor(client) {
9569
- this.client = client;
9570
- }
9571
- listTemplates() {
9572
- return this.client.getJson("/api/v2/document-templates");
9573
- }
9574
- createTemplate(input) {
9575
- return this.client.requestJson(
9576
- "/api/v2/document-templates",
9577
- jsonOptions4(input, "POST")
9578
- );
9579
- }
9580
- updateTemplate(template, input) {
9581
- return this.client.requestJson(
9582
- `/api/v2/document-templates/${selectorValue4(template)}`,
9583
- jsonOptions4(input, "PATCH")
9584
- );
9585
- }
9586
- deleteTemplate(template) {
9587
- return this.client.requestJson(
9588
- `/api/v2/document-templates/${selectorValue4(template)}`,
9589
- { method: "DELETE" }
9590
- );
9591
- }
9592
- addAsset(template, input) {
9593
- return this.client.requestJson(
9594
- `/api/v2/document-templates/${selectorValue4(template)}/assets`,
9595
- { method: "POST", body: input }
9596
- );
9597
- }
9598
- deleteAsset(template, assetId) {
9599
- return this.client.requestJson(
9600
- `/api/v2/document-templates/${selectorValue4(template)}/assets/${segment3(assetId)}`,
9601
- { method: "DELETE" }
9602
- );
9603
- }
9604
- downloadAsset(template, assetId) {
9605
- return this.client.requestBinary(
9606
- `/api/v2/document-templates/${selectorValue4(template)}/assets/${segment3(assetId)}/download`
9607
- );
9608
- }
9609
- };
9610
-
9611
- // src/commands/document-templates.ts
9612
- function getCommandIo5(stdout) {
9613
- return stdout ?? process.stdout;
9614
- }
9615
- function writeLine5(stdout, value) {
9616
- stdout.write(`${value}
9617
- `);
9618
- }
9619
- function writeBinary(stdout, value) {
9620
- stdout.write(Buffer.from(value));
9621
- }
9622
- function getGlobalOptions5(command) {
9623
- return command.optsWithGlobals();
9624
- }
9625
- function emitJson5(stdout, commandName, data, configPath, meta = {}) {
9626
- writeLine5(
9627
- stdout,
9628
- JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
9629
- );
9630
- }
9631
- function toConfigurationError5(filePath, error) {
9632
- if (error instanceof CliError) {
9633
- throw error;
9634
- }
9635
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
9636
- throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
9637
- }
9638
- if (error instanceof Error) {
9639
- throw new CliError("configuration_error", error.message);
9640
- }
9641
- throw error;
9642
- }
9643
- function createDocumentTemplatesApi(command, filePath) {
9644
- try {
9645
- const config = readRuntimeConfig(filePath);
9646
- const runtime = resolveRuntimeContext(config, getGlobalOptions5(command));
9647
- if (!runtime.baseUrl) {
9648
- throw new CliError(
9649
- "configuration_error",
9650
- `Resolved profile "${runtime.profile}" is missing a base URL.`
9651
- );
9652
- }
9653
- return {
9654
- api: new DocumentTemplatesApi(
9655
- new ApiClient({
9656
- baseUrl: runtime.baseUrl,
9657
- apiKey: runtime.apiKey
9658
- })
9659
- ),
9660
- json: runtime.json,
9661
- readOnly: runtime.readOnly
9662
- };
9663
- } catch (error) {
9664
- toConfigurationError5(filePath, error);
9665
- }
9666
- }
9667
- function ensureWritable4(commandName, readOnly, commandMode) {
9668
- if (readOnly) {
9669
- throw new CliError(
9670
- "command_not_allowed_in_read_only_mode",
9671
- `Command "${commandName}" is not allowed in read-only mode.`,
9672
- {
9673
- commandMode,
9674
- executionMode: "read-only"
9675
- }
9676
- );
9677
- }
9678
- }
9679
- function parseUuidOrSlugSelector4(input) {
9680
- try {
9681
- return normalizeUuidOrSlug(input);
9682
- } catch (error) {
9683
- const message = error instanceof Error ? error.message : "Invalid selector.";
9684
- throw new InvalidArgumentError4(message);
9685
- }
9686
- }
9687
- function isJsonObject4(value) {
9688
- return typeof value === "object" && value !== null && !Array.isArray(value);
9689
- }
9690
- function isEmptyObject4(value) {
9691
- return Object.keys(value).length === 0;
9692
- }
9693
- function parseJsonValue2(input, sourceLabel) {
9694
- try {
9695
- return JSON.parse(input);
9696
- } catch (error) {
9697
- const message = error instanceof Error ? error.message : "Invalid JSON.";
9698
- throw new CliError(
9699
- "invalid_cli_usage",
9700
- `Failed to parse JSON from ${sourceLabel}: ${message}`
9701
- );
9702
- }
9703
- }
9704
- function readTextFile2(filePath, label) {
9705
- try {
9706
- return readFileSync5(filePath, "utf8");
9707
- } catch (error) {
9708
- const message = error instanceof Error ? error.message : "Unable to read file.";
9709
- throw new CliError(
9710
- "invalid_cli_usage",
9711
- `Failed to read ${label} from ${filePath}: ${message}`
9712
- );
9713
- }
9714
- }
9715
- function readJsonObjectOption2(raw, rawFile, rawLabel, rawFileLabel) {
9716
- if (raw && rawFile) {
9717
- throw new CliError(
9718
- "invalid_cli_usage",
9719
- `Provide either "${rawLabel}" or "${rawFileLabel}", not both.`
9720
- );
9721
- }
9722
- let parsed;
9723
- if (raw) {
9724
- parsed = parseJsonValue2(raw, rawLabel);
9725
- } else if (rawFile) {
9726
- parsed = parseJsonValue2(readTextFile2(rawFile, rawFileLabel), `${rawFileLabel} ${rawFile}`);
9727
- } else {
9728
- return {};
9729
- }
9730
- if (!isJsonObject4(parsed)) {
9731
- throw new CliError(
9732
- "invalid_cli_usage",
9733
- `Expected ${raw ? rawLabel : rawFileLabel} to contain a JSON object.`
9734
- );
9735
- }
9736
- return parsed;
9737
- }
9738
- function readLocalFile(filePath) {
9739
- try {
9740
- return readFileSync5(filePath);
9741
- } catch (error) {
9742
- const message = error instanceof Error ? error.message : "Unable to read file.";
9743
- throw new CliError("invalid_cli_usage", `Failed to read file at ${filePath}: ${message}`);
9744
- }
9745
- }
9746
- function writeDownloadedFile(outputPath, value) {
9747
- try {
9748
- writeFileSync2(outputPath, Buffer.from(value));
9749
- } catch (error) {
9750
- const message = error instanceof Error ? error.message : "Unable to write file.";
9751
- throw new CliError(
9752
- "invalid_cli_usage",
9753
- `Failed to write downloaded file to ${outputPath}: ${message}`
9754
- );
9755
- }
9756
- }
9757
- function templateRows(templates) {
9758
- return templates.map((template) => ({
9759
- id: template.id ?? "",
9760
- name: template.name ?? "",
9761
- assetCount: Array.isArray(template.assets) ? template.assets.length : 0,
9762
- updatedAt: template.updatedAt ?? ""
9763
- }));
9764
- }
9765
- function resolveTemplate(templates, selector) {
9766
- if (selector.kind === "uuid") {
9767
- const match = templates.find((template) => template.id === selector.value);
9768
- if (match) {
9769
- return match;
9770
- }
9771
- throw new CliError(
9772
- "invalid_cli_usage",
9773
- `Document template "${selector.value}" was not found.`
9774
- );
9775
- }
9776
- const matches = templates.filter((template) => template.name === selector.value);
9777
- if (matches.length === 1) {
9778
- return matches[0];
9779
- }
9780
- if (matches.length > 1) {
9781
- throw new CliError(
9782
- "invalid_cli_usage",
9783
- `Document template "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9784
- );
9785
- }
9786
- throw new CliError(
9787
- "invalid_cli_usage",
9788
- `Document template "${selector.value}" was not found.`
9789
- );
9790
- }
9791
- async function resolveTemplateSelector(api, selector) {
9792
- if (selector.kind === "uuid") {
9793
- return selector;
9794
- }
9795
- const templates = await api.listTemplates();
9796
- const resolved = resolveTemplate(templates, selector);
9797
- if (typeof resolved.id !== "string" || resolved.id.length === 0) {
9798
- throw new CliError(
9799
- "invalid_cli_usage",
9800
- `Document template "${selector.value}" is missing an id in the API response.`
9801
- );
9802
- }
9803
- return { kind: "uuid", value: resolved.id };
9804
- }
9805
- function buildCreateInput(options) {
9806
- const raw = readJsonObjectOption2(options.raw, options.rawFile, "--raw", "--raw-file");
9807
- const input = { ...raw };
9808
- if (options.name !== void 0) {
9809
- input.name = options.name;
9810
- }
9811
- if (typeof input.name !== "string" || input.name.trim().length === 0) {
9812
- throw new CliError("invalid_cli_usage", 'Provide template name via "--name".');
9813
- }
9814
- if (input.assets === void 0) {
9815
- input.assets = [];
9816
- }
9817
- return input;
9818
- }
9819
- function buildUpdateInput(options) {
9820
- const input = {};
9821
- if (options.name !== void 0) {
9822
- input.name = options.name;
9823
- }
9824
- if (isEmptyObject4(input)) {
9825
- throw new CliError("invalid_cli_usage", 'Provide template updates via "--name".');
9826
- }
9827
- return input;
9828
- }
9829
- function registerDocumentTemplatesCommands(program, options = {}) {
9830
- const filePath = options.configPath ?? defaultConfigPath;
9831
- const stdout = getCommandIo5(options.stdout);
9832
- const templates = program.command("document-templates").description("Manage document templates and their assets");
9833
- templates.command("list").description("List document templates").action(async function action() {
9834
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9835
- const data = await api.listTemplates();
8336
+ emitJson4(stdout, "displays widgets get", data);
8337
+ return;
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));
9836
8345
  if (json) {
9837
- emitJson5(stdout, "document-templates list", data, filePath);
8346
+ emitJson4(stdout, "displays widgets create", data);
9838
8347
  return;
9839
8348
  }
9840
- printTable(templateRows(data), ["id", "name", "assetCount", "updatedAt"], stdout);
8349
+ writeLine4(stdout, `Created widget on display "${display.value}".`);
9841
8350
  });
9842
- 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) {
9843
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9844
- const list = await api.listTemplates();
9845
- 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));
9846
8355
  if (json) {
9847
- emitJson5(stdout, "document-templates get", data, filePath);
8356
+ emitJson4(stdout, "displays widgets update", data);
9848
8357
  return;
9849
8358
  }
9850
- printTable([data], void 0, stdout);
8359
+ writeLine4(stdout, `Updated widget "${widgetId}".`);
9851
8360
  });
9852
- 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) {
9853
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9854
- ensureWritable4("document-templates create", readOnly, "write");
9855
- 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);
9856
8365
  if (json) {
9857
- emitJson5(stdout, "document-templates create", data, filePath);
8366
+ emitJson4(stdout, "displays widgets delete", data);
9858
8367
  return;
9859
8368
  }
9860
- writeLine5(stdout, `Created document template "${String(data.name ?? commandOptions.name)}".`);
8369
+ writeLine4(stdout, `Deleted widget "${widgetId}".`);
9861
8370
  });
9862
- 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) {
9863
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9864
- ensureWritable4("document-templates update", readOnly, "write");
9865
- const resolved = await resolveTemplateSelector(api, template);
9866
- 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);
9867
8376
  if (json) {
9868
- emitJson5(stdout, "document-templates update", data, filePath);
8377
+ emitJson4(stdout, "displays navigation-targets list", items);
9869
8378
  return;
9870
8379
  }
9871
- writeLine5(stdout, `Updated document template "${String(data.name ?? template.value)}".`);
8380
+ printTable(items, void 0, stdout);
9872
8381
  });
9873
- templates.command("delete").description("Delete a document template (and its assets)").argument("<template>", "template UUID or exact name", parseUuidOrSlugSelector4).action(async function action(template) {
9874
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9875
- ensureWritable4("document-templates delete", readOnly, "destructive");
9876
- const resolved = await resolveTemplateSelector(api, template);
9877
- 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));
9878
8386
  if (json) {
9879
- emitJson5(stdout, "document-templates delete", data, filePath);
8387
+ emitJson4(stdout, "displays navigation-targets create", data);
9880
8388
  return;
9881
8389
  }
9882
- writeLine5(stdout, `Deleted document template "${template.value}".`);
8390
+ writeLine4(stdout, `Created navigation target on display "${display.value}".`);
9883
8391
  });
9884
- const assets = templates.command("assets").description("Manage document template assets");
9885
- 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) {
9886
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9887
- ensureWritable4("document-templates assets add", readOnly, "write");
9888
- const contents = readLocalFile(localPath);
9889
- const formData = new FormData();
9890
- formData.append("file", new Blob([contents]), basename(localPath));
9891
- if (commandOptions.name !== void 0) {
9892
- 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;
9893
8399
  }
9894
- const resolved = await resolveTemplateSelector(api, template);
9895
- 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);
9896
8406
  if (json) {
9897
- emitJson5(stdout, "document-templates assets add", data, filePath);
8407
+ emitJson4(stdout, "displays navigation-targets delete", data);
9898
8408
  return;
9899
8409
  }
9900
- writeLine5(
9901
- stdout,
9902
- `Added asset "${commandOptions.name ?? basename(localPath)}" to template "${template.value}".`
9903
- );
8410
+ writeLine4(stdout, `Deleted navigation target "${targetId}".`);
9904
8411
  });
9905
- 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) {
9906
- const { api, json, readOnly } = createDocumentTemplatesApi(this, filePath);
9907
- ensureWritable4("document-templates assets delete", readOnly, "destructive");
9908
- const resolved = await resolveTemplateSelector(api, template);
9909
- 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;
9910
8417
  if (json) {
9911
- emitJson5(stdout, "document-templates assets delete", data, filePath);
8418
+ emitJson4(stdout, "displays cross-widget-filter get", item);
9912
8419
  return;
9913
8420
  }
9914
- writeLine5(stdout, `Deleted asset "${assetId}" from template "${template.value}".`);
8421
+ printTable(item ? [item] : [], void 0, stdout);
9915
8422
  });
9916
- 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) {
9917
- const { api, json } = createDocumentTemplatesApi(this, filePath);
9918
- if (json && !commandOptions.output) {
9919
- throw new CliError(
9920
- "invalid_cli_usage",
9921
- 'Provide "--output" when using "--json" with "document-templates assets download".'
9922
- );
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;
9923
8430
  }
9924
- const resolved = await resolveTemplateSelector(api, template);
9925
- const data = await api.downloadAsset(resolved, assetId);
9926
- if (commandOptions.output) {
9927
- writeDownloadedFile(commandOptions.output, data);
9928
- if (json) {
9929
- emitJson5(
9930
- stdout,
9931
- "document-templates assets download",
9932
- {
9933
- template: resolved.value,
9934
- asset: assetId,
9935
- output: commandOptions.output,
9936
- bytes: data.byteLength
9937
- },
9938
- filePath
9939
- );
9940
- return;
9941
- }
9942
- 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);
9943
8439
  return;
9944
8440
  }
9945
- writeBinary(stdout, data);
8441
+ writeLine4(stdout, `Deleted cross widget filter for display "${display.value}".`);
9946
8442
  });
9947
8443
  }
9948
8444
 
9949
8445
  // src/commands/files.ts
9950
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
9951
- import { basename as basename2 } from "path";
9952
- 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";
9953
8449
 
9954
8450
  // src/api/files.ts
9955
- function selectorValue5(selector) {
8451
+ function selectorValue4(selector) {
9956
8452
  return selector.value;
9957
8453
  }
9958
8454
  var FilesApi = class {
@@ -9966,11 +8462,11 @@ var FilesApi = class {
9966
8462
  });
9967
8463
  }
9968
8464
  downloadFile(file) {
9969
- return this.client.requestBinary(`/api/v2/files/${selectorValue5(file)}`);
8465
+ return this.client.requestBinary(`/api/v2/files/${selectorValue4(file)}`);
9970
8466
  }
9971
8467
  deleteFile(file) {
9972
8468
  return this.client.requestJson(
9973
- `/api/v2/files/${selectorValue5(file)}`,
8469
+ `/api/v2/files/${selectorValue4(file)}`,
9974
8470
  { method: "DELETE" }
9975
8471
  );
9976
8472
  }
@@ -9980,26 +8476,26 @@ var FilesApi = class {
9980
8476
  };
9981
8477
 
9982
8478
  // src/commands/files.ts
9983
- function getCommandIo6(stdout) {
8479
+ function getCommandIo5(stdout) {
9984
8480
  return stdout ?? process.stdout;
9985
8481
  }
9986
- function writeLine6(stdout, value) {
8482
+ function writeLine5(stdout, value) {
9987
8483
  stdout.write(`${value}
9988
8484
  `);
9989
8485
  }
9990
- function writeBinary2(stdout, value) {
8486
+ function writeBinary(stdout, value) {
9991
8487
  stdout.write(Buffer.from(value));
9992
8488
  }
9993
- function getGlobalOptions6(command) {
8489
+ function getGlobalOptions5(command) {
9994
8490
  return command.optsWithGlobals();
9995
8491
  }
9996
- function emitJson6(stdout, commandName, data, configPath, meta = {}) {
9997
- writeLine6(
8492
+ function emitJson5(stdout, commandName, data, configPath, meta = {}) {
8493
+ writeLine5(
9998
8494
  stdout,
9999
8495
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
10000
8496
  );
10001
8497
  }
10002
- function toConfigurationError6(filePath, error) {
8498
+ function toConfigurationError5(filePath, error) {
10003
8499
  if (error instanceof CliError) {
10004
8500
  throw error;
10005
8501
  }
@@ -10014,7 +8510,7 @@ function toConfigurationError6(filePath, error) {
10014
8510
  function createFilesApi(command, filePath) {
10015
8511
  try {
10016
8512
  const config = readRuntimeConfig(filePath);
10017
- const runtime = resolveRuntimeContext(config, getGlobalOptions6(command));
8513
+ const runtime = resolveRuntimeContext(config, getGlobalOptions5(command));
10018
8514
  if (!runtime.baseUrl) {
10019
8515
  throw new CliError(
10020
8516
  "configuration_error",
@@ -10032,10 +8528,10 @@ function createFilesApi(command, filePath) {
10032
8528
  readOnly: runtime.readOnly
10033
8529
  };
10034
8530
  } catch (error) {
10035
- toConfigurationError6(filePath, error);
8531
+ toConfigurationError5(filePath, error);
10036
8532
  }
10037
8533
  }
10038
- function ensureWritable5(commandName, readOnly, commandMode) {
8534
+ function ensureWritable4(commandName, readOnly, commandMode) {
10039
8535
  if (readOnly) {
10040
8536
  throw new CliError(
10041
8537
  "command_not_allowed_in_read_only_mode",
@@ -10047,28 +8543,28 @@ function ensureWritable5(commandName, readOnly, commandMode) {
10047
8543
  );
10048
8544
  }
10049
8545
  }
10050
- function parseUuidOrSlugSelector5(input) {
8546
+ function parseUuidOrSlugSelector4(input) {
10051
8547
  try {
10052
8548
  return normalizeUuidOrSlug(input);
10053
8549
  } catch (error) {
10054
8550
  const message = error instanceof Error ? error.message : "Invalid selector.";
10055
- throw new InvalidArgumentError5(message);
8551
+ throw new InvalidArgumentError4(message);
10056
8552
  }
10057
8553
  }
10058
8554
  function isRecord3(value) {
10059
8555
  return typeof value === "object" && value !== null && !Array.isArray(value);
10060
8556
  }
10061
- function readLocalFile2(filePath) {
8557
+ function readLocalFile(filePath) {
10062
8558
  try {
10063
- return readFileSync6(filePath);
8559
+ return readFileSync5(filePath);
10064
8560
  } catch (error) {
10065
8561
  const message = error instanceof Error ? error.message : "Unable to read file.";
10066
8562
  throw new CliError("invalid_cli_usage", `Failed to read file at ${filePath}: ${message}`);
10067
8563
  }
10068
8564
  }
10069
- function writeDownloadedFile2(outputPath, value) {
8565
+ function writeDownloadedFile(outputPath, value) {
10070
8566
  try {
10071
- writeFileSync3(outputPath, Buffer.from(value));
8567
+ writeFileSync2(outputPath, Buffer.from(value));
10072
8568
  } catch (error) {
10073
8569
  const message = error instanceof Error ? error.message : "Unable to write file.";
10074
8570
  throw new CliError(
@@ -10079,20 +8575,20 @@ function writeDownloadedFile2(outputPath, value) {
10079
8575
  }
10080
8576
  function registerFilesCommands(program, options = {}) {
10081
8577
  const filePath = options.configPath ?? defaultConfigPath;
10082
- const stdout = getCommandIo6(options.stdout);
8578
+ const stdout = getCommandIo5(options.stdout);
10083
8579
  const files = program.command("files").description("Manage files and storage");
10084
8580
  files.command("upload").description("Upload a local file").argument("<path>", "path to the local file").action(function action(path) {
10085
8581
  const { api, json, readOnly } = createFilesApi(this, filePath);
10086
- ensureWritable5("files upload", readOnly, "write");
10087
- const contents = readLocalFile2(path);
8582
+ ensureWritable4("files upload", readOnly, "write");
8583
+ const contents = readLocalFile(path);
10088
8584
  const formData = new FormData();
10089
- formData.append("file", new Blob([contents]), basename2(path));
8585
+ formData.append("file", new Blob([contents]), basename(path));
10090
8586
  return api.uploadFile(formData).then((data) => {
10091
8587
  if (json) {
10092
- emitJson6(stdout, "files upload", data, filePath);
8588
+ emitJson5(stdout, "files upload", data, filePath);
10093
8589
  return;
10094
8590
  }
10095
- writeLine6(stdout, `Uploaded file "${basename2(path)}".`);
8591
+ writeLine5(stdout, `Uploaded file "${basename(path)}".`);
10096
8592
  });
10097
8593
  });
10098
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) {
@@ -10103,12 +8599,12 @@ function registerFilesCommands(program, options = {}) {
10103
8599
  'Provide "--output" when using "--json" with "files download".'
10104
8600
  );
10105
8601
  }
10106
- const fileSelector = parseUuidOrSlugSelector5(file);
8602
+ const fileSelector = parseUuidOrSlugSelector4(file);
10107
8603
  return api.downloadFile(fileSelector).then((data) => {
10108
8604
  if (commandOptions.output) {
10109
- writeDownloadedFile2(commandOptions.output, data);
8605
+ writeDownloadedFile(commandOptions.output, data);
10110
8606
  if (json) {
10111
- emitJson6(
8607
+ emitJson5(
10112
8608
  stdout,
10113
8609
  "files download",
10114
8610
  {
@@ -10120,45 +8616,45 @@ function registerFilesCommands(program, options = {}) {
10120
8616
  );
10121
8617
  return;
10122
8618
  }
10123
- writeLine6(stdout, `Downloaded file to "${commandOptions.output}".`);
8619
+ writeLine5(stdout, `Downloaded file to "${commandOptions.output}".`);
10124
8620
  return;
10125
8621
  }
10126
- writeBinary2(stdout, data);
8622
+ writeBinary(stdout, data);
10127
8623
  });
10128
8624
  });
10129
8625
  files.command("delete").description("Delete a file").argument("<file>", "file identifier").action(function action(file) {
10130
8626
  const { api, json, readOnly } = createFilesApi(this, filePath);
10131
- ensureWritable5("files delete", readOnly, "destructive");
10132
- const fileSelector = parseUuidOrSlugSelector5(file);
8627
+ ensureWritable4("files delete", readOnly, "destructive");
8628
+ const fileSelector = parseUuidOrSlugSelector4(file);
10133
8629
  return api.deleteFile(fileSelector).then((data) => {
10134
8630
  if (json) {
10135
- emitJson6(stdout, "files delete", data, filePath);
8631
+ emitJson5(stdout, "files delete", data, filePath);
10136
8632
  return;
10137
8633
  }
10138
- writeLine6(stdout, `Deleted file "${fileSelector.value}".`);
8634
+ writeLine5(stdout, `Deleted file "${fileSelector.value}".`);
10139
8635
  });
10140
8636
  });
10141
8637
  files.command("storage").description("Show storage usage information").action(function action() {
10142
8638
  const { api, json } = createFilesApi(this, filePath);
10143
8639
  return api.getStorageInfo().then((data) => {
10144
8640
  if (json) {
10145
- emitJson6(stdout, "files storage", data, filePath);
8641
+ emitJson5(stdout, "files storage", data, filePath);
10146
8642
  return;
10147
8643
  }
10148
8644
  if (isRecord3(data)) {
10149
8645
  printTable([data], Object.keys(data), stdout);
10150
8646
  return;
10151
8647
  }
10152
- writeLine6(stdout, String(data));
8648
+ writeLine5(stdout, String(data));
10153
8649
  });
10154
8650
  });
10155
8651
  }
10156
8652
 
10157
8653
  // src/commands/logs.ts
10158
- import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
8654
+ import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
10159
8655
 
10160
8656
  // src/api/logs.ts
10161
- function selectorValue6(selector) {
8657
+ function selectorValue5(selector) {
10162
8658
  return selector.value;
10163
8659
  }
10164
8660
  var LogsApi = class {
@@ -10167,29 +8663,29 @@ var LogsApi = class {
10167
8663
  }
10168
8664
  listLogs(schema, recordId) {
10169
8665
  return this.client.getJson(
10170
- `/api/v2/schemas/${selectorValue6(schema)}/records/${recordId}/logs`
8666
+ `/api/v2/schemas/${selectorValue5(schema)}/records/${recordId}/logs`
10171
8667
  );
10172
8668
  }
10173
8669
  };
10174
8670
 
10175
8671
  // src/commands/logs.ts
10176
- function getCommandIo7(stdout) {
8672
+ function getCommandIo6(stdout) {
10177
8673
  return stdout ?? process.stdout;
10178
8674
  }
10179
- function writeLine7(stdout, value) {
8675
+ function writeLine6(stdout, value) {
10180
8676
  stdout.write(`${value}
10181
8677
  `);
10182
8678
  }
10183
- function getGlobalOptions7(command) {
8679
+ function getGlobalOptions6(command) {
10184
8680
  return command.optsWithGlobals();
10185
8681
  }
10186
- function emitJson7(stdout, commandName, data, ..._extra) {
10187
- writeLine7(
8682
+ function emitJson6(stdout, commandName, data, ..._extra) {
8683
+ writeLine6(
10188
8684
  stdout,
10189
8685
  JSON.stringify(buildJsonSuccess(data, { command: commandName }))
10190
8686
  );
10191
8687
  }
10192
- function toConfigurationError7(filePath, error) {
8688
+ function toConfigurationError6(filePath, error) {
10193
8689
  if (error instanceof CliError) {
10194
8690
  throw error;
10195
8691
  }
@@ -10204,7 +8700,7 @@ function toConfigurationError7(filePath, error) {
10204
8700
  function createLogsApi(command, filePath) {
10205
8701
  try {
10206
8702
  const config = readRuntimeConfig(filePath);
10207
- const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
8703
+ const runtime = resolveRuntimeContext(config, getGlobalOptions6(command));
10208
8704
  if (!runtime.baseUrl) {
10209
8705
  throw new CliError(
10210
8706
  "configuration_error",
@@ -10221,25 +8717,25 @@ function createLogsApi(command, filePath) {
10221
8717
  json: runtime.json
10222
8718
  };
10223
8719
  } catch (error) {
10224
- toConfigurationError7(filePath, error);
8720
+ toConfigurationError6(filePath, error);
10225
8721
  }
10226
8722
  }
10227
- function parseUuidOrSlugSelector6(input) {
8723
+ function parseUuidOrSlugSelector5(input) {
10228
8724
  try {
10229
8725
  return normalizeUuidOrSlug(input);
10230
8726
  } catch (error) {
10231
8727
  const message = error instanceof Error ? error.message : "Invalid selector.";
10232
- throw new InvalidArgumentError6(message);
8728
+ throw new InvalidArgumentError5(message);
10233
8729
  }
10234
8730
  }
10235
- function isJsonObject5(value) {
8731
+ function isJsonObject4(value) {
10236
8732
  return typeof value === "object" && value !== null && !Array.isArray(value);
10237
8733
  }
10238
8734
  function toTableRows3(data) {
10239
8735
  if (Array.isArray(data)) {
10240
- return data.map((entry) => isJsonObject5(entry) ? entry : { value: entry });
8736
+ return data.map((entry) => isJsonObject4(entry) ? entry : { value: entry });
10241
8737
  }
10242
- if (isJsonObject5(data)) {
8738
+ if (isJsonObject4(data)) {
10243
8739
  return [data];
10244
8740
  }
10245
8741
  return [{ value: data }];
@@ -10249,13 +8745,13 @@ function emitTable3(stdout, data) {
10249
8745
  }
10250
8746
  function registerLogsCommands(program, options = {}) {
10251
8747
  const filePath = options.configPath ?? defaultConfigPath;
10252
- const stdout = getCommandIo7(options.stdout);
8748
+ const stdout = getCommandIo6(options.stdout);
10253
8749
  const logs = program.command("logs").description("Inspect record change logs");
10254
- 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) {
10255
8751
  const { api, json } = createLogsApi(this, filePath);
10256
8752
  const data = await api.listLogs(schema, record.value);
10257
8753
  if (json) {
10258
- emitJson7(stdout, "logs list", data, filePath);
8754
+ emitJson6(stdout, "logs list", data, filePath);
10259
8755
  return;
10260
8756
  }
10261
8757
  emitTable3(stdout, data);
@@ -10263,11 +8759,11 @@ function registerLogsCommands(program, options = {}) {
10263
8759
  }
10264
8760
 
10265
8761
  // src/commands/navigation.ts
10266
- import { readFileSync as readFileSync7 } from "fs";
10267
- import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
8762
+ import { readFileSync as readFileSync6 } from "fs";
8763
+ import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
10268
8764
 
10269
8765
  // src/api/navigation.ts
10270
- function jsonOptions5(body, method) {
8766
+ function jsonOptions4(body, method) {
10271
8767
  return {
10272
8768
  method,
10273
8769
  headers: {
@@ -10276,7 +8772,7 @@ function jsonOptions5(body, method) {
10276
8772
  body: JSON.stringify(body)
10277
8773
  };
10278
8774
  }
10279
- function selectorValue7(selector) {
8775
+ function selectorValue6(selector) {
10280
8776
  return selector.value;
10281
8777
  }
10282
8778
  var NavigationApi = class {
@@ -10289,44 +8785,44 @@ var NavigationApi = class {
10289
8785
  createFolder(body) {
10290
8786
  return this.client.requestJson(
10291
8787
  "/api/v2/navigation/folders",
10292
- jsonOptions5(body, "POST")
8788
+ jsonOptions4(body, "POST")
10293
8789
  );
10294
8790
  }
10295
8791
  updateFolder(folder, body) {
10296
8792
  return this.client.requestJson(
10297
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
10298
- jsonOptions5(body, "PATCH")
8793
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8794
+ jsonOptions4(body, "PATCH")
10299
8795
  );
10300
8796
  }
10301
8797
  deleteFolder(folder) {
10302
8798
  return this.client.requestJson(
10303
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
8799
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
10304
8800
  { method: "DELETE" }
10305
8801
  );
10306
8802
  }
10307
8803
  moveResource(body) {
10308
8804
  return this.client.requestJson(
10309
8805
  "/api/v2/navigation/resources:move",
10310
- jsonOptions5(body, "POST")
8806
+ jsonOptions4(body, "POST")
10311
8807
  );
10312
8808
  }
10313
8809
  };
10314
8810
 
10315
8811
  // src/commands/navigation.ts
10316
- function getCommandIo8(stdout) {
8812
+ function getCommandIo7(stdout) {
10317
8813
  return stdout ?? process.stdout;
10318
8814
  }
10319
- function writeLine8(stdout, value) {
8815
+ function writeLine7(stdout, value) {
10320
8816
  stdout.write(`${value}
10321
8817
  `);
10322
8818
  }
10323
- function getGlobalOptions8(command) {
8819
+ function getGlobalOptions7(command) {
10324
8820
  return command.optsWithGlobals();
10325
8821
  }
10326
- function emitJson8(stdout, commandName, data, configPath) {
10327
- 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 })));
10328
8824
  }
10329
- function toConfigurationError8(filePath, error) {
8825
+ function toConfigurationError7(filePath, error) {
10330
8826
  if (error instanceof CliError) {
10331
8827
  throw error;
10332
8828
  }
@@ -10341,7 +8837,7 @@ function toConfigurationError8(filePath, error) {
10341
8837
  function createNavigationApi(command, filePath) {
10342
8838
  try {
10343
8839
  const config = readRuntimeConfig(filePath);
10344
- const runtime = resolveRuntimeContext(config, getGlobalOptions8(command));
8840
+ const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
10345
8841
  if (!runtime.baseUrl) {
10346
8842
  throw new CliError("configuration_error", `Resolved profile "${runtime.profile}" is missing a base URL.`);
10347
8843
  }
@@ -10356,10 +8852,10 @@ function createNavigationApi(command, filePath) {
10356
8852
  readOnly: runtime.readOnly
10357
8853
  };
10358
8854
  } catch (error) {
10359
- toConfigurationError8(filePath, error);
8855
+ toConfigurationError7(filePath, error);
10360
8856
  }
10361
8857
  }
10362
- function ensureWritable6(commandName, readOnly, mode) {
8858
+ function ensureWritable5(commandName, readOnly, mode) {
10363
8859
  if (readOnly) {
10364
8860
  throw new CliError(
10365
8861
  "command_not_allowed_in_read_only_mode",
@@ -10368,12 +8864,12 @@ function ensureWritable6(commandName, readOnly, mode) {
10368
8864
  );
10369
8865
  }
10370
8866
  }
10371
- function parseUuidOrSlugSelector7(input) {
8867
+ function parseUuidOrSlugSelector6(input) {
10372
8868
  try {
10373
8869
  return normalizeUuidOrSlug(input);
10374
8870
  } catch (error) {
10375
8871
  const message = error instanceof Error ? error.message : "Invalid selector.";
10376
- throw new InvalidArgumentError7(message);
8872
+ throw new InvalidArgumentError6(message);
10377
8873
  }
10378
8874
  }
10379
8875
  function parseInteger(value, flagName) {
@@ -10390,7 +8886,7 @@ function readJsonObject(raw, rawFile) {
10390
8886
  if (raw && rawFile) {
10391
8887
  throw new CliError("invalid_cli_usage", 'Use either "--props" or "--props-file", not both.');
10392
8888
  }
10393
- const source = rawFile ? readFileSync7(rawFile, "utf8") : raw;
8889
+ const source = rawFile ? readFileSync6(rawFile, "utf8") : raw;
10394
8890
  if (!source) {
10395
8891
  return {};
10396
8892
  }
@@ -10452,41 +8948,41 @@ function folderRows2(folders) {
10452
8948
  }
10453
8949
  function registerNavigationCommands(program, options = {}) {
10454
8950
  const filePath = options.configPath ?? defaultConfigPath;
10455
- const stdout = getCommandIo8(options.stdout);
8951
+ const stdout = getCommandIo7(options.stdout);
10456
8952
  const navigation = program.command("navigation").description("Manage workspace navigation");
10457
8953
  const folders = navigation.command("folders").description("Manage navigation folders");
10458
8954
  folders.command("list").description("List navigation folders").action(async function action() {
10459
8955
  const { api, json } = createNavigationApi(this, filePath);
10460
8956
  const data = await api.listFolders();
10461
8957
  if (json) {
10462
- emitJson8(stdout, "navigation folders list", data, filePath);
8958
+ emitJson7(stdout, "navigation folders list", data, filePath);
10463
8959
  return;
10464
8960
  }
10465
8961
  printTable(folderRows2(data), ["id", "order", "name", "resourceCount"], stdout);
10466
8962
  });
10467
- 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) {
10468
8964
  const { api, json } = createNavigationApi(this, filePath);
10469
8965
  const data = await api.listFolders();
10470
8966
  const resolved = resolveFolder2(data, folder);
10471
8967
  if (json) {
10472
- emitJson8(stdout, "navigation folders get", resolved, filePath);
8968
+ emitJson7(stdout, "navigation folders get", resolved, filePath);
10473
8969
  return;
10474
8970
  }
10475
8971
  printTable(folderRows2([resolved]), ["id", "order", "name", "resourceCount"], stdout);
10476
8972
  });
10477
- 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) {
10478
8974
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10479
- ensureWritable6("navigation folders create", readOnly, "write");
8975
+ ensureWritable5("navigation folders create", readOnly, "write");
10480
8976
  const data = await api.createFolder(buildFolderBody(commandOptions));
10481
8977
  if (json) {
10482
- emitJson8(stdout, "navigation folders create", data, filePath);
8978
+ emitJson7(stdout, "navigation folders create", data, filePath);
10483
8979
  return;
10484
8980
  }
10485
- writeLine8(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
8981
+ writeLine7(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
10486
8982
  });
10487
- 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) {
10488
8984
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10489
- ensureWritable6("navigation folders update", readOnly, "write");
8985
+ ensureWritable5("navigation folders update", readOnly, "write");
10490
8986
  const allFolders = await api.listFolders();
10491
8987
  const resolved = resolveFolder2(allFolders, folder);
10492
8988
  const body = buildFolderBody(commandOptions);
@@ -10495,55 +8991,54 @@ function registerNavigationCommands(program, options = {}) {
10495
8991
  }
10496
8992
  const data = await api.updateFolder({ kind: "uuid", value: resolved.id }, body);
10497
8993
  if (json) {
10498
- emitJson8(stdout, "navigation folders update", data, filePath);
8994
+ emitJson7(stdout, "navigation folders update", data, filePath);
10499
8995
  return;
10500
8996
  }
10501
- 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)}".`);
10502
8998
  });
10503
- 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) {
10504
9000
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10505
- ensureWritable6("navigation folders delete", readOnly, "destructive");
9001
+ ensureWritable5("navigation folders delete", readOnly, "destructive");
10506
9002
  const allFolders = await api.listFolders();
10507
9003
  const resolved = resolveFolder2(allFolders, folder);
10508
9004
  const data = await api.deleteFolder({ kind: "uuid", value: resolved.id });
10509
9005
  if (json) {
10510
- emitJson8(stdout, "navigation folders delete", data, filePath);
9006
+ emitJson7(stdout, "navigation folders delete", data, filePath);
10511
9007
  return;
10512
9008
  }
10513
- writeLine8(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
9009
+ writeLine7(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
10514
9010
  });
10515
- navigation.command("resources").description("Manage navigation resources").command("move").description(
10516
- "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."
10517
- ).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) {
10518
9012
  const { api, json, readOnly } = createNavigationApi(this, filePath);
10519
- ensureWritable6("navigation resources move", readOnly, "write");
9013
+ ensureWritable5("navigation resources move", readOnly, "write");
10520
9014
  const allFolders = await api.listFolders();
10521
- const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector7(commandOptions.to));
9015
+ const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector6(commandOptions.to));
10522
9016
  const data = await api.moveResource({
10523
9017
  resourceId,
9018
+ resourceType: commandOptions.type.toUpperCase(),
10524
9019
  targetFolderId: resolved.id
10525
9020
  });
10526
9021
  if (json) {
10527
- emitJson8(stdout, "navigation resources move", data, filePath);
9022
+ emitJson7(stdout, "navigation resources move", data, filePath);
10528
9023
  return;
10529
9024
  }
10530
- writeLine8(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
9025
+ writeLine7(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
10531
9026
  });
10532
9027
  }
10533
9028
 
10534
9029
  // src/commands/profiles.ts
10535
- function getCommandIo9(stdout) {
9030
+ function getCommandIo8(stdout) {
10536
9031
  return stdout ?? process.stdout;
10537
9032
  }
10538
- function writeLine9(stdout, value) {
9033
+ function writeLine8(stdout, value) {
10539
9034
  stdout.write(`${value}
10540
9035
  `);
10541
9036
  }
10542
- function getGlobalOptions9(command) {
9037
+ function getGlobalOptions8(command) {
10543
9038
  return command.optsWithGlobals();
10544
9039
  }
10545
- function emitJson9(stdout, commandName, data, configPath) {
10546
- writeLine9(
9040
+ function emitJson8(stdout, commandName, data, configPath) {
9041
+ writeLine8(
10547
9042
  stdout,
10548
9043
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
10549
9044
  );
@@ -10599,15 +9094,15 @@ function emitProfilesTable(stdout, data) {
10599
9094
  }
10600
9095
  function registerProfilesCommands(program, options = {}) {
10601
9096
  const filePath = options.configPath ?? defaultConfigPath;
10602
- const stdout = getCommandIo9(options.stdout);
9097
+ const stdout = getCommandIo8(options.stdout);
10603
9098
  const profiles = program.command("profiles").description("Manage local CLI profiles");
10604
9099
  profiles.command("list").description("List configured profiles").action(function action() {
10605
9100
  const config = readRequiredConfig(filePath);
10606
9101
  const data = Object.entries(config.profiles).map(
10607
9102
  ([name, profile]) => toDisplayProfile(name, profile, config.defaultProfile)
10608
9103
  );
10609
- if (getGlobalOptions9(this).json) {
10610
- emitJson9(stdout, "profiles list", data, filePath);
9104
+ if (getGlobalOptions8(this).json) {
9105
+ emitJson8(stdout, "profiles list", data, filePath);
10611
9106
  return;
10612
9107
  }
10613
9108
  emitProfilesTable(stdout, data);
@@ -10616,8 +9111,8 @@ function registerProfilesCommands(program, options = {}) {
10616
9111
  const config = readRequiredConfig(filePath);
10617
9112
  const profile = getRequiredProfile(config, profileName);
10618
9113
  const data = toDisplayProfile(profileName, profile, config.defaultProfile);
10619
- if (getGlobalOptions9(this).json) {
10620
- emitJson9(stdout, "profiles get", data, filePath);
9114
+ if (getGlobalOptions8(this).json) {
9115
+ emitJson8(stdout, "profiles get", data, filePath);
10621
9116
  return;
10622
9117
  }
10623
9118
  emitProfilesTable(stdout, [data]);
@@ -10631,11 +9126,11 @@ function registerProfilesCommands(program, options = {}) {
10631
9126
  profile: profileName,
10632
9127
  defaultProfile: nextConfig.defaultProfile
10633
9128
  };
10634
- if (getGlobalOptions9(this).json) {
10635
- emitJson9(stdout, "profiles use", data, filePath);
9129
+ if (getGlobalOptions8(this).json) {
9130
+ emitJson8(stdout, "profiles use", data, filePath);
10636
9131
  return;
10637
9132
  }
10638
- writeLine9(stdout, `Using profile "${profileName}".`);
9133
+ writeLine8(stdout, `Using profile "${profileName}".`);
10639
9134
  });
10640
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) {
10641
9136
  const config = loadConfigForAdd(filePath);
@@ -10659,11 +9154,11 @@ function registerProfilesCommands(program, options = {}) {
10659
9154
  nextConfig.profiles[profileName] ?? {},
10660
9155
  nextConfig.defaultProfile
10661
9156
  );
10662
- if (getGlobalOptions9(this).json) {
10663
- emitJson9(stdout, "profiles add", data, filePath);
9157
+ if (getGlobalOptions8(this).json) {
9158
+ emitJson8(stdout, "profiles add", data, filePath);
10664
9159
  return;
10665
9160
  }
10666
- writeLine9(stdout, `Added profile "${profileName}".`);
9161
+ writeLine8(stdout, `Added profile "${profileName}".`);
10667
9162
  });
10668
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) {
10669
9164
  if (commandOptions.apiKey === void 0 && commandOptions.baseUrl === void 0) {
@@ -10685,11 +9180,11 @@ function registerProfilesCommands(program, options = {}) {
10685
9180
  nextConfig.profiles[profileName] ?? {},
10686
9181
  nextConfig.defaultProfile
10687
9182
  );
10688
- if (getGlobalOptions9(this).json) {
10689
- emitJson9(stdout, "profiles update", data, filePath);
9183
+ if (getGlobalOptions8(this).json) {
9184
+ emitJson8(stdout, "profiles update", data, filePath);
10690
9185
  return;
10691
9186
  }
10692
- writeLine9(stdout, `Updated profile "${profileName}".`);
9187
+ writeLine8(stdout, `Updated profile "${profileName}".`);
10693
9188
  });
10694
9189
  profiles.command("remove").description("Remove a profile from the local config").argument("<profile>", "profile name").action(function action(profileName) {
10695
9190
  const config = readRequiredConfig(filePath);
@@ -10700,20 +9195,20 @@ function registerProfilesCommands(program, options = {}) {
10700
9195
  profile: profileName,
10701
9196
  defaultProfile: nextConfig.defaultProfile
10702
9197
  };
10703
- if (getGlobalOptions9(this).json) {
10704
- emitJson9(stdout, "profiles remove", data, filePath);
9198
+ if (getGlobalOptions8(this).json) {
9199
+ emitJson8(stdout, "profiles remove", data, filePath);
10705
9200
  return;
10706
9201
  }
10707
- writeLine9(stdout, `Removed profile "${profileName}".`);
9202
+ writeLine8(stdout, `Removed profile "${profileName}".`);
10708
9203
  });
10709
9204
  }
10710
9205
 
10711
9206
  // src/commands/records.ts
10712
- import { readFileSync as readFileSync8 } from "fs";
10713
- import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
9207
+ import { readFileSync as readFileSync7 } from "fs";
9208
+ import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
10714
9209
 
10715
9210
  // src/api/records.ts
10716
- function jsonOptions6(body, method) {
9211
+ function jsonOptions5(body, method) {
10717
9212
  return {
10718
9213
  method,
10719
9214
  headers: {
@@ -10722,7 +9217,7 @@ function jsonOptions6(body, method) {
10722
9217
  body: JSON.stringify(body)
10723
9218
  };
10724
9219
  }
10725
- function selectorValue8(selector) {
9220
+ function selectorValue7(selector) {
10726
9221
  return selector.value;
10727
9222
  }
10728
9223
  var RecordsApi = class {
@@ -10737,7 +9232,7 @@ var RecordsApi = class {
10737
9232
  if (query.offset !== void 0) {
10738
9233
  params.set("offset", String(query.offset));
10739
9234
  }
10740
- const path = `/api/v2/schemas/${selectorValue8(schema)}/records`;
9235
+ const path = `/api/v2/schemas/${selectorValue7(schema)}/records`;
10741
9236
  const queryString = params.toString();
10742
9237
  return this.client.getJson(
10743
9238
  queryString ? `${path}?${queryString}` : path
@@ -10746,36 +9241,36 @@ var RecordsApi = class {
10746
9241
  queryRecords(schema, query) {
10747
9242
  const body = this.normalizeQueryInput(query);
10748
9243
  return this.client.requestJson(
10749
- `/api/v2/schemas/${selectorValue8(schema)}/records:query`,
10750
- jsonOptions6(body, "POST")
9244
+ `/api/v2/schemas/${selectorValue7(schema)}/records:query`,
9245
+ jsonOptions5(body, "POST")
10751
9246
  );
10752
9247
  }
10753
9248
  getRecord(schema, record) {
10754
9249
  return this.client.getJson(
10755
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`
9250
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`
10756
9251
  );
10757
9252
  }
10758
- createRecords(schema, records) {
9253
+ createRecord(schema, input) {
10759
9254
  return this.client.requestJson(
10760
- `/api/v2/schemas/${selectorValue8(schema)}/records`,
10761
- jsonOptions6({ records }, "POST")
9255
+ `/api/v2/schemas/${selectorValue7(schema)}/records`,
9256
+ jsonOptions5(input, "POST")
10762
9257
  );
10763
9258
  }
10764
9259
  updateRecord(schema, record, input) {
10765
9260
  return this.client.requestJson(
10766
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
10767
- jsonOptions6(input, "PATCH")
9261
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9262
+ jsonOptions5(input, "PATCH")
10768
9263
  );
10769
9264
  }
10770
- deleteRecords(schema, recordIds) {
9265
+ deleteRecord(schema, record) {
10771
9266
  return this.client.requestJson(
10772
- `/api/v2/schemas/${selectorValue8(schema)}/records:delete`,
10773
- jsonOptions6({ recordIds }, "POST")
9267
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9268
+ { method: "DELETE" }
10774
9269
  );
10775
9270
  }
10776
9271
  clearRecords(schema) {
10777
9272
  return this.client.requestJson(
10778
- `/api/v2/schemas/${selectorValue8(schema)}/records:clear`,
9273
+ `/api/v2/schemas/${selectorValue7(schema)}/records:clear`,
10779
9274
  { method: "DELETE" }
10780
9275
  );
10781
9276
  }
@@ -10808,7 +9303,7 @@ var RecordsApi = class {
10808
9303
  };
10809
9304
 
10810
9305
  // src/api/schemas.ts
10811
- function jsonOptions7(body, method) {
9306
+ function jsonOptions6(body, method) {
10812
9307
  return {
10813
9308
  method,
10814
9309
  headers: {
@@ -10817,7 +9312,7 @@ function jsonOptions7(body, method) {
10817
9312
  body: JSON.stringify(body)
10818
9313
  };
10819
9314
  }
10820
- function selectorValue9(selector) {
9315
+ function selectorValue8(selector) {
10821
9316
  return selector.value;
10822
9317
  }
10823
9318
  var SchemasApi = class {
@@ -10828,76 +9323,150 @@ var SchemasApi = class {
10828
9323
  return this.client.getJson("/api/v2/schemas");
10829
9324
  }
10830
9325
  getSchema(schema) {
10831
- return this.client.getJson(`/api/v2/schemas/${selectorValue9(schema)}`);
9326
+ return this.client.getJson(`/api/v2/schemas/${selectorValue8(schema)}`);
10832
9327
  }
10833
9328
  createSchema(input) {
10834
- return this.client.requestJson("/api/v2/schemas", jsonOptions7(input, "POST"));
9329
+ return this.client.requestJson("/api/v2/schemas", jsonOptions6(input, "POST"));
10835
9330
  }
10836
9331
  updateSchema(schema, input) {
10837
9332
  return this.client.requestJson(
10838
- `/api/v2/schemas/${selectorValue9(schema)}`,
10839
- jsonOptions7(input, "PATCH")
9333
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9334
+ jsonOptions6(input, "PATCH")
10840
9335
  );
10841
9336
  }
10842
- setUniqueFields(schema, input) {
9337
+ deleteSchema(schema) {
10843
9338
  return this.client.requestJson(
10844
- `/api/v2/schemas/${selectorValue9(schema)}/unique-fields`,
10845
- jsonOptions7(input, "PUT")
9339
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9340
+ { method: "DELETE" }
10846
9341
  );
10847
9342
  }
10848
- 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) {
9353
+ return this.client.requestJson(
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) {
10849
9365
  return this.client.requestJson(
10850
- `/api/v2/schemas/${selectorValue9(schema)}`,
9366
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`,
10851
9367
  { method: "DELETE" }
10852
9368
  );
10853
9369
  }
10854
- async listFields(schema) {
10855
- const result = await this.getSchema(schema);
10856
- 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}".`);
10857
9413
  }
10858
- getField(schema, field) {
10859
- return this.client.getJson(
10860
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`
10861
- );
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;
10862
9422
  }
10863
- createField(schema, input) {
10864
- return this.client.requestJson(
10865
- `/api/v2/schemas/${selectorValue9(schema)}/fields`,
10866
- jsonOptions7(input, "POST")
10867
- );
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;
10868
9429
  }
10869
- updateField(schema, field, input) {
10870
- return this.client.requestJson(
10871
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`,
10872
- jsonOptions7(input, "PATCH")
10873
- );
9430
+ if (rawValue.length === 0) {
9431
+ throw new Error(`Comparator "${comparator}" requires a value.`);
10874
9432
  }
10875
- deleteField(schema, field) {
10876
- return this.client.requestJson(
10877
- `/api/v2/schemas/${selectorValue9(schema)}/fields/${selectorValue9(field)}`,
10878
- { 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}".`
10879
9441
  );
10880
9442
  }
10881
- };
9443
+ const comparator = comparatorCandidate;
9444
+ return {
9445
+ field,
9446
+ comparator,
9447
+ value: normalizeValue(comparator, rawValue),
9448
+ raw: trimmed
9449
+ };
9450
+ }
10882
9451
 
10883
9452
  // src/commands/records.ts
10884
- function getCommandIo10(stdout) {
9453
+ function getCommandIo9(stdout) {
10885
9454
  return stdout ?? process.stdout;
10886
9455
  }
10887
- function writeLine10(stdout, value) {
9456
+ function writeLine9(stdout, value) {
10888
9457
  stdout.write(`${value}
10889
9458
  `);
10890
9459
  }
10891
- function getGlobalOptions10(command) {
9460
+ function getGlobalOptions9(command) {
10892
9461
  return command.optsWithGlobals();
10893
9462
  }
10894
- function emitJson10(stdout, commandName, data, configPath, meta = {}) {
10895
- writeLine10(
9463
+ function emitJson9(stdout, commandName, data, configPath, meta = {}) {
9464
+ writeLine9(
10896
9465
  stdout,
10897
9466
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
10898
9467
  );
10899
9468
  }
10900
- function toConfigurationError9(filePath, error) {
9469
+ function toConfigurationError8(filePath, error) {
10901
9470
  if (error instanceof CliError) {
10902
9471
  throw error;
10903
9472
  }
@@ -10912,7 +9481,7 @@ function toConfigurationError9(filePath, error) {
10912
9481
  function createRecordsApi(command, filePath) {
10913
9482
  try {
10914
9483
  const config = readRuntimeConfig(filePath);
10915
- const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
9484
+ const runtime = resolveRuntimeContext(config, getGlobalOptions9(command));
10916
9485
  if (!runtime.baseUrl) {
10917
9486
  throw new CliError(
10918
9487
  "configuration_error",
@@ -10931,10 +9500,10 @@ function createRecordsApi(command, filePath) {
10931
9500
  readOnly: runtime.readOnly
10932
9501
  };
10933
9502
  } catch (error) {
10934
- toConfigurationError9(filePath, error);
9503
+ toConfigurationError8(filePath, error);
10935
9504
  }
10936
9505
  }
10937
- function ensureWritable7(commandName, readOnly, commandMode) {
9506
+ function ensureWritable6(commandName, readOnly, commandMode) {
10938
9507
  if (readOnly) {
10939
9508
  throw new CliError(
10940
9509
  "command_not_allowed_in_read_only_mode",
@@ -10946,24 +9515,24 @@ function ensureWritable7(commandName, readOnly, commandMode) {
10946
9515
  );
10947
9516
  }
10948
9517
  }
10949
- function parseUuidOrSlugSelector8(input) {
9518
+ function parseUuidOrSlugSelector7(input) {
10950
9519
  try {
10951
9520
  return normalizeUuidOrSlug(input);
10952
9521
  } catch (error) {
10953
9522
  const message = error instanceof Error ? error.message : "Invalid selector.";
10954
- throw new InvalidArgumentError8(message);
9523
+ throw new InvalidArgumentError7(message);
10955
9524
  }
10956
9525
  }
10957
9526
  function parseNonNegativeInteger2(input) {
10958
9527
  if (!/^\d+$/.test(input.trim())) {
10959
- throw new InvalidArgumentError8(`Expected a non-negative integer, received "${input}".`);
9528
+ throw new InvalidArgumentError7(`Expected a non-negative integer, received "${input}".`);
10960
9529
  }
10961
9530
  return Number(input);
10962
9531
  }
10963
9532
  function parseCommaSeparatedValues(input, label) {
10964
9533
  const values = input.split(",").map((value) => value.trim()).filter(Boolean);
10965
9534
  if (values.length === 0) {
10966
- throw new InvalidArgumentError8(`Expected ${label} to contain at least one value.`);
9535
+ throw new InvalidArgumentError7(`Expected ${label} to contain at least one value.`);
10967
9536
  }
10968
9537
  return values;
10969
9538
  }
@@ -10972,7 +9541,7 @@ function parseExpressionValue(input) {
10972
9541
  return parseExpression(input);
10973
9542
  } catch (error) {
10974
9543
  const message = error instanceof Error ? error.message : "Invalid expression.";
10975
- throw new InvalidArgumentError8(message);
9544
+ throw new InvalidArgumentError7(message);
10976
9545
  }
10977
9546
  }
10978
9547
  function parseKeyValueAssignment(input) {
@@ -10980,7 +9549,7 @@ function parseKeyValueAssignment(input) {
10980
9549
  return parseKeyValue(input);
10981
9550
  } catch (error) {
10982
9551
  const message = error instanceof Error ? error.message : "Invalid assignment.";
10983
- throw new InvalidArgumentError8(message);
9552
+ throw new InvalidArgumentError7(message);
10984
9553
  }
10985
9554
  }
10986
9555
  function parseJsonKeyValueAssignment(input) {
@@ -10988,75 +9557,14 @@ function parseJsonKeyValueAssignment(input) {
10988
9557
  return parseJsonAssignment(input);
10989
9558
  } catch (error) {
10990
9559
  const message = error instanceof Error ? error.message : "Invalid JSON assignment.";
10991
- throw new InvalidArgumentError8(message);
10992
- }
10993
- }
10994
- function dedupeStrings(values) {
10995
- return [...new Set(values)];
10996
- }
10997
- function toRecordUuid(value) {
10998
- try {
10999
- const normalized = normalizeUuidOrSlug(value);
11000
- return normalized.kind === "uuid" ? normalized.value : null;
11001
- } catch {
11002
- return null;
11003
- }
11004
- }
11005
- function collectRecordIds(value, previous = []) {
11006
- const uuid = toRecordUuid(value.trim());
11007
- if (!uuid) {
11008
- throw new InvalidArgumentError8(`Expected a record UUID, received "${value}".`);
11009
- }
11010
- return [...previous, uuid];
11011
- }
11012
- function readRecordIdsFromFile(path) {
11013
- let contents;
11014
- try {
11015
- contents = readFileSync8(path, "utf8");
11016
- } catch (error) {
11017
- const message = error instanceof Error ? error.message : "Unable to read file.";
11018
- throw new CliError(
11019
- "invalid_cli_usage",
11020
- `Failed to read record ids from ${path}: ${message}`
11021
- );
11022
- }
11023
- const ids = [];
11024
- contents.split(/\r?\n/).forEach((line, index) => {
11025
- const value = line.trim();
11026
- if (!value) {
11027
- return;
11028
- }
11029
- const uuid = toRecordUuid(value);
11030
- if (!uuid) {
11031
- throw new CliError(
11032
- "invalid_cli_usage",
11033
- `Invalid record UUID "${value}" at ${path}:${index + 1}.`
11034
- );
11035
- }
11036
- ids.push(uuid);
11037
- });
11038
- return ids;
11039
- }
11040
- function resolveDeleteRecordIds(options) {
11041
- const flagIds = options.record ?? [];
11042
- const fileIds = options.recordsFile ? readRecordIdsFromFile(options.recordsFile) : [];
11043
- const recordIds = dedupeStrings([...flagIds, ...fileIds]);
11044
- if (recordIds.length === 0) {
11045
- throw new CliError(
11046
- "invalid_cli_usage",
11047
- 'Provide at least one record id via "--record <uuid>" (repeatable) or "--records-file <path>".'
11048
- );
9560
+ throw new InvalidArgumentError7(message);
11049
9561
  }
11050
- return recordIds;
11051
9562
  }
11052
9563
  function collectStringValues(value, previous = []) {
11053
9564
  return [...previous, value];
11054
9565
  }
11055
- function collectSelectValues(value, previous = []) {
11056
- return dedupeStrings([...previous, ...parseCommaSeparatedValues(value, "--select")]);
11057
- }
11058
9566
  function collectSortValues(value, previous = []) {
11059
- return dedupeStrings([...previous, ...parseCommaSeparatedValues(value, "--sort")]);
9567
+ return [...previous, ...parseCommaSeparatedValues(value, "--sort")];
11060
9568
  }
11061
9569
  function collectWhereExpressions(value, previous = []) {
11062
9570
  return [...previous, parseExpressionValue(value)];
@@ -11067,7 +9575,7 @@ function collectKeyValueAssignments(value, previous = []) {
11067
9575
  function collectJsonAssignments(value, previous = []) {
11068
9576
  return [...previous, parseJsonKeyValueAssignment(value)];
11069
9577
  }
11070
- function isJsonObject6(value) {
9578
+ function isJsonObject5(value) {
11071
9579
  return typeof value === "object" && value !== null && !Array.isArray(value);
11072
9580
  }
11073
9581
  function parseRawJsonObject2(input, sourceLabel) {
@@ -11081,7 +9589,7 @@ function parseRawJsonObject2(input, sourceLabel) {
11081
9589
  `Failed to parse JSON from ${sourceLabel}: ${message}`
11082
9590
  );
11083
9591
  }
11084
- if (!isJsonObject6(parsed)) {
9592
+ if (!isJsonObject5(parsed)) {
11085
9593
  throw new CliError(
11086
9594
  "invalid_cli_usage",
11087
9595
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -11102,7 +9610,7 @@ function readRawObject3(raw, rawFile) {
11102
9610
  if (rawFile) {
11103
9611
  let contents;
11104
9612
  try {
11105
- contents = readFileSync8(rawFile, "utf8");
9613
+ contents = readFileSync7(rawFile, "utf8");
11106
9614
  } catch (error) {
11107
9615
  const message = error instanceof Error ? error.message : "Unable to read file.";
11108
9616
  throw new CliError(
@@ -11114,7 +9622,7 @@ function readRawObject3(raw, rawFile) {
11114
9622
  }
11115
9623
  return {};
11116
9624
  }
11117
- function isEmptyObject5(value) {
9625
+ function isEmptyObject4(value) {
11118
9626
  return Object.keys(value).length === 0;
11119
9627
  }
11120
9628
  function buildAssignmentObject(assignments = [], jsonAssignments = []) {
@@ -11146,9 +9654,6 @@ function buildRecordQueryInput(options, allowRaw) {
11146
9654
  if (where && where.length > 0) {
11147
9655
  input.where = where;
11148
9656
  }
11149
- if (options.search !== void 0) {
11150
- input.search = { term: options.search };
11151
- }
11152
9657
  if (options.sort && options.sort.length > 0) {
11153
9658
  input.sort = [...options.sort];
11154
9659
  }
@@ -11160,80 +9665,53 @@ function buildRecordQueryInput(options, allowRaw) {
11160
9665
  }
11161
9666
  return input;
11162
9667
  }
11163
- function readRecordsFromFile(path) {
11164
- let contents;
11165
- try {
11166
- contents = readFileSync8(path, "utf8");
11167
- } catch (error) {
11168
- const message = error instanceof Error ? error.message : "Unable to read file.";
11169
- throw new CliError(
11170
- "invalid_cli_usage",
11171
- `Failed to read records from ${path}: ${message}`
11172
- );
11173
- }
11174
- let parsed;
11175
- try {
11176
- parsed = JSON.parse(contents);
11177
- } catch (error) {
11178
- 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)) {
11179
9674
  throw new CliError(
11180
9675
  "invalid_cli_usage",
11181
- `Failed to parse JSON from --records-file ${path}: ${message}`
9676
+ 'Provide record fields via "--set", "--set-json", "--raw", or "--raw-file".'
11182
9677
  );
11183
9678
  }
11184
- if (!Array.isArray(parsed)) {
11185
- throw new CliError(
11186
- "invalid_cli_usage",
11187
- `Expected --records-file ${path} to contain a JSON array of record objects.`
11188
- );
9679
+ return { values };
9680
+ }
9681
+ function readRawSetPayload2(raw) {
9682
+ const setValue = raw.set;
9683
+ if (setValue === void 0) {
9684
+ return {};
11189
9685
  }
11190
- if (parsed.length === 0) {
9686
+ if (!isJsonObject5(setValue)) {
11191
9687
  throw new CliError(
11192
9688
  "invalid_cli_usage",
11193
- `--records-file ${path} must contain at least one record.`
9689
+ 'Expected raw update payload field "set" to be a JSON object.'
11194
9690
  );
11195
9691
  }
11196
- return parsed.map((record, index) => {
11197
- if (!isJsonObject6(record)) {
11198
- throw new CliError(
11199
- "invalid_cli_usage",
11200
- `Record at index ${index} in --records-file ${path} must be a JSON object.`
11201
- );
11202
- }
11203
- return record;
11204
- });
9692
+ return { ...setValue };
11205
9693
  }
11206
- function buildCreateRecords(options) {
11207
- const hasSingleRecordFlags = (options.set?.length ?? 0) > 0 || (options.setJson?.length ?? 0) > 0 || options.raw !== void 0 || options.rawFile !== void 0;
11208
- if (options.recordsFile !== void 0) {
11209
- if (hasSingleRecordFlags) {
11210
- throw new CliError(
11211
- "invalid_cli_usage",
11212
- 'Provide either "--records-file" or the single-record flags (--set/--set-json/--raw/--raw-file), not both.'
11213
- );
11214
- }
11215
- return readRecordsFromFile(options.recordsFile);
9694
+ function readRawUnsetPayload2(raw) {
9695
+ const unsetValue = raw.unset;
9696
+ if (unsetValue === void 0) {
9697
+ return [];
11216
9698
  }
11217
- const values = {
11218
- ...readRawObject3(options.raw, options.rawFile),
11219
- ...buildAssignmentObject(options.set, options.setJson)
11220
- };
11221
- if (isEmptyObject5(values)) {
9699
+ if (!Array.isArray(unsetValue) || !unsetValue.every((value) => typeof value === "string")) {
11222
9700
  throw new CliError(
11223
9701
  "invalid_cli_usage",
11224
- '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.'
11225
9703
  );
11226
9704
  }
11227
- return [values];
9705
+ return [...unsetValue];
11228
9706
  }
11229
9707
  function buildRecordUpdateInput(options) {
11230
9708
  const raw = readRawObject3(options.raw, options.rawFile);
11231
- const input = {};
9709
+ const input = { ...raw };
11232
9710
  const setPayload = {
11233
- ...raw,
9711
+ ...readRawSetPayload2(raw),
11234
9712
  ...buildAssignmentObject(options.set, options.setJson)
11235
9713
  };
11236
- const unsetPayload = [...options.unset ?? []];
9714
+ const unsetPayload = [...readRawUnsetPayload2(raw), ...options.unset ?? []];
11237
9715
  for (const key of Object.keys(setPayload)) {
11238
9716
  const unsetIndex = unsetPayload.indexOf(key);
11239
9717
  if (unsetIndex !== -1) {
@@ -11250,7 +9728,7 @@ function buildRecordUpdateInput(options) {
11250
9728
  } else {
11251
9729
  delete input.unset;
11252
9730
  }
11253
- if (isEmptyObject5(input)) {
9731
+ if (isEmptyObject4(input)) {
11254
9732
  throw new CliError(
11255
9733
  "invalid_cli_usage",
11256
9734
  'Provide record updates via "--set", "--set-json", "--unset", "--raw", or "--raw-file".'
@@ -11260,9 +9738,9 @@ function buildRecordUpdateInput(options) {
11260
9738
  }
11261
9739
  function toTableRows4(data) {
11262
9740
  if (Array.isArray(data)) {
11263
- return data.map((entry) => isJsonObject6(entry) ? entry : { value: entry });
9741
+ return data.map((entry) => isJsonObject5(entry) ? entry : { value: entry });
11264
9742
  }
11265
- if (isJsonObject6(data)) {
9743
+ if (isJsonObject5(data)) {
11266
9744
  return [data];
11267
9745
  }
11268
9746
  return [{ value: data }];
@@ -11292,9 +9770,9 @@ async function resolveSchemaSelector(api, selector) {
11292
9770
  }
11293
9771
  function registerRecordsCommands(program, options = {}) {
11294
9772
  const filePath = options.configPath ?? defaultConfigPath;
11295
- const stdout = getCommandIo10(options.stdout);
9773
+ const stdout = getCommandIo9(options.stdout);
11296
9774
  const records = program.command("records").description("Manage schema records");
11297
- 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) {
11298
9776
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11299
9777
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11300
9778
  const data = await api.listRecords(
@@ -11303,7 +9781,7 @@ function registerRecordsCommands(program, options = {}) {
11303
9781
  );
11304
9782
  const recordsData = getQueryRecords(data);
11305
9783
  if (json) {
11306
- emitJson10(
9784
+ emitJson9(
11307
9785
  stdout,
11308
9786
  "records list",
11309
9787
  recordsData,
@@ -11314,10 +9792,7 @@ function registerRecordsCommands(program, options = {}) {
11314
9792
  }
11315
9793
  emitTable4(stdout, recordsData);
11316
9794
  });
11317
- 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(
11318
- "--search <term>",
11319
- "free-text search term (matched across the schema's searchable fields)"
11320
- ).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) {
11321
9796
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11322
9797
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11323
9798
  const data = await api.queryRecords(
@@ -11326,7 +9801,7 @@ function registerRecordsCommands(program, options = {}) {
11326
9801
  );
11327
9802
  const recordsData = getQueryRecords(data);
11328
9803
  if (json) {
11329
- emitJson10(
9804
+ emitJson9(
11330
9805
  stdout,
11331
9806
  "records query",
11332
9807
  recordsData,
@@ -11337,40 +9812,33 @@ function registerRecordsCommands(program, options = {}) {
11337
9812
  }
11338
9813
  emitTable4(stdout, recordsData);
11339
9814
  });
11340
- 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) {
11341
9816
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
11342
9817
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11343
9818
  const data = await api.getRecord(resolvedSchema, record);
11344
9819
  if (json) {
11345
- emitJson10(stdout, "records get", data, filePath);
9820
+ emitJson9(stdout, "records get", data, filePath);
11346
9821
  return;
11347
9822
  }
11348
9823
  emitTable4(stdout, data);
11349
9824
  });
11350
- records.command("create").description("Create one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).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").option(
11351
- "--records-file <path>",
11352
- "path to a JSON array of record objects (mutually exclusive with --set/--set-json/--raw/--raw-file)"
11353
- ).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) {
11354
9826
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11355
- ensureWritable7("records create", readOnly, "write");
11356
- const records2 = buildCreateRecords(commandOptions);
9827
+ ensureWritable6("records create", readOnly, "write");
11357
9828
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11358
- const data = await api.createRecords(resolvedSchema, records2);
9829
+ const data = await api.createRecord(
9830
+ resolvedSchema,
9831
+ buildRecordCreateInput(commandOptions)
9832
+ );
11359
9833
  if (json) {
11360
- emitJson10(stdout, "records create", data, filePath);
9834
+ emitJson9(stdout, "records create", data, filePath);
11361
9835
  return;
11362
9836
  }
11363
- writeLine10(stdout, `Created ${data.created.length} record(s) in schema "${schema.value}".`);
11364
- if (data.errors.length > 0) {
11365
- writeLine10(stdout, `${data.errors.length} record(s) rejected:`);
11366
- for (const error of data.errors) {
11367
- writeLine10(stdout, ` - index ${error.index}: ${error.message}`);
11368
- }
11369
- }
9837
+ writeLine9(stdout, `Created record "${getRecordIdentifier(data)}".`);
11370
9838
  });
11371
- records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector8).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 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) {
11372
9840
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11373
- ensureWritable7("records update", readOnly, "write");
9841
+ ensureWritable6("records update", readOnly, "write");
11374
9842
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11375
9843
  const data = await api.updateRecord(
11376
9844
  resolvedSchema,
@@ -11378,71 +9846,60 @@ function registerRecordsCommands(program, options = {}) {
11378
9846
  buildRecordUpdateInput(commandOptions)
11379
9847
  );
11380
9848
  if (json) {
11381
- emitJson10(stdout, "records update", data, filePath);
9849
+ emitJson9(stdout, "records update", data, filePath);
11382
9850
  return;
11383
9851
  }
11384
- writeLine10(stdout, `Updated record "${getRecordIdentifier(data)}".`);
9852
+ writeLine9(stdout, `Updated record "${getRecordIdentifier(data)}".`);
11385
9853
  });
11386
- 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(
11387
- "--records-file <path>",
11388
- "path to a file with one record uuid per line (merged with --record)"
11389
- ).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) {
11390
9855
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11391
- ensureWritable7("records delete", readOnly, "destructive");
11392
- const recordIds = resolveDeleteRecordIds(commandOptions);
9856
+ ensureWritable6("records delete", readOnly, "destructive");
11393
9857
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11394
- 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
+ };
11395
9864
  if (json) {
11396
- emitJson10(stdout, "records delete", data, filePath);
9865
+ emitJson9(stdout, "records delete", data, filePath);
11397
9866
  return;
11398
9867
  }
11399
- writeLine10(
11400
- stdout,
11401
- `Deleted ${recordIds.length} record(s) from schema "${schema.value}".`
11402
- );
9868
+ writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
11403
9869
  });
11404
- 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) {
11405
9871
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
11406
- ensureWritable7("records clear", readOnly, "destructive");
9872
+ ensureWritable6("records clear", readOnly, "destructive");
11407
9873
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
11408
9874
  const data = await api.clearRecords(resolvedSchema);
11409
9875
  if (json) {
11410
- emitJson10(stdout, "records clear", data, filePath);
9876
+ emitJson9(stdout, "records clear", data, filePath);
11411
9877
  return;
11412
9878
  }
11413
- writeLine10(stdout, `Cleared all records from schema "${schema.value}".`);
9879
+ writeLine9(stdout, `Cleared all records from schema "${schema.value}".`);
11414
9880
  });
11415
9881
  }
11416
9882
 
11417
9883
  // src/commands/schemas.ts
11418
- import { readFileSync as readFileSync9 } from "fs";
11419
- import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
11420
- var HIGHLIGHTED_FIELD_HELP = `
11421
- Highlighted field:
11422
- The schema's "main" field. The frontend uses its value as each record's
11423
- display name, in two places:
11424
- - Activity panel: the record's title in the activity side panel
11425
- (the panel with the record's logs and comments).
11426
- - Detail view: the record's name in the left-hand record list you
11427
- browse to open each record's form.
11428
- `;
11429
- function getCommandIo11(stdout) {
9884
+ import { readFileSync as readFileSync8 } from "fs";
9885
+ import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
9886
+ function getCommandIo10(stdout) {
11430
9887
  return stdout ?? process.stdout;
11431
9888
  }
11432
- function writeLine11(stdout, value) {
9889
+ function writeLine10(stdout, value) {
11433
9890
  stdout.write(`${value}
11434
9891
  `);
11435
9892
  }
11436
- function getGlobalOptions11(command) {
9893
+ function getGlobalOptions10(command) {
11437
9894
  return command.optsWithGlobals();
11438
9895
  }
11439
- function emitJson11(stdout, commandName, data, configPath) {
11440
- writeLine11(
9896
+ function emitJson10(stdout, commandName, data, configPath) {
9897
+ writeLine10(
11441
9898
  stdout,
11442
9899
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
11443
9900
  );
11444
9901
  }
11445
- function toConfigurationError10(filePath, error) {
9902
+ function toConfigurationError9(filePath, error) {
11446
9903
  if (error instanceof CliError) {
11447
9904
  throw error;
11448
9905
  }
@@ -11457,7 +9914,7 @@ function toConfigurationError10(filePath, error) {
11457
9914
  function createSchemasApi(command, filePath) {
11458
9915
  try {
11459
9916
  const config = readRuntimeConfig(filePath);
11460
- const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
9917
+ const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
11461
9918
  if (!runtime.baseUrl) {
11462
9919
  throw new CliError(
11463
9920
  "configuration_error",
@@ -11476,10 +9933,10 @@ function createSchemasApi(command, filePath) {
11476
9933
  readOnly: runtime.readOnly
11477
9934
  };
11478
9935
  } catch (error) {
11479
- toConfigurationError10(filePath, error);
9936
+ toConfigurationError9(filePath, error);
11480
9937
  }
11481
9938
  }
11482
- function ensureWritable8(commandName, readOnly, commandMode) {
9939
+ function ensureWritable7(commandName, readOnly, commandMode) {
11483
9940
  if (readOnly) {
11484
9941
  throw new CliError(
11485
9942
  "command_not_allowed_in_read_only_mode",
@@ -11491,17 +9948,14 @@ function ensureWritable8(commandName, readOnly, commandMode) {
11491
9948
  );
11492
9949
  }
11493
9950
  }
11494
- function parseUuidOrSlugSelector9(input) {
9951
+ function parseUuidOrSlugSelector8(input) {
11495
9952
  try {
11496
9953
  return normalizeUuidOrSlug(input);
11497
9954
  } catch (error) {
11498
9955
  const message = error instanceof Error ? error.message : "Invalid selector.";
11499
- throw new InvalidArgumentError9(message);
9956
+ throw new InvalidArgumentError8(message);
11500
9957
  }
11501
9958
  }
11502
- function collectFieldSelectors(value, previous = []) {
11503
- return [...previous, parseUuidOrSlugSelector9(value)];
11504
- }
11505
9959
  function parseBooleanFlag(input) {
11506
9960
  const normalized = input.trim().toLowerCase();
11507
9961
  if (["true", "1", "yes", "y", "on"].includes(normalized)) {
@@ -11510,9 +9964,9 @@ function parseBooleanFlag(input) {
11510
9964
  if (["false", "0", "no", "n", "off"].includes(normalized)) {
11511
9965
  return false;
11512
9966
  }
11513
- throw new InvalidArgumentError9(`Expected a boolean value, received "${input}".`);
9967
+ throw new InvalidArgumentError8(`Expected a boolean value, received "${input}".`);
11514
9968
  }
11515
- function isJsonObject7(value) {
9969
+ function isJsonObject6(value) {
11516
9970
  return typeof value === "object" && value !== null && !Array.isArray(value);
11517
9971
  }
11518
9972
  function parseRawJsonObject3(input, sourceLabel) {
@@ -11526,7 +9980,7 @@ function parseRawJsonObject3(input, sourceLabel) {
11526
9980
  `Failed to parse JSON from ${sourceLabel}: ${message}`
11527
9981
  );
11528
9982
  }
11529
- if (!isJsonObject7(parsed)) {
9983
+ if (!isJsonObject6(parsed)) {
11530
9984
  throw new CliError(
11531
9985
  "invalid_cli_usage",
11532
9986
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -11547,7 +10001,7 @@ function readRawObject4(raw, rawFile) {
11547
10001
  if (rawFile) {
11548
10002
  let contents;
11549
10003
  try {
11550
- contents = readFileSync9(rawFile, "utf8");
10004
+ contents = readFileSync8(rawFile, "utf8");
11551
10005
  } catch (error) {
11552
10006
  const message = error instanceof Error ? error.message : "Unable to read file.";
11553
10007
  throw new CliError(
@@ -11606,7 +10060,7 @@ function applyFieldDefaultValue(input, defaultValue) {
11606
10060
  return;
11607
10061
  }
11608
10062
  const config = input.config;
11609
- if (config !== void 0 && !isJsonObject7(config)) {
10063
+ if (config !== void 0 && !isJsonObject6(config)) {
11610
10064
  throw new CliError(
11611
10065
  "invalid_cli_usage",
11612
10066
  'Expected field "config" to be a JSON object when using "--default".'
@@ -11646,7 +10100,7 @@ function buildFieldCreateInput(options) {
11646
10100
  input.required = options.required;
11647
10101
  }
11648
10102
  applyFieldDefaultValue(input, options.default);
11649
- if ("config" in input && isJsonObject7(input.config) && isEmptyObject6(input.config)) {
10103
+ if ("config" in input && isJsonObject6(input.config) && isEmptyObject5(input.config)) {
11650
10104
  delete input.config;
11651
10105
  }
11652
10106
  return input;
@@ -11719,35 +10173,35 @@ async function resolveFieldSelector(api, schema, selector) {
11719
10173
  value: match.id
11720
10174
  };
11721
10175
  }
11722
- function isEmptyObject6(value) {
10176
+ function isEmptyObject5(value) {
11723
10177
  return Object.keys(value).length === 0;
11724
10178
  }
11725
10179
  function registerSchemasCommands(program, options = {}) {
11726
10180
  const filePath = options.configPath ?? defaultConfigPath;
11727
- const stdout = getCommandIo11(options.stdout);
10181
+ const stdout = getCommandIo10(options.stdout);
11728
10182
  const schemas = program.command("schemas").description("Manage schemas and schema fields");
11729
10183
  schemas.command("list").description("List schemas").action(async function action() {
11730
10184
  const { api, json } = createSchemasApi(this, filePath);
11731
10185
  const data = await api.listSchemas();
11732
10186
  if (json) {
11733
- emitJson11(stdout, "schemas list", data, filePath);
10187
+ emitJson10(stdout, "schemas list", data, filePath);
11734
10188
  return;
11735
10189
  }
11736
10190
  emitSchemasTable(stdout, data);
11737
10191
  });
11738
- 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) {
11739
10193
  const { api, json } = createSchemasApi(this, filePath);
11740
10194
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11741
10195
  const data = await api.getSchema(resolvedSchema);
11742
10196
  if (json) {
11743
- emitJson11(stdout, "schemas get", data, filePath);
10197
+ emitJson10(stdout, "schemas get", data, filePath);
11744
10198
  return;
11745
10199
  }
11746
10200
  emitSchemasTable(stdout, [data]);
11747
10201
  });
11748
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) {
11749
10203
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11750
- ensureWritable8("schemas create", readOnly, "write");
10204
+ ensureWritable7("schemas create", readOnly, "write");
11751
10205
  const input = {
11752
10206
  name: commandOptions.name,
11753
10207
  slug: commandOptions.slug,
@@ -11756,87 +10210,32 @@ function registerSchemasCommands(program, options = {}) {
11756
10210
  };
11757
10211
  const data = await api.createSchema(input);
11758
10212
  if (json) {
11759
- emitJson11(stdout, "schemas create", data, filePath);
10213
+ emitJson10(stdout, "schemas create", data, filePath);
11760
10214
  return;
11761
10215
  }
11762
- writeLine11(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
10216
+ writeLine10(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
11763
10217
  });
11764
- 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(
11765
- "--highlighted-field <field>",
11766
- "its value is used as each record's display name in the UI (field uuid or slug)",
11767
- parseUuidOrSlugSelector9
11768
- ).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) {
11769
10219
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11770
- ensureWritable8("schemas update", readOnly, "write");
10220
+ ensureWritable7("schemas update", readOnly, "write");
11771
10221
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11772
10222
  const input = buildSchemaUpdateInput(commandOptions);
11773
- if (commandOptions.highlightedField !== void 0) {
11774
- const resolvedField = await resolveFieldSelector(
11775
- api,
11776
- resolvedSchema,
11777
- commandOptions.highlightedField
11778
- );
11779
- input.highlightedField = resolvedField.value;
11780
- }
11781
- if (isEmptyObject6(input)) {
10223
+ if (isEmptyObject5(input)) {
11782
10224
  throw new CliError(
11783
10225
  "invalid_cli_usage",
11784
- '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".'
11785
10227
  );
11786
10228
  }
11787
10229
  const data = await api.updateSchema(resolvedSchema, input);
11788
10230
  if (json) {
11789
- emitJson11(stdout, "schemas update", data, filePath);
11790
- return;
11791
- }
11792
- writeLine11(stdout, `Updated schema "${data.slug ?? schema.value}".`);
11793
- }).addHelpText("after", HIGHLIGHTED_FIELD_HELP);
11794
- 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(
11795
- "--field <field>",
11796
- "field uuid or slug to include in the unique constraint (repeatable)",
11797
- collectFieldSelectors,
11798
- []
11799
- ).option("--clear", "clear the unique constraint (sends an empty field list)").action(async function action(schema, commandOptions) {
11800
- const { api, json, readOnly } = createSchemasApi(this, filePath);
11801
- ensureWritable8("schemas set-unique-fields", readOnly, "write");
11802
- const selectors = commandOptions.field ?? [];
11803
- if (commandOptions.clear && selectors.length > 0) {
11804
- throw new CliError(
11805
- "invalid_cli_usage",
11806
- 'Use either "--field" or "--clear", not both.'
11807
- );
11808
- }
11809
- if (!commandOptions.clear && selectors.length === 0) {
11810
- throw new CliError(
11811
- "invalid_cli_usage",
11812
- 'Provide at least one field via "--field", or pass "--clear" to remove the unique constraint.'
11813
- );
11814
- }
11815
- const resolvedSchema = await resolveSchemaSelector2(api, schema);
11816
- const resolvedFields = await Promise.all(
11817
- selectors.map((selector) => resolveFieldSelector(api, resolvedSchema, selector))
11818
- );
11819
- const input = {
11820
- fieldIds: resolvedFields.map((field) => field.value)
11821
- };
11822
- const data = await api.setUniqueFields(resolvedSchema, input);
11823
- if (json) {
11824
- emitJson11(stdout, "schemas set-unique-fields", data, filePath);
11825
- return;
11826
- }
11827
- if (input.fieldIds.length === 0) {
11828
- writeLine11(stdout, `Cleared unique fields on schema "${schema.value}".`);
10231
+ emitJson10(stdout, "schemas update", data, filePath);
11829
10232
  return;
11830
10233
  }
11831
- const count = input.fieldIds.length;
11832
- writeLine11(
11833
- stdout,
11834
- `Set unique fields on schema "${schema.value}" (${count} field${count === 1 ? "" : "s"}).`
11835
- );
10234
+ writeLine10(stdout, `Updated schema "${data.slug ?? schema.value}".`);
11836
10235
  });
11837
- 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) {
11838
10237
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11839
- ensureWritable8("schemas delete", readOnly, "destructive");
10238
+ ensureWritable7("schemas delete", readOnly, "destructive");
11840
10239
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11841
10240
  await api.deleteSchema(resolvedSchema);
11842
10241
  const data = {
@@ -11844,36 +10243,36 @@ function registerSchemasCommands(program, options = {}) {
11844
10243
  deleted: true
11845
10244
  };
11846
10245
  if (json) {
11847
- emitJson11(stdout, "schemas delete", data, filePath);
10246
+ emitJson10(stdout, "schemas delete", data, filePath);
11848
10247
  return;
11849
10248
  }
11850
- writeLine11(stdout, `Deleted schema "${schema.value}".`);
10249
+ writeLine10(stdout, `Deleted schema "${schema.value}".`);
11851
10250
  });
11852
10251
  const fields = schemas.command("fields").description("Manage schema fields");
11853
- 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) {
11854
10253
  const { api, json } = createSchemasApi(this, filePath);
11855
10254
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11856
10255
  const data = await api.listFields(resolvedSchema);
11857
10256
  if (json) {
11858
- emitJson11(stdout, "schemas fields list", data, filePath);
10257
+ emitJson10(stdout, "schemas fields list", data, filePath);
11859
10258
  return;
11860
10259
  }
11861
10260
  emitFieldsTable(stdout, data);
11862
10261
  });
11863
- 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) {
11864
10263
  const { api, json } = createSchemasApi(this, filePath);
11865
10264
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11866
10265
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11867
10266
  const data = await api.getField(resolvedSchema, resolvedField);
11868
10267
  if (json) {
11869
- emitJson11(stdout, "schemas fields get", data, filePath);
10268
+ emitJson10(stdout, "schemas fields get", data, filePath);
11870
10269
  return;
11871
10270
  }
11872
10271
  emitFieldsTable(stdout, [data]);
11873
10272
  });
11874
- 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) {
11875
10274
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11876
- ensureWritable8("schemas fields create", readOnly, "write");
10275
+ ensureWritable7("schemas fields create", readOnly, "write");
11877
10276
  const input = buildFieldCreateInput(commandOptions);
11878
10277
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11879
10278
  let data;
@@ -11883,14 +10282,14 @@ function registerSchemasCommands(program, options = {}) {
11883
10282
  toFieldCreateError(error, input);
11884
10283
  }
11885
10284
  if (json) {
11886
- emitJson11(stdout, "schemas fields create", data, filePath);
10285
+ emitJson10(stdout, "schemas fields create", data, filePath);
11887
10286
  return;
11888
10287
  }
11889
- writeLine11(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
10288
+ writeLine10(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
11890
10289
  });
11891
- 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) {
11892
10291
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11893
- ensureWritable8("schemas fields update", readOnly, "write");
10292
+ ensureWritable7("schemas fields update", readOnly, "write");
11894
10293
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11895
10294
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11896
10295
  const currentField = await api.getField(resolvedSchema, resolvedField);
@@ -11899,7 +10298,7 @@ function registerSchemasCommands(program, options = {}) {
11899
10298
  throw new CliError("invalid_cli_usage", `Field "${field.value}" is missing type metadata.`);
11900
10299
  }
11901
10300
  const input = buildFieldUpdateInput(currentType, commandOptions);
11902
- if (isEmptyObject6(input)) {
10301
+ if (isEmptyObject5(input)) {
11903
10302
  throw new CliError(
11904
10303
  "invalid_cli_usage",
11905
10304
  'Provide at least one field update via "--label", "--required", "--raw", or "--raw-file".'
@@ -11907,14 +10306,14 @@ function registerSchemasCommands(program, options = {}) {
11907
10306
  }
11908
10307
  const data = await api.updateField(resolvedSchema, resolvedField, input);
11909
10308
  if (json) {
11910
- emitJson11(stdout, "schemas fields update", data, filePath);
10309
+ emitJson10(stdout, "schemas fields update", data, filePath);
11911
10310
  return;
11912
10311
  }
11913
- writeLine11(stdout, `Updated field "${data.slug ?? field.value}".`);
10312
+ writeLine10(stdout, `Updated field "${data.slug ?? field.value}".`);
11914
10313
  });
11915
- 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) {
11916
10315
  const { api, json, readOnly } = createSchemasApi(this, filePath);
11917
- ensureWritable8("schemas fields delete", readOnly, "destructive");
10316
+ ensureWritable7("schemas fields delete", readOnly, "destructive");
11918
10317
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
11919
10318
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
11920
10319
  await api.deleteField(resolvedSchema, resolvedField);
@@ -11924,19 +10323,19 @@ function registerSchemasCommands(program, options = {}) {
11924
10323
  deleted: true
11925
10324
  };
11926
10325
  if (json) {
11927
- emitJson11(stdout, "schemas fields delete", data, filePath);
10326
+ emitJson10(stdout, "schemas fields delete", data, filePath);
11928
10327
  return;
11929
10328
  }
11930
- writeLine11(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
10329
+ writeLine10(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
11931
10330
  });
11932
10331
  }
11933
10332
 
11934
10333
  // src/commands/teamspace.ts
11935
- import { readFileSync as readFileSync10 } from "fs";
11936
- import { InvalidArgumentError as InvalidArgumentError10 } from "commander";
10334
+ import { readFileSync as readFileSync9 } from "fs";
10335
+ import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
11937
10336
 
11938
10337
  // src/api/teamspace.ts
11939
- function jsonOptions8(body, method) {
10338
+ function jsonOptions7(body, method) {
11940
10339
  return {
11941
10340
  method,
11942
10341
  headers: {
@@ -11945,7 +10344,7 @@ function jsonOptions8(body, method) {
11945
10344
  body: JSON.stringify(body)
11946
10345
  };
11947
10346
  }
11948
- function selectorValue10(selector) {
10347
+ function selectorValue9(selector) {
11949
10348
  return selector.value;
11950
10349
  }
11951
10350
  var TeamspaceApi = class {
@@ -11966,53 +10365,53 @@ var TeamspaceApi = class {
11966
10365
  createFolder(input) {
11967
10366
  return this.client.requestJson(
11968
10367
  "/api/v2/teamspaces/folders",
11969
- jsonOptions8(input, "POST")
10368
+ jsonOptions7(input, "POST")
11970
10369
  );
11971
10370
  }
11972
10371
  updateFolder(folder, input) {
11973
10372
  return this.client.requestJson(
11974
- `/api/v2/teamspaces/folders/${selectorValue10(folder)}`,
11975
- jsonOptions8(input, "PATCH")
10373
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
10374
+ jsonOptions7(input, "PATCH")
11976
10375
  );
11977
10376
  }
11978
10377
  deleteFolder(folder) {
11979
10378
  return this.client.requestJson(
11980
- `/api/v2/teamspaces/folders/${selectorValue10(folder)}`,
10379
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
11981
10380
  { method: "DELETE" }
11982
10381
  );
11983
10382
  }
11984
10383
  publishResource(input) {
11985
10384
  return this.client.requestJson(
11986
10385
  "/api/v2/teamspaces/resources:publish",
11987
- jsonOptions8(input, "POST")
10386
+ jsonOptions7(input, "POST")
11988
10387
  );
11989
10388
  }
11990
10389
  unpublishResource(resourceId) {
11991
10390
  return this.client.requestJson(
11992
10391
  "/api/v2/teamspaces/resources:unpublish",
11993
- jsonOptions8({ resourceId }, "POST")
10392
+ jsonOptions7({ resourceId }, "POST")
11994
10393
  );
11995
10394
  }
11996
10395
  };
11997
10396
 
11998
10397
  // src/commands/teamspace.ts
11999
- function getCommandIo12(stdout) {
10398
+ function getCommandIo11(stdout) {
12000
10399
  return stdout ?? process.stdout;
12001
10400
  }
12002
- function writeLine12(stdout, value) {
10401
+ function writeLine11(stdout, value) {
12003
10402
  stdout.write(`${value}
12004
10403
  `);
12005
10404
  }
12006
- function getGlobalOptions12(command) {
10405
+ function getGlobalOptions11(command) {
12007
10406
  return command.optsWithGlobals();
12008
10407
  }
12009
- function emitJson12(stdout, commandName, data, configPath) {
12010
- writeLine12(
10408
+ function emitJson11(stdout, commandName, data, configPath) {
10409
+ writeLine11(
12011
10410
  stdout,
12012
10411
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
12013
10412
  );
12014
10413
  }
12015
- function toConfigurationError11(filePath, error) {
10414
+ function toConfigurationError10(filePath, error) {
12016
10415
  if (error instanceof CliError) {
12017
10416
  throw error;
12018
10417
  }
@@ -12027,7 +10426,7 @@ function toConfigurationError11(filePath, error) {
12027
10426
  function createTeamspaceApi(command, filePath) {
12028
10427
  try {
12029
10428
  const config = readRuntimeConfig(filePath);
12030
- const runtime = resolveRuntimeContext(config, getGlobalOptions12(command));
10429
+ const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
12031
10430
  if (!runtime.baseUrl) {
12032
10431
  throw new CliError(
12033
10432
  "configuration_error",
@@ -12045,10 +10444,10 @@ function createTeamspaceApi(command, filePath) {
12045
10444
  readOnly: runtime.readOnly
12046
10445
  };
12047
10446
  } catch (error) {
12048
- toConfigurationError11(filePath, error);
10447
+ toConfigurationError10(filePath, error);
12049
10448
  }
12050
10449
  }
12051
- function ensureWritable9(commandName, readOnly, commandMode) {
10450
+ function ensureWritable8(commandName, readOnly, commandMode) {
12052
10451
  if (readOnly) {
12053
10452
  throw new CliError(
12054
10453
  "command_not_allowed_in_read_only_mode",
@@ -12060,21 +10459,21 @@ function ensureWritable9(commandName, readOnly, commandMode) {
12060
10459
  );
12061
10460
  }
12062
10461
  }
12063
- function parseUuidOrSlugSelector10(input) {
10462
+ function parseUuidOrSlugSelector9(input) {
12064
10463
  try {
12065
10464
  return normalizeUuidOrSlug(input);
12066
10465
  } catch (error) {
12067
10466
  const message = error instanceof Error ? error.message : "Invalid selector.";
12068
- throw new InvalidArgumentError10(message);
10467
+ throw new InvalidArgumentError9(message);
12069
10468
  }
12070
10469
  }
12071
10470
  function parseNonNegativeInteger3(input) {
12072
10471
  if (!/^\d+$/.test(input.trim())) {
12073
- throw new InvalidArgumentError10(`Expected a non-negative integer, received "${input}".`);
10472
+ throw new InvalidArgumentError9(`Expected a non-negative integer, received "${input}".`);
12074
10473
  }
12075
10474
  return Number(input);
12076
10475
  }
12077
- function isJsonObject8(value) {
10476
+ function isJsonObject7(value) {
12078
10477
  return typeof value === "object" && value !== null && !Array.isArray(value);
12079
10478
  }
12080
10479
  function parseRawJsonObject4(input, sourceLabel) {
@@ -12088,7 +10487,7 @@ function parseRawJsonObject4(input, sourceLabel) {
12088
10487
  `Failed to parse JSON from ${sourceLabel}: ${message}`
12089
10488
  );
12090
10489
  }
12091
- if (!isJsonObject8(parsed)) {
10490
+ if (!isJsonObject7(parsed)) {
12092
10491
  throw new CliError(
12093
10492
  "invalid_cli_usage",
12094
10493
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -12109,7 +10508,7 @@ function readRawObject5(raw, rawFile) {
12109
10508
  if (rawFile) {
12110
10509
  let contents;
12111
10510
  try {
12112
- contents = readFileSync10(rawFile, "utf8");
10511
+ contents = readFileSync9(rawFile, "utf8");
12113
10512
  } catch (error) {
12114
10513
  const message = error instanceof Error ? error.message : "Unable to read file.";
12115
10514
  throw new CliError(
@@ -12121,7 +10520,7 @@ function readRawObject5(raw, rawFile) {
12121
10520
  }
12122
10521
  return void 0;
12123
10522
  }
12124
- function isEmptyObject7(value) {
10523
+ function isEmptyObject6(value) {
12125
10524
  return Object.keys(value).length === 0;
12126
10525
  }
12127
10526
  function buildFolderCreateInput(options) {
@@ -12152,7 +10551,7 @@ function buildFolderUpdateInput(options) {
12152
10551
  if (props !== void 0) {
12153
10552
  input.additionalProperties = props;
12154
10553
  }
12155
- if (isEmptyObject7(input)) {
10554
+ if (isEmptyObject6(input)) {
12156
10555
  throw new CliError(
12157
10556
  "invalid_cli_usage",
12158
10557
  'Provide folder updates via "--name", "--order", "--props", or "--props-file".'
@@ -12162,9 +10561,9 @@ function buildFolderUpdateInput(options) {
12162
10561
  }
12163
10562
  function toTableRows5(data) {
12164
10563
  if (Array.isArray(data)) {
12165
- return data.map((entry) => isJsonObject8(entry) ? entry : { value: entry });
10564
+ return data.map((entry) => isJsonObject7(entry) ? entry : { value: entry });
12166
10565
  }
12167
- if (isJsonObject8(data)) {
10566
+ if (isJsonObject7(data)) {
12168
10567
  return [data];
12169
10568
  }
12170
10569
  return [{ value: data }];
@@ -12226,91 +10625,85 @@ async function resolveFolderSelector2(api, selector) {
12226
10625
  }
12227
10626
  function registerTeamspaceCommands(program, options = {}) {
12228
10627
  const filePath = options.configPath ?? defaultConfigPath;
12229
- const stdout = getCommandIo12(options.stdout);
10628
+ const stdout = getCommandIo11(options.stdout);
12230
10629
  const teamspace = program.command("teamspace").description("Manage teamspace folders and resources");
12231
10630
  const folders = teamspace.command("folders").description("Manage teamspace folders");
12232
- 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) {
12233
10632
  const { api, json } = createTeamspaceApi(this, filePath);
12234
10633
  const data = await api.listFolders(Boolean(commandOptions.includeResources));
12235
10634
  if (json) {
12236
- emitJson12(stdout, "teamspace folders list", data, filePath);
10635
+ emitJson11(stdout, "teamspace folders list", data, filePath);
12237
10636
  return;
12238
10637
  }
12239
10638
  emitTable5(stdout, data);
12240
10639
  });
12241
- 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) {
12242
10641
  const { api, json } = createTeamspaceApi(this, filePath);
12243
10642
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12244
10643
  const allFolders = await api.listFolders(Boolean(commandOptions.includeResources));
12245
10644
  const data = findFolderEntity(allFolders, resolvedFolder);
12246
10645
  if (json) {
12247
- emitJson12(stdout, "teamspace folders get", data, filePath);
10646
+ emitJson11(stdout, "teamspace folders get", data, filePath);
12248
10647
  return;
12249
10648
  }
12250
10649
  emitTable5(stdout, data);
12251
10650
  });
12252
- 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) {
12253
10652
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12254
- ensureWritable9("teamspace folders create", readOnly, "write");
10653
+ ensureWritable8("teamspace folders create", readOnly, "write");
12255
10654
  const data = await api.createFolder(buildFolderCreateInput(commandOptions));
12256
10655
  if (json) {
12257
- emitJson12(stdout, "teamspace folders create", data, filePath);
10656
+ emitJson11(stdout, "teamspace folders create", data, filePath);
12258
10657
  return;
12259
10658
  }
12260
- writeLine12(stdout, `Created folder "${getFolderIdentifier(data)}".`);
10659
+ writeLine11(stdout, `Created folder "${getFolderIdentifier(data)}".`);
12261
10660
  });
12262
- 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) {
12263
10662
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12264
- ensureWritable9("teamspace folders update", readOnly, "write");
10663
+ ensureWritable8("teamspace folders update", readOnly, "write");
12265
10664
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12266
10665
  const data = await api.updateFolder(resolvedFolder, buildFolderUpdateInput(commandOptions));
12267
10666
  if (json) {
12268
- emitJson12(stdout, "teamspace folders update", data, filePath);
10667
+ emitJson11(stdout, "teamspace folders update", data, filePath);
12269
10668
  return;
12270
10669
  }
12271
- writeLine12(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
10670
+ writeLine11(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
12272
10671
  });
12273
- 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) {
12274
10673
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12275
- ensureWritable9("teamspace folders delete", readOnly, "destructive");
10674
+ ensureWritable8("teamspace folders delete", readOnly, "destructive");
12276
10675
  const resolvedFolder = await resolveFolderSelector2(api, folder);
12277
10676
  const data = await api.deleteFolder(resolvedFolder);
12278
10677
  if (json) {
12279
- emitJson12(stdout, "teamspace folders delete", data, filePath);
10678
+ emitJson11(stdout, "teamspace folders delete", data, filePath);
12280
10679
  return;
12281
10680
  }
12282
- writeLine12(stdout, `Deleted folder "${resolvedFolder.value}".`);
10681
+ writeLine11(stdout, `Deleted folder "${resolvedFolder.value}".`);
12283
10682
  });
12284
10683
  const resources = teamspace.command("resources").description("Manage teamspace resources");
12285
- resources.command("publish").description(
12286
- "Publish a resource to a teamspace folder. Publishing an already-published resource moves it to the new folder."
12287
- ).argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector10).requiredOption(
12288
- "--to <folder>",
12289
- "target folder UUID or exact name (root folder UUID is 00000000-0000-0000-0000-000000000000)",
12290
- parseUuidOrSlugSelector10
12291
- ).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) {
12292
10685
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12293
- ensureWritable9("teamspace resources publish", readOnly, "write");
10686
+ ensureWritable8("teamspace resources publish", readOnly, "write");
12294
10687
  const folder = await resolveFolderSelector2(api, commandOptions.to);
12295
10688
  const data = await api.publishResource({
12296
10689
  resourceId: resource.value,
12297
10690
  targetFolderId: folder.value
12298
10691
  });
12299
10692
  if (json) {
12300
- emitJson12(stdout, "teamspace resources publish", data, filePath);
10693
+ emitJson11(stdout, "teamspace resources publish", data, filePath);
12301
10694
  return;
12302
10695
  }
12303
- writeLine12(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
10696
+ writeLine11(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
12304
10697
  });
12305
- 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) {
12306
10699
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
12307
- ensureWritable9("teamspace resources unpublish", readOnly, "write");
10700
+ ensureWritable8("teamspace resources unpublish", readOnly, "write");
12308
10701
  const data = await api.unpublishResource(resource.value);
12309
10702
  if (json) {
12310
- emitJson12(stdout, "teamspace resources unpublish", data, filePath);
10703
+ emitJson11(stdout, "teamspace resources unpublish", data, filePath);
12311
10704
  return;
12312
10705
  }
12313
- writeLine12(stdout, `Unpublished resource "${resource.value}".`);
10706
+ writeLine11(stdout, `Unpublished resource "${resource.value}".`);
12314
10707
  });
12315
10708
  }
12316
10709
 
@@ -12318,13 +10711,12 @@ function registerTeamspaceCommands(program, options = {}) {
12318
10711
  var require2 = createRequire(import.meta.url);
12319
10712
  var { version } = require2("../package.json");
12320
10713
  function buildProgram(options = {}) {
12321
- const program = new Command11();
10714
+ const program = new Command10();
12322
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");
12323
10716
  registerProfilesCommands(program, options);
12324
10717
  registerAutomationsCommands(program, options);
12325
10718
  registerConfigCommands(program, options);
12326
10719
  registerDisplaysCommands(program, options);
12327
- registerDocumentTemplatesCommands(program, options);
12328
10720
  registerFilesCommands(program, options);
12329
10721
  registerNavigationCommands(program, options);
12330
10722
  registerSchemasCommands(program, options);
@@ -12469,9 +10861,9 @@ function getCompletions(program, request, deps = {}) {
12469
10861
 
12470
10862
  // src/completion/install.ts
12471
10863
  import { execFileSync } from "child_process";
12472
- 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";
12473
10865
  import { homedir as homedir2, platform } from "os";
12474
- 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";
12475
10867
 
12476
10868
  // src/completion/scripts.ts
12477
10869
  var PROGRAM = "zinkee";
@@ -12593,7 +10985,7 @@ function defaultPowerShellProfile(env) {
12593
10985
  function detectShell(env) {
12594
10986
  const fromEnv = env.shellEnv;
12595
10987
  if (fromEnv) {
12596
- const name = basename3(fromEnv).toLowerCase().replace(/\.exe$/, "");
10988
+ const name = basename2(fromEnv).toLowerCase().replace(/\.exe$/, "");
12597
10989
  if (name === "bash") {
12598
10990
  return "bash";
12599
10991
  }
@@ -12691,7 +11083,7 @@ ${BLOCK_END}
12691
11083
  }
12692
11084
  function readFileOrEmpty(path) {
12693
11085
  try {
12694
- return readFileSync11(path, "utf8");
11086
+ return readFileSync10(path, "utf8");
12695
11087
  } catch (error) {
12696
11088
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
12697
11089
  return "";
@@ -12701,7 +11093,7 @@ function readFileOrEmpty(path) {
12701
11093
  }
12702
11094
  function writeFileEnsuringDir(path, content) {
12703
11095
  mkdirSync2(dirname2(path), { recursive: true });
12704
- writeFileSync4(path, content, "utf8");
11096
+ writeFileSync3(path, content, "utf8");
12705
11097
  }
12706
11098
  function installCompletion(shell, env) {
12707
11099
  const target = resolveTarget(shell, env);