@carthooks/arcubase-cli 0.1.21 → 0.1.22

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.
Files changed (56) hide show
  1. package/bundle/arcubase-admin.mjs +1297 -79
  2. package/bundle/arcubase.mjs +1297 -79
  3. package/dist/generated/command_registry.generated.d.ts +285 -0
  4. package/dist/generated/command_registry.generated.d.ts.map +1 -1
  5. package/dist/generated/command_registry.generated.js +395 -0
  6. package/dist/generated/help_examples.generated.d.ts +77 -0
  7. package/dist/generated/help_examples.generated.d.ts.map +1 -1
  8. package/dist/generated/help_examples.generated.js +122 -0
  9. package/dist/generated/type_index.generated.d.ts +40 -1
  10. package/dist/generated/type_index.generated.d.ts.map +1 -1
  11. package/dist/generated/type_index.generated.js +42 -1
  12. package/dist/generated/zod_registry.generated.d.ts +29 -1
  13. package/dist/generated/zod_registry.generated.d.ts.map +1 -1
  14. package/dist/generated/zod_registry.generated.js +37 -0
  15. package/dist/runtime/dev_sdk_gen.d.ts +9 -0
  16. package/dist/runtime/dev_sdk_gen.d.ts.map +1 -0
  17. package/dist/runtime/dev_sdk_gen.js +319 -0
  18. package/dist/runtime/execute.d.ts.map +1 -1
  19. package/dist/runtime/execute.js +280 -1
  20. package/dist/runtime/zod_registry.d.ts.map +1 -1
  21. package/dist/runtime/zod_registry.js +58 -0
  22. package/package.json +1 -1
  23. package/sdk-dist/api/admin/index.ts +1 -0
  24. package/sdk-dist/api/admin/public-link.ts +48 -0
  25. package/sdk-dist/api/shared-link/form.ts +42 -1
  26. package/sdk-dist/api/user/index.ts +0 -1
  27. package/sdk-dist/docs/runtime-reference/dashboard.md +15 -0
  28. package/sdk-dist/docs/runtime-reference/dev-sdk-gen.md +41 -0
  29. package/sdk-dist/docs/runtime-reference/help-examples/admin/dashboard/update-layout.json +16 -0
  30. package/sdk-dist/docs/runtime-reference/help-examples/admin/widget/create.json +33 -0
  31. package/sdk-dist/docs/runtime-reference/help-examples/admin/widget/preview-data.json +42 -0
  32. package/sdk-dist/docs/runtime-reference/widgets.md +40 -0
  33. package/sdk-dist/generated/command_registry.generated.ts +395 -0
  34. package/sdk-dist/generated/help_examples.generated.ts +122 -0
  35. package/sdk-dist/generated/type_index.generated.ts +42 -1
  36. package/sdk-dist/generated/zod_registry.generated.ts +56 -0
  37. package/sdk-dist/types/app.ts +37 -1
  38. package/sdk-dist/types/common.ts +77 -35
  39. package/sdk-dist/types/index.ts +1 -1
  40. package/sdk-dist/types/public-link.ts +10 -0
  41. package/sdk-dist/types/shared-link.ts +16 -1
  42. package/sdk-dist/types/user-action.ts +1 -43
  43. package/src/generated/command_registry.generated.ts +395 -0
  44. package/src/generated/help_examples.generated.ts +122 -0
  45. package/src/generated/type_index.generated.ts +42 -1
  46. package/src/generated/zod_registry.generated.ts +56 -0
  47. package/src/runtime/dev_sdk_gen.ts +360 -0
  48. package/src/runtime/execute.ts +325 -1
  49. package/src/runtime/zod_registry.ts +58 -0
  50. package/src/tests/command_registry.test.ts +20 -2
  51. package/src/tests/dev_sdk_gen.test.ts +226 -0
  52. package/src/tests/docs_readability.test.ts +15 -0
  53. package/src/tests/execute_validation.test.ts +129 -0
  54. package/src/tests/help.test.ts +70 -0
  55. package/sdk-dist/api/user/copilot.ts +0 -20
  56. package/sdk-dist/types/copilot.ts +0 -34
@@ -297,6 +297,148 @@ var adminCommands = [
297
297
  "queryParams": [],
298
298
  "responseType": "boolean"
299
299
  },
300
+ {
301
+ "scope": "admin",
302
+ "module": "dashboard",
303
+ "functionName": "getDashboardList",
304
+ "commandPath": [
305
+ "dashboard",
306
+ "list"
307
+ ],
308
+ "method": "GET",
309
+ "endpoint": "/api/apps/:app_id/dashboard",
310
+ "pathParams": [
311
+ {
312
+ "param": "app_id",
313
+ "flag": "app-id"
314
+ }
315
+ ],
316
+ "controller": "Dashboard.GetList",
317
+ "requestType": null,
318
+ "queryParams": [],
319
+ "responseType": "DashboardGetListRespVO"
320
+ },
321
+ {
322
+ "scope": "admin",
323
+ "module": "dashboard",
324
+ "functionName": "createDashboard",
325
+ "commandPath": [
326
+ "dashboard",
327
+ "create"
328
+ ],
329
+ "method": "POST",
330
+ "endpoint": "/api/apps/:app_id/dashboard",
331
+ "pathParams": [
332
+ {
333
+ "param": "app_id",
334
+ "flag": "app-id"
335
+ }
336
+ ],
337
+ "controller": "Dashboard.Create",
338
+ "requestType": "DashboardCreateReqVO",
339
+ "queryParams": [],
340
+ "responseType": "DashboardCreateRespVO"
341
+ },
342
+ {
343
+ "scope": "admin",
344
+ "module": "dashboard",
345
+ "functionName": "getDashboardOptions",
346
+ "commandPath": [
347
+ "dashboard",
348
+ "get-options"
349
+ ],
350
+ "method": "GET",
351
+ "endpoint": "/api/apps/:app_id/dashboard/:dashboard_id/options",
352
+ "pathParams": [
353
+ {
354
+ "param": "app_id",
355
+ "flag": "app-id"
356
+ },
357
+ {
358
+ "param": "dashboard_id",
359
+ "flag": "dashboard-id"
360
+ }
361
+ ],
362
+ "controller": "Dashboard.FetchOptions",
363
+ "requestType": null,
364
+ "queryParams": [],
365
+ "responseType": "DashboardFetchOptionsRespVO"
366
+ },
367
+ {
368
+ "scope": "admin",
369
+ "module": "dashboard",
370
+ "functionName": "updateDashboardOptions",
371
+ "commandPath": [
372
+ "dashboard",
373
+ "update-options"
374
+ ],
375
+ "method": "PUT",
376
+ "endpoint": "/api/apps/:app_id/dashboard/:dashboard_id/options",
377
+ "pathParams": [
378
+ {
379
+ "param": "app_id",
380
+ "flag": "app-id"
381
+ },
382
+ {
383
+ "param": "dashboard_id",
384
+ "flag": "dashboard-id"
385
+ }
386
+ ],
387
+ "controller": "Dashboard.UpdateOptions",
388
+ "requestType": "DashboardUpdateOptionsReqVO",
389
+ "queryParams": [],
390
+ "responseType": "DashboardUpdateOptionsRespVO"
391
+ },
392
+ {
393
+ "scope": "admin",
394
+ "module": "dashboard",
395
+ "functionName": "updateDashboardLayout",
396
+ "commandPath": [
397
+ "dashboard",
398
+ "update-layout"
399
+ ],
400
+ "method": "PUT",
401
+ "endpoint": "/api/apps/:app_id/dashboard/:dashboard_id/layout",
402
+ "pathParams": [
403
+ {
404
+ "param": "app_id",
405
+ "flag": "app-id"
406
+ },
407
+ {
408
+ "param": "dashboard_id",
409
+ "flag": "dashboard-id"
410
+ }
411
+ ],
412
+ "controller": "Dashboard.UpdateLayout",
413
+ "requestType": "DashboardUpdateLayoutReqVO",
414
+ "queryParams": [],
415
+ "responseType": "DashboardUpdateLayoutRespVO"
416
+ },
417
+ {
418
+ "scope": "admin",
419
+ "module": "dashboard",
420
+ "functionName": "updateDashboardTitle",
421
+ "commandPath": [
422
+ "dashboard",
423
+ "rename"
424
+ ],
425
+ "method": "PUT",
426
+ "endpoint": "/api/apps/:app_id/dashboard/:dashboard_id/label",
427
+ "pathParams": [
428
+ {
429
+ "param": "app_id",
430
+ "flag": "app-id"
431
+ },
432
+ {
433
+ "param": "dashboard_id",
434
+ "flag": "dashboard-id"
435
+ }
436
+ ],
437
+ "controller": "Dashboard.UpdateTitle",
438
+ "requestType": "DashboardUpdateTitleReqVO",
439
+ "queryParams": [],
440
+ "responseType": "DashboardUpdateTitleRespVO"
441
+ },
300
442
  {
301
443
  "scope": "admin",
302
444
  "module": "table",
@@ -732,6 +874,188 @@ var adminCommands = [
732
874
  "requestType": "EntityWorkflowUpdateReqVO",
733
875
  "queryParams": [],
734
876
  "responseType": "EntityWorkflowUpdateRespVO"
877
+ },
878
+ {
879
+ "scope": "admin",
880
+ "module": "widget",
881
+ "functionName": "widgetsList",
882
+ "commandPath": [
883
+ "widget",
884
+ "list"
885
+ ],
886
+ "method": "GET",
887
+ "endpoint": "/api/apps/:app_id/widgets",
888
+ "pathParams": [
889
+ {
890
+ "param": "app_id",
891
+ "flag": "app-id"
892
+ }
893
+ ],
894
+ "controller": "App.WidgetsList",
895
+ "requestType": null,
896
+ "queryParams": [
897
+ {
898
+ "key": "type",
899
+ "flag": "type",
900
+ "type": "string",
901
+ "hasDefault": true
902
+ },
903
+ {
904
+ "key": "dashboard_id",
905
+ "flag": "dashboard-id",
906
+ "type": "number",
907
+ "hasDefault": true
908
+ },
909
+ {
910
+ "key": "ingress_id",
911
+ "flag": "ingress-id",
912
+ "type": "number",
913
+ "hasDefault": true
914
+ }
915
+ ],
916
+ "responseType": "AppWidgetsListRespVO"
917
+ },
918
+ {
919
+ "scope": "admin",
920
+ "module": "widget",
921
+ "functionName": "getWidgets",
922
+ "commandPath": [
923
+ "widget",
924
+ "get"
925
+ ],
926
+ "method": "GET",
927
+ "endpoint": "/api/apps/:app_id/widgets/:widgets_id",
928
+ "pathParams": [
929
+ {
930
+ "param": "app_id",
931
+ "flag": "app-id"
932
+ },
933
+ {
934
+ "param": "widgets_id",
935
+ "flag": "widget-id"
936
+ }
937
+ ],
938
+ "controller": "App.GetWidgets",
939
+ "requestType": null,
940
+ "queryParams": [],
941
+ "responseType": "AppGetWidgetsRespVO"
942
+ },
943
+ {
944
+ "scope": "admin",
945
+ "module": "widget",
946
+ "functionName": "newWidgets",
947
+ "commandPath": [
948
+ "widget",
949
+ "create"
950
+ ],
951
+ "method": "POST",
952
+ "endpoint": "/api/apps/:app_id/widgets",
953
+ "pathParams": [
954
+ {
955
+ "param": "app_id",
956
+ "flag": "app-id"
957
+ }
958
+ ],
959
+ "controller": "App.NewWidgets",
960
+ "requestType": "AppNewWidgetsReqVO",
961
+ "queryParams": [],
962
+ "responseType": "AppNewWidgetsRespVO"
963
+ },
964
+ {
965
+ "scope": "admin",
966
+ "module": "widget",
967
+ "functionName": "updateWidgets",
968
+ "commandPath": [
969
+ "widget",
970
+ "update"
971
+ ],
972
+ "method": "PUT",
973
+ "endpoint": "/api/apps/:app_id/widgets/:widgets_id",
974
+ "pathParams": [
975
+ {
976
+ "param": "app_id",
977
+ "flag": "app-id"
978
+ },
979
+ {
980
+ "param": "widgets_id",
981
+ "flag": "widget-id"
982
+ }
983
+ ],
984
+ "controller": "App.UpdateWidgets",
985
+ "requestType": "AppUpdateWidgetsReqVO",
986
+ "queryParams": [],
987
+ "responseType": "AppUpdateWidgetsRespVO"
988
+ },
989
+ {
990
+ "scope": "admin",
991
+ "module": "widget",
992
+ "functionName": "updateWidgetsIngressOptions",
993
+ "commandPath": [
994
+ "widget",
995
+ "update-ingress-options"
996
+ ],
997
+ "method": "PUT",
998
+ "endpoint": "/api/apps/:app_id/widgets/:widgets_id/ingress-options",
999
+ "pathParams": [
1000
+ {
1001
+ "param": "app_id",
1002
+ "flag": "app-id"
1003
+ },
1004
+ {
1005
+ "param": "widgets_id",
1006
+ "flag": "widget-id"
1007
+ }
1008
+ ],
1009
+ "controller": "App.UpdateWidgetsIngressOptions",
1010
+ "requestType": "AppUpdateWidgetsIngressOptionsReqVO",
1011
+ "queryParams": [],
1012
+ "responseType": "AppUpdateWidgetsIngressOptionsRespVO"
1013
+ },
1014
+ {
1015
+ "scope": "admin",
1016
+ "module": "widget",
1017
+ "functionName": "previewWidgetsData",
1018
+ "commandPath": [
1019
+ "widget",
1020
+ "preview-data"
1021
+ ],
1022
+ "method": "POST",
1023
+ "endpoint": "/api/apps/:app_id/widgets-preview",
1024
+ "pathParams": [
1025
+ {
1026
+ "param": "app_id",
1027
+ "flag": "app-id"
1028
+ }
1029
+ ],
1030
+ "controller": "App.PreviewWidgetsData",
1031
+ "requestType": "AppPreviewWidgetsDataReqVO",
1032
+ "queryParams": [],
1033
+ "responseType": "AppPreviewWidgetsDataRespVO"
1034
+ },
1035
+ {
1036
+ "scope": "admin",
1037
+ "module": "widget",
1038
+ "functionName": "deleteWidgets",
1039
+ "commandPath": [
1040
+ "widget",
1041
+ "delete"
1042
+ ],
1043
+ "method": "DELETE",
1044
+ "endpoint": "/api/apps/:app_id/widgets/:widgets_id",
1045
+ "pathParams": [
1046
+ {
1047
+ "param": "app_id",
1048
+ "flag": "app-id"
1049
+ },
1050
+ {
1051
+ "param": "widgets_id",
1052
+ "flag": "widget-id"
1053
+ }
1054
+ ],
1055
+ "controller": "App.DeleteWidgets",
1056
+ "requestType": null,
1057
+ "queryParams": [],
1058
+ "responseType": "boolean"
735
1059
  }
736
1060
  ];
737
1061
  var userCommands = [
@@ -758,6 +1082,56 @@ var userCommands = [
758
1082
  ],
759
1083
  "responseType": "GlobalActionEntryRespVO"
760
1084
  },
1085
+ {
1086
+ "scope": "user",
1087
+ "module": "dashboard",
1088
+ "functionName": "getDashboard",
1089
+ "commandPath": [
1090
+ "dashboard",
1091
+ "get"
1092
+ ],
1093
+ "method": "GET",
1094
+ "endpoint": "/api/dashboard/:app_id/:dashboard_id",
1095
+ "pathParams": [
1096
+ {
1097
+ "param": "app_id",
1098
+ "flag": "app-id"
1099
+ },
1100
+ {
1101
+ "param": "dashboard_id",
1102
+ "flag": "dashboard-id"
1103
+ }
1104
+ ],
1105
+ "controller": "UserAction.DashboardGet",
1106
+ "requestType": null,
1107
+ "queryParams": [],
1108
+ "responseType": "DashboardGetRespVO"
1109
+ },
1110
+ {
1111
+ "scope": "user",
1112
+ "module": "dashboard",
1113
+ "functionName": "getDashboardWidgets",
1114
+ "commandPath": [
1115
+ "dashboard",
1116
+ "widgets"
1117
+ ],
1118
+ "method": "GET",
1119
+ "endpoint": "/api/dashboard/:app_id/:dashboard_id/widgets",
1120
+ "pathParams": [
1121
+ {
1122
+ "param": "app_id",
1123
+ "flag": "app-id"
1124
+ },
1125
+ {
1126
+ "param": "dashboard_id",
1127
+ "flag": "dashboard-id"
1128
+ }
1129
+ ],
1130
+ "controller": "UserAction.DashboardWidgets",
1131
+ "requestType": null,
1132
+ "queryParams": [],
1133
+ "responseType": "DashboardWidgets[]"
1134
+ },
761
1135
  {
762
1136
  "scope": "user",
763
1137
  "module": "table",
@@ -1179,6 +1553,27 @@ var userCommands = [
1179
1553
  "queryParams": [],
1180
1554
  "responseType": "MobileUploadCheckRespVO"
1181
1555
  },
1556
+ {
1557
+ "scope": "user",
1558
+ "module": "widget",
1559
+ "functionName": "fetchWidgetsData",
1560
+ "commandPath": [
1561
+ "widget",
1562
+ "data"
1563
+ ],
1564
+ "method": "POST",
1565
+ "endpoint": "/api/apps/:app_id/widgets-data",
1566
+ "pathParams": [
1567
+ {
1568
+ "param": "app_id",
1569
+ "flag": "app-id"
1570
+ }
1571
+ ],
1572
+ "controller": "UserAction.FetchWidgetsData",
1573
+ "requestType": "FetchWidgetsDataReqVO",
1574
+ "queryParams": [],
1575
+ "responseType": "FetchWidgetsDataRespVO"
1576
+ },
1182
1577
  {
1183
1578
  "scope": "user",
1184
1579
  "module": "profile",
@@ -16117,9 +16512,26 @@ var AppIngressBulkApplyItemVOSchema = external_exports.lazy(() => external_expor
16117
16512
  var AppIngressBulkApplyReqVOSchema = external_exports.lazy(() => external_exports.object({ "dry_run": external_exports.boolean().optional(), "items": external_exports.array(AppIngressBulkApplyItemVOSchema).optional(), "mode": external_exports.string().optional() }).strict());
16118
16513
  var AppIngressCreateReqVOSchema = external_exports.lazy(() => external_exports.object({ "enabled": external_exports.boolean().optional(), "entity_id": external_exports.number().optional(), "icon_name": external_exports.string().optional(), "name": external_exports.string().optional(), "options": EntityIngressOptionsSchema.optional(), "type": external_exports.string().optional(), "url": external_exports.string().optional() }).strict());
16119
16514
  var AppIngressUpdateReqVOSchema = external_exports.lazy(() => external_exports.object({ "enabled": external_exports.boolean().optional(), "name": external_exports.string().optional(), "options": EntityIngressOptionsSchema.optional(), "update": external_exports.array(external_exports.string()).optional() }).strict());
16515
+ var WidgetsTypeCodeSchema = external_exports.lazy(() => external_exports.union([external_exports.literal(1), external_exports.literal(2)]));
16516
+ var WidgetsTypeSchema = external_exports.lazy(() => external_exports.object({ "dashboard_id": external_exports.number().optional(), "ingress_id": external_exports.number().optional(), "type": WidgetsTypeCodeSchema.optional() }).strict());
16517
+ var AppNewWidgetsReqVOSchema = external_exports.lazy(() => external_exports.object({ "options": WidgetsTypeSchema.optional(), "type": external_exports.string().optional() }).strict());
16518
+ var CubeDimensionSchema = external_exports.lazy(() => external_exports.object({ "FieldID": external_exports.number().optional(), "IsField": external_exports.boolean().optional(), "Label": external_exports.string().optional(), "Name": external_exports.string().optional(), "Options": external_exports.record(external_exports.string(), external_exports.any()).optional(), "OrderBy": external_exports.string().optional(), "PropName": external_exports.string().optional() }).strict());
16519
+ var CubeMeasureAggregateSchema = external_exports.lazy(() => external_exports.union([external_exports.literal("sum"), external_exports.literal("avg"), external_exports.literal("max"), external_exports.literal("min"), external_exports.literal("count"), external_exports.literal("distinct_count")]));
16520
+ var CubeMeasureSchema = external_exports.lazy(() => external_exports.object({ "Aggregate": CubeMeasureAggregateSchema.optional(), "FieldID": external_exports.number().optional(), "Label": external_exports.string().optional(), "Name": external_exports.string().optional(), "Options": external_exports.record(external_exports.string(), external_exports.any()).optional(), "OrderBy": external_exports.string().optional() }).strict());
16521
+ var AppPreviewWidgetsDataReqVOSchema = external_exports.lazy(() => external_exports.object({ "conditions": PermitConditionSetSchema.optional(), "dataSource": external_exports.number().optional(), "dataSourceType": external_exports.string().optional(), "dimensions": external_exports.array(CubeDimensionSchema).optional(), "measures": external_exports.array(CubeMeasureSchema).optional() }).strict());
16120
16522
  var GormDeletedAtSchema = external_exports.lazy(() => external_exports.object({ "Time": external_exports.string().optional(), "Valid": external_exports.boolean().optional() }).strict());
16121
16523
  var AppOptionsSchema = external_exports.lazy(() => external_exports.object({ "use_home_dashboard": external_exports.boolean().optional() }).strict());
16122
16524
  var AppUpdateAppReqVOSchema = external_exports.lazy(() => external_exports.object({ "CreatedAt": external_exports.string().optional(), "DeletedAt": GormDeletedAtSchema.optional(), "ID": external_exports.number().optional(), "Options": AppOptionsSchema.optional(), "UpdatedAt": external_exports.string().optional(), "changed": external_exports.array(external_exports.string()).optional(), "has_workflow": external_exports.boolean().optional(), "icon_color": external_exports.string().optional(), "icon_name": external_exports.string().optional(), "name": external_exports.string().optional(), "tenant_id": external_exports.number().optional(), "use_home_dashboard": external_exports.boolean().optional() }).strict());
16525
+ var WidgetsListViewOptionsSchema = external_exports.lazy(() => external_exports.object({ "cond_follow": external_exports.boolean().optional(), "cond_follow_cols": external_exports.array(external_exports.string()).optional(), "cond_follow_tab": external_exports.boolean().optional(), "link": external_exports.record(external_exports.string(), external_exports.any()).optional() }).strict());
16526
+ var AppUpdateWidgetsIngressOptionsReqVOSchema = external_exports.lazy(() => external_exports.object({ "options": WidgetsListViewOptionsSchema.optional() }).strict());
16527
+ var ChartOptionSchema = external_exports.lazy(() => external_exports.object({ "conditions": PermitConditionSetSchema.optional(), "dimensions": external_exports.array(CubeDimensionSchema).optional(), "entity_id": external_exports.number().optional(), "measures": external_exports.array(CubeMeasureSchema).optional(), "options": external_exports.record(external_exports.string(), external_exports.any()).optional(), "type": external_exports.string().optional() }).strict());
16528
+ var WidgetsOptionSchema = external_exports.lazy(() => external_exports.object({ "charts": ChartOptionSchema.optional(), "ingress": WidgetsListViewOptionsSchema.optional(), "render": external_exports.record(external_exports.string(), external_exports.any()).optional() }).strict());
16529
+ var AppUpdateWidgetsReqVOSchema = external_exports.lazy(() => external_exports.object({ "entity_id": external_exports.number().optional(), "options": WidgetsOptionSchema.optional() }).strict());
16530
+ var DashboardCreateReqVOSchema = external_exports.lazy(() => external_exports.object({ "name": external_exports.string().optional() }).strict());
16531
+ var LayoutPositionSchema = external_exports.lazy(() => external_exports.object({ "h": external_exports.number().optional(), "id": external_exports.number().optional(), "w": external_exports.number().optional(), "x": external_exports.number().optional(), "y": external_exports.number().optional() }).strict());
16532
+ var DashboardUpdateLayoutReqVOSchema = external_exports.lazy(() => external_exports.array(LayoutPositionSchema));
16533
+ var DashboardUpdateOptionsReqVOSchema = external_exports.lazy(() => external_exports.object({ "changed": external_exports.array(external_exports.string()).optional(), "i18n_name": external_exports.record(external_exports.string(), external_exports.string()).optional(), "theme": external_exports.object({ "gutter": external_exports.number().optional(), "has_shadow": external_exports.boolean().optional(), "round_corners": external_exports.number().optional() }).strict().optional(), "users": external_exports.array(PermitUserScopeSchema).optional() }).strict());
16534
+ var DashboardUpdateTitleReqVOSchema = external_exports.lazy(() => external_exports.object({ "name": external_exports.string().optional() }).strict());
16123
16535
  var EntityBulkUpdateActionVOSchema = external_exports.lazy(() => external_exports.object({ "number_add": external_exports.number().optional(), "number_mul": external_exports.number().optional(), "number_sub": external_exports.number().optional(), "text_append": external_exports.string().optional(), "text_prepend": external_exports.string().optional(), "text_replace": external_exports.string().optional(), "text_search": external_exports.string().optional(), "type": external_exports.string().optional(), "value": external_exports.any().optional() }).strict());
16124
16536
  var EntityBulkUpdateFieldVOSchema = external_exports.lazy(() => external_exports.object({ "action": EntityBulkUpdateActionVOSchema.optional(), "id": external_exports.number().optional() }).strict());
16125
16537
  var EntityBulkUpdateReqVOSchema = external_exports.lazy(() => external_exports.object({ "fields": external_exports.array(EntityBulkUpdateFieldVOSchema).optional(), "policy_id": external_exports.string().optional() }).strict());
@@ -16168,6 +16580,8 @@ var WorkflowSLAConfigSchema = external_exports.lazy(() => external_exports.objec
16168
16580
  var WorkflowOptionsSchema = external_exports.lazy(() => external_exports.object({ "allow_urge": external_exports.boolean().optional(), "allow_view_diagram": external_exports.boolean().optional(), "auto_approve_rule": WorkflowAutoApproveRuleSchema.optional(), "retract_rule": WorkflowRetractRuleSchema.optional(), "sla": external_exports.array(WorkflowSLAConfigSchema).optional() }).strict());
16169
16581
  var EntityWorkflowDeployReqVOSchema = external_exports.lazy(() => external_exports.object({ "diagram": WorkflowConfigDiagramSchema.optional(), "id": external_exports.number().optional(), "options": WorkflowOptionsSchema.optional() }).strict());
16170
16582
  var EntityWorkflowUpdateReqVOSchema = external_exports.lazy(() => external_exports.object({ "diagram": WorkflowConfigDiagramSchema.optional(), "id": external_exports.number().optional(), "options": WorkflowOptionsSchema.optional() }).strict());
16583
+ var EntityUtilsQueryOrderSchema = external_exports.lazy(() => external_exports.object({ "column": external_exports.string().optional(), "order": external_exports.string().optional() }).strict());
16584
+ var FetchWidgetsDataReqVOSchema = external_exports.lazy(() => external_exports.object({ "dashboard_id": external_exports.number().optional(), "ingress_hash_id": external_exports.string().optional(), "ingress_id": external_exports.number().optional(), "querys": external_exports.object({ "search": external_exports.record(external_exports.string(), external_exports.any()).optional(), "sorts": external_exports.array(EntityUtilsQueryOrderSchema).optional() }).strict().optional(), "type": WidgetsTypeCodeSchema.optional() }).strict());
16171
16585
  var GetUploadTokenReqVOSchema = external_exports.lazy(() => external_exports.object({ "global": external_exports.boolean().optional() }).strict());
16172
16586
  var InsertReqVOSchema = external_exports.lazy(() => external_exports.object({ "fields": external_exports.record(external_exports.string(), external_exports.any()).optional(), "policy_id": external_exports.string().optional() }).strict());
16173
16587
  var MobileUploadCheckReqVOSchema = external_exports.lazy(() => external_exports.object({ "id": external_exports.number().optional(), "ignored": external_exports.record(external_exports.string(), external_exports.boolean()).optional(), "secret": external_exports.string().optional() }).strict());
@@ -16185,7 +16599,15 @@ var bodySchemas = {
16185
16599
  "AppIngressBulkApplyReqVO": AppIngressBulkApplyReqVOSchema,
16186
16600
  "AppIngressCreateReqVO": AppIngressCreateReqVOSchema,
16187
16601
  "AppIngressUpdateReqVO": AppIngressUpdateReqVOSchema,
16602
+ "AppNewWidgetsReqVO": AppNewWidgetsReqVOSchema,
16603
+ "AppPreviewWidgetsDataReqVO": AppPreviewWidgetsDataReqVOSchema,
16188
16604
  "AppUpdateAppReqVO": AppUpdateAppReqVOSchema,
16605
+ "AppUpdateWidgetsIngressOptionsReqVO": AppUpdateWidgetsIngressOptionsReqVOSchema,
16606
+ "AppUpdateWidgetsReqVO": AppUpdateWidgetsReqVOSchema,
16607
+ "DashboardCreateReqVO": DashboardCreateReqVOSchema,
16608
+ "DashboardUpdateLayoutReqVO": DashboardUpdateLayoutReqVOSchema,
16609
+ "DashboardUpdateOptionsReqVO": DashboardUpdateOptionsReqVOSchema,
16610
+ "DashboardUpdateTitleReqVO": DashboardUpdateTitleReqVOSchema,
16189
16611
  "EntityBulkUpdateReqVO": EntityBulkUpdateReqVOSchema,
16190
16612
  "EntityDoActionReqVO": EntityDoActionReqVOSchema,
16191
16613
  "EntityQueryRelationReqVO": EntityQueryRelationReqVOSchema,
@@ -16198,6 +16620,7 @@ var bodySchemas = {
16198
16620
  "EntityWorkflowApproveUsersReqVO": EntityWorkflowApproveUsersReqVOSchema,
16199
16621
  "EntityWorkflowDeployReqVO": EntityWorkflowDeployReqVOSchema,
16200
16622
  "EntityWorkflowUpdateReqVO": EntityWorkflowUpdateReqVOSchema,
16623
+ "FetchWidgetsDataReqVO": FetchWidgetsDataReqVOSchema,
16201
16624
  "GetUploadTokenReqVO": GetUploadTokenReqVOSchema,
16202
16625
  "InsertReqVO": InsertReqVOSchema,
16203
16626
  "MobileUploadCheckReqVO": MobileUploadCheckReqVOSchema,
@@ -16229,10 +16652,47 @@ var typeIndex = {
16229
16652
  "file": "types/ingress.ts",
16230
16653
  "dependencies": []
16231
16654
  },
16655
+ "AppNewWidgetsReqVO": {
16656
+ "file": "types/widgets.ts",
16657
+ "dependencies": []
16658
+ },
16659
+ "AppPreviewWidgetsDataReqVO": {
16660
+ "file": "types/widgets.ts",
16661
+ "dependencies": []
16662
+ },
16232
16663
  "AppUpdateAppReqVO": {
16233
16664
  "file": "types/app.ts",
16234
16665
  "dependencies": []
16235
16666
  },
16667
+ "AppUpdateWidgetsIngressOptionsReqVO": {
16668
+ "file": "types/widgets.ts",
16669
+ "dependencies": []
16670
+ },
16671
+ "AppUpdateWidgetsReqVO": {
16672
+ "file": "types/widgets.ts",
16673
+ "dependencies": []
16674
+ },
16675
+ "DashboardCreateReqVO": {
16676
+ "file": "types/dashboard.ts",
16677
+ "dependencies": []
16678
+ },
16679
+ "DashboardUpdateLayoutReqVO": {
16680
+ "file": "types/dashboard.ts",
16681
+ "dependencies": [
16682
+ {
16683
+ "symbol": "LayoutPosition",
16684
+ "file": "types/dashboard.ts"
16685
+ }
16686
+ ]
16687
+ },
16688
+ "DashboardUpdateOptionsReqVO": {
16689
+ "file": "types/dashboard.ts",
16690
+ "dependencies": []
16691
+ },
16692
+ "DashboardUpdateTitleReqVO": {
16693
+ "file": "types/dashboard.ts",
16694
+ "dependencies": []
16695
+ },
16236
16696
  "EntityBulkUpdateReqVO": {
16237
16697
  "file": "types/user-action.ts",
16238
16698
  "dependencies": []
@@ -16242,7 +16702,7 @@ var typeIndex = {
16242
16702
  "dependencies": []
16243
16703
  },
16244
16704
  "EntityQueryRelationReqVO": {
16245
- "file": "types/user-action.ts",
16705
+ "file": "types/common.ts",
16246
16706
  "dependencies": []
16247
16707
  },
16248
16708
  "EntityQueryReqVO": {
@@ -16281,6 +16741,10 @@ var typeIndex = {
16281
16741
  "file": "types/workflow.ts",
16282
16742
  "dependencies": []
16283
16743
  },
16744
+ "FetchWidgetsDataReqVO": {
16745
+ "file": "types/user-action.ts",
16746
+ "dependencies": []
16747
+ },
16284
16748
  "GetUploadTokenReqVO": {
16285
16749
  "file": "types/user-action.ts",
16286
16750
  "dependencies": []
@@ -17062,11 +17526,31 @@ var conditionDocHint = {
17062
17526
  title: "Condition",
17063
17527
  file: "docs/runtime-reference/condition.md"
17064
17528
  };
17529
+ var dashboardDocHint = {
17530
+ title: "Dashboard",
17531
+ file: "docs/runtime-reference/dashboard.md"
17532
+ };
17533
+ var widgetsDocHint = {
17534
+ title: "Widgets",
17535
+ file: "docs/runtime-reference/widgets.md"
17536
+ };
17065
17537
  var docHintIndex = {
17066
17538
  AppCreateByTenantsReqVO: [
17067
17539
  { title: "Table lifecycle", file: "docs/runtime-reference/table-lifecycle.md" },
17068
17540
  examplesIndexDocHint
17069
17541
  ],
17542
+ AppNewWidgetsReqVO: [
17543
+ widgetsDocHint
17544
+ ],
17545
+ AppPreviewWidgetsDataReqVO: [
17546
+ widgetsDocHint
17547
+ ],
17548
+ AppUpdateWidgetsIngressOptionsReqVO: [
17549
+ widgetsDocHint
17550
+ ],
17551
+ AppUpdateWidgetsReqVO: [
17552
+ widgetsDocHint
17553
+ ],
17070
17554
  AppCreateEntityReqVO: [
17071
17555
  { title: "Table lifecycle", file: "docs/runtime-reference/table-lifecycle.md" },
17072
17556
  { title: "Table schema cheatsheet", file: "docs/runtime-reference/entity-schema.md" },
@@ -17085,6 +17569,19 @@ var docHintIndex = {
17085
17569
  { title: "Access rule", file: "docs/runtime-reference/access-rule.md" },
17086
17570
  examplesIndexDocHint
17087
17571
  ],
17572
+ DashboardCreateReqVO: [
17573
+ dashboardDocHint
17574
+ ],
17575
+ DashboardUpdateLayoutReqVO: [
17576
+ dashboardDocHint,
17577
+ widgetsDocHint
17578
+ ],
17579
+ DashboardUpdateOptionsReqVO: [
17580
+ dashboardDocHint
17581
+ ],
17582
+ DashboardUpdateTitleReqVO: [
17583
+ dashboardDocHint
17584
+ ],
17088
17585
  EntitySaveReqVO: [
17089
17586
  { title: "Table schema cheatsheet", file: "docs/runtime-reference/entity-schema.md" },
17090
17587
  { title: "Field type index", file: "docs/runtime-reference/entity-schema/README.md" },
@@ -17124,6 +17621,9 @@ var docHintIndex = {
17124
17621
  { title: "Search and bulk actions", file: "docs/runtime-reference/search-and-bulk-actions.md" },
17125
17622
  examplesIndexDocHint
17126
17623
  ],
17624
+ FetchWidgetsDataReqVO: [
17625
+ widgetsDocHint
17626
+ ],
17127
17627
  "EntityInvokeBatchOperatorReqVO & InvokeRequestVO": [
17128
17628
  selectionDocHint,
17129
17629
  conditionDocHint,
@@ -17175,6 +17675,21 @@ var commandDocHintIndex = {
17175
17675
  { title: "Table lifecycle", file: "docs/runtime-reference/table-lifecycle.md" },
17176
17676
  examplesIndexDocHint
17177
17677
  ],
17678
+ "admin.dashboard.getDashboardList": [
17679
+ dashboardDocHint
17680
+ ],
17681
+ "admin.dashboard.getDashboardOptions": [
17682
+ dashboardDocHint
17683
+ ],
17684
+ "admin.widget.widgetsList": [
17685
+ widgetsDocHint
17686
+ ],
17687
+ "admin.widget.getWidgets": [
17688
+ widgetsDocHint
17689
+ ],
17690
+ "admin.widget.deleteWidgets": [
17691
+ widgetsDocHint
17692
+ ],
17178
17693
  "admin.app.createEntity": [
17179
17694
  { title: "Table lifecycle", file: "docs/runtime-reference/table-lifecycle.md" },
17180
17695
  examplesIndexDocHint
@@ -17241,6 +17756,13 @@ var commandDocHintIndex = {
17241
17756
  conditionDocHint,
17242
17757
  { title: "Search and bulk actions", file: "docs/runtime-reference/search-and-bulk-actions.md" },
17243
17758
  examplesIndexDocHint
17759
+ ],
17760
+ "user.dashboard.getDashboard": [
17761
+ dashboardDocHint
17762
+ ],
17763
+ "user.dashboard.getDashboardWidgets": [
17764
+ dashboardDocHint,
17765
+ widgetsDocHint
17244
17766
  ]
17245
17767
  };
17246
17768
  function getCommandDocHints(operation, env = process.env) {
@@ -17793,6 +18315,128 @@ var helpExamplesIndex = {
17793
18315
  }
17794
18316
  ]
17795
18317
  },
18318
+ "admin.dashboard.update-layout": {
18319
+ "command": [
18320
+ "dashboard",
18321
+ "update-layout"
18322
+ ],
18323
+ "examples": [
18324
+ {
18325
+ "title": "place one dashboard widget in the top-left area",
18326
+ "body": [
18327
+ {
18328
+ "id": 2188892001,
18329
+ "x": 0,
18330
+ "y": 0,
18331
+ "w": 12,
18332
+ "h": 6
18333
+ }
18334
+ ],
18335
+ "notes": [
18336
+ "the request body is a top-level array",
18337
+ 'do not wrap the array as {"layout":[...]}'
18338
+ ]
18339
+ }
18340
+ ]
18341
+ },
18342
+ "admin.widget.create": {
18343
+ "command": [
18344
+ "widget",
18345
+ "create"
18346
+ ],
18347
+ "examples": [
18348
+ {
18349
+ "title": "create a dashboard chart widget",
18350
+ "body": {
18351
+ "type": "chart",
18352
+ "options": {
18353
+ "dashboard_id": 2188892001
18354
+ }
18355
+ },
18356
+ "notes": [
18357
+ "do not set options.type by hand",
18358
+ "dashboard_id selects a dashboard widget",
18359
+ "use widget update next to save chart options"
18360
+ ]
18361
+ },
18362
+ {
18363
+ "title": "create an ingress list widget",
18364
+ "body": {
18365
+ "type": "list",
18366
+ "options": {
18367
+ "ingress_id": 2188893001
18368
+ }
18369
+ },
18370
+ "notes": [
18371
+ "ingress_id selects an ingress widget",
18372
+ "do not place ingress widgets with dashboard update-layout"
18373
+ ]
18374
+ }
18375
+ ]
18376
+ },
18377
+ "admin.widget.preview-data": {
18378
+ "command": [
18379
+ "widget",
18380
+ "preview-data"
18381
+ ],
18382
+ "examples": [
18383
+ {
18384
+ "title": "preview dashboard chart data from a table",
18385
+ "body": {
18386
+ "dataSource": 2188891001,
18387
+ "dataSourceType": "entity",
18388
+ "dimensions": [
18389
+ {
18390
+ "IsField": true,
18391
+ "FieldID": 1004,
18392
+ "Name": "Source"
18393
+ }
18394
+ ],
18395
+ "measures": [
18396
+ {
18397
+ "FieldID": 1005,
18398
+ "Aggregate": "sum",
18399
+ "Name": "Total Amount"
18400
+ }
18401
+ ]
18402
+ },
18403
+ "notes": [
18404
+ "preview-data does not accept --widget-id",
18405
+ "do not send widget_id or id in the request body",
18406
+ "copy dimensions and measures from the chart query you want to preview"
18407
+ ]
18408
+ },
18409
+ {
18410
+ "title": "preview count and distinct_count in one grouped chart",
18411
+ "body": {
18412
+ "dataSource": 2188891001,
18413
+ "dataSourceType": "entity",
18414
+ "dimensions": [
18415
+ {
18416
+ "IsField": true,
18417
+ "FieldID": 1004,
18418
+ "Name": "Source"
18419
+ }
18420
+ ],
18421
+ "measures": [
18422
+ {
18423
+ "Aggregate": "count",
18424
+ "Name": "Lead Count"
18425
+ },
18426
+ {
18427
+ "FieldID": 1002,
18428
+ "Aggregate": "distinct_count",
18429
+ "Name": "Distinct Customers"
18430
+ }
18431
+ ]
18432
+ },
18433
+ "notes": [
18434
+ "supported Aggregate values are sum, avg, max, min, count, and distinct_count",
18435
+ "unsupported aggregate names fail local body validation before the request is sent"
18436
+ ]
18437
+ }
18438
+ ]
18439
+ },
17796
18440
  "user.row.bulk-update": {
17797
18441
  "command": [
17798
18442
  "row",
@@ -17935,10 +18579,313 @@ function renderCommandHelpExamples(scope, command) {
17935
18579
  ].join("\n").trimEnd();
17936
18580
  }
17937
18581
 
18582
+ // src/runtime/dev_sdk_gen.ts
18583
+ function isRecord3(value) {
18584
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
18585
+ }
18586
+ function unwrapData(payload) {
18587
+ return isRecord3(payload) && "data" in payload ? payload.data : payload;
18588
+ }
18589
+ function toPascalCase(value) {
18590
+ const words = value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean);
18591
+ if (words.length === 0) return "Entity";
18592
+ return words.map((word) => `${word[0].toUpperCase()}${word.slice(1)}`).join("");
18593
+ }
18594
+ function toCamelCase(value) {
18595
+ const pascal = toPascalCase(value);
18596
+ return `${pascal[0].toLowerCase()}${pascal.slice(1)}`;
18597
+ }
18598
+ function sanitizeEntityKey(entity) {
18599
+ const fallback = entity.sdkName || `entity_${entity.id}`;
18600
+ return toCamelCase(fallback) === "entity" ? `entity${entity.id}` : toCamelCase(fallback);
18601
+ }
18602
+ function normalizeFieldType(type) {
18603
+ switch (type) {
18604
+ case "number":
18605
+ return "number";
18606
+ case "boolean":
18607
+ return "boolean";
18608
+ case "select":
18609
+ case "radio":
18610
+ case "checkbox":
18611
+ case "status":
18612
+ return "number | string";
18613
+ case "file":
18614
+ case "image":
18615
+ case "member":
18616
+ case "members":
18617
+ case "department":
18618
+ case "departments":
18619
+ case "linkto":
18620
+ case "relation":
18621
+ case "relationfield":
18622
+ case "subform":
18623
+ return "unknown";
18624
+ default:
18625
+ return "string";
18626
+ }
18627
+ }
18628
+ function normalizeEntities(payload) {
18629
+ const root = unwrapData(payload);
18630
+ if (!isRecord3(root)) {
18631
+ throw new CLIError("SDK_GEN_INVALID_SCHEMA", "sdk-gen expected an app detail object", 2);
18632
+ }
18633
+ const appId = typeof root.id === "number" ? root.id : typeof root.app_id === "number" ? root.app_id : void 0;
18634
+ if (!appId) {
18635
+ throw new CLIError("SDK_GEN_APP_ID_REQUIRED", "sdk-gen expected app id in app detail response", 2);
18636
+ }
18637
+ const sourceEntities = Array.isArray(root.entities) ? root.entities : Array.isArray(root.tables) ? root.tables : Array.isArray(root.entitys) ? root.entitys : [];
18638
+ const entities = sourceEntities.filter((item) => isRecord3(item)).filter((item) => typeof item.id === "number" && typeof item.name === "string").map((item) => {
18639
+ const fields = Array.isArray(item.fields) ? item.fields.filter((field) => isRecord3(field)).filter((field) => typeof field.id === "number" && typeof field.label === "string" && typeof field.type === "string").map((field) => ({
18640
+ id: field.id,
18641
+ label: field.label,
18642
+ key: typeof field.key === "string" ? field.key.trim() : "",
18643
+ type: field.type,
18644
+ required: field.required === true,
18645
+ options: isRecord3(field.options) ? field.options : void 0
18646
+ })) : [];
18647
+ const entity = {
18648
+ appId,
18649
+ id: item.id,
18650
+ name: item.name,
18651
+ sdkName: typeof item.key === "string" && item.key.trim() ? item.key.trim() : "",
18652
+ fields
18653
+ };
18654
+ entity.sdkName = sanitizeEntityKey(entity);
18655
+ return entity;
18656
+ });
18657
+ if (entities.length === 0) {
18658
+ throw new CLIError("SDK_GEN_NO_ENTITIES", "sdk-gen could not find entities in app detail response", 2);
18659
+ }
18660
+ validateEntities(entities);
18661
+ return entities;
18662
+ }
18663
+ function validateEntities(entities) {
18664
+ const entityKeys = /* @__PURE__ */ new Set();
18665
+ for (const entity of entities) {
18666
+ if (entityKeys.has(entity.sdkName)) {
18667
+ throw new CLIError("SDK_GEN_DUPLICATE_ENTITY_KEY", `duplicate generated entity key: ${entity.sdkName}`, 2);
18668
+ }
18669
+ entityKeys.add(entity.sdkName);
18670
+ const fieldKeys = /* @__PURE__ */ new Set();
18671
+ for (const field of entity.fields) {
18672
+ if (!field.key) {
18673
+ throw new CLIError("SDK_GEN_FIELD_KEY_REQUIRED", `field.key is required for ${entity.name}.${field.label} (${field.id})`, 2);
18674
+ }
18675
+ if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(field.key)) {
18676
+ throw new CLIError("SDK_GEN_INVALID_FIELD_KEY", `field.key must be a TypeScript identifier: ${entity.name}.${field.key}`, 2);
18677
+ }
18678
+ if (fieldKeys.has(field.key)) {
18679
+ throw new CLIError("SDK_GEN_DUPLICATE_FIELD_KEY", `duplicate field.key in ${entity.name}: ${field.key}`, 2);
18680
+ }
18681
+ fieldKeys.add(field.key);
18682
+ }
18683
+ }
18684
+ }
18685
+ function emitRuntime() {
18686
+ return `export type ArcubaseSdkConfig = {
18687
+ baseURL: string
18688
+ accessToken?: string
18689
+ refreshToken?: string
18690
+ }
18691
+
18692
+ export type ArcubaseRow<TFields> = {
18693
+ id: number
18694
+ title?: string
18695
+ fields: TFields
18696
+ raw: Record<string, any>
18697
+ }
18698
+
18699
+ export type ArcubaseRuntime = {
18700
+ config: ArcubaseSdkConfig
18701
+ request<T>(method: string, endpoint: string, body?: unknown): Promise<T>
18702
+ }
18703
+
18704
+ type ArcubaseEnvelope<T> = {
18705
+ data?: T
18706
+ error?: { message?: string; key?: string; type?: string }
18707
+ }
18708
+
18709
+ export function createRuntime(config: ArcubaseSdkConfig): ArcubaseRuntime {
18710
+ let accessToken = config.accessToken ?? ''
18711
+ let refreshToken = config.refreshToken ?? ''
18712
+
18713
+ async function request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {
18714
+ const baseURL = config.baseURL.endsWith('/') ? config.baseURL : \`\${config.baseURL}/\`
18715
+ const response = await fetch(new URL(endpoint.replace(/^\\/+/, ''), baseURL).toString(), {
18716
+ method,
18717
+ headers: {
18718
+ 'Content-Type': 'application/json',
18719
+ ...(accessToken ? { Authorization: \`Bearer \${accessToken}\` } : {}),
18720
+ },
18721
+ body: body === undefined ? undefined : JSON.stringify(body),
18722
+ })
18723
+ const payload = await response.json().catch(() => null) as ArcubaseEnvelope<T> | null
18724
+ if (!response.ok || payload?.error) {
18725
+ throw new Error(payload?.error?.message ?? \`Arcubase request failed: \${response.status}\`)
18726
+ }
18727
+ return payload?.data as T
18728
+ }
18729
+
18730
+ return {
18731
+ config: { ...config, accessToken, refreshToken },
18732
+ request,
18733
+ }
18734
+ }
18735
+ `;
18736
+ }
18737
+ function emitSchema(entities) {
18738
+ const schema = {
18739
+ entities: Object.fromEntries(entities.map((entity) => [
18740
+ entity.sdkName,
18741
+ {
18742
+ entityId: entity.id,
18743
+ name: entity.name,
18744
+ fields: Object.fromEntries(entity.fields.map((field) => [
18745
+ field.key,
18746
+ {
18747
+ fieldId: field.id,
18748
+ label: field.label,
18749
+ type: field.type,
18750
+ required: field.required
18751
+ }
18752
+ ]))
18753
+ }
18754
+ ]))
18755
+ };
18756
+ return `export const arcubaseSchema = ${JSON.stringify(schema, null, 2)} as const
18757
+
18758
+ export type ArcubaseEntityKey = keyof typeof arcubaseSchema.entities
18759
+ `;
18760
+ }
18761
+ function emitEntity(entity) {
18762
+ const typeName = toPascalCase(entity.sdkName);
18763
+ const fieldLines = entity.fields.map((field) => {
18764
+ const optional2 = field.required ? "" : "?";
18765
+ return ` ${field.key}${optional2}: ${normalizeFieldType(field.type)}`;
18766
+ });
18767
+ const fieldMapLines = entity.fields.map((field) => ` ${field.key}: ${field.id},`);
18768
+ return `import type { ArcubaseRuntime, ArcubaseRow } from '../runtime.js'
18769
+
18770
+ export type ${typeName}Fields = {
18771
+ ${fieldLines.join("\n")}
18772
+ }
18773
+
18774
+ export type ${typeName}CreateInput = ${typeName}Fields
18775
+ export type ${typeName}UpdateInput = Partial<${typeName}Fields>
18776
+
18777
+ const entityId = ${entity.id}
18778
+ const fieldIds = {
18779
+ ${fieldMapLines.join("\n")}
18780
+ } as const
18781
+
18782
+ function toArcubaseFields(fields: Partial<${typeName}Fields>): Record<string, any> {
18783
+ const out: Record<string, any> = {}
18784
+ for (const [key, value] of Object.entries(fields)) {
18785
+ if (value === undefined) continue
18786
+ const fieldId = fieldIds[key as keyof typeof fieldIds]
18787
+ if (!fieldId) {
18788
+ throw new Error(\`Unknown ${entity.sdkName} field: \${key}\`)
18789
+ }
18790
+ out[String(fieldId)] = value
18791
+ }
18792
+ return out
18793
+ }
18794
+
18795
+ function fromArcubaseFields(raw: Record<string, any> | undefined): ${typeName}Fields {
18796
+ const out: Record<string, any> = {}
18797
+ const source = raw ?? {}
18798
+ for (const [key, fieldId] of Object.entries(fieldIds)) {
18799
+ if (String(fieldId) in source) {
18800
+ out[key] = source[String(fieldId)]
18801
+ }
18802
+ }
18803
+ return out as ${typeName}Fields
18804
+ }
18805
+
18806
+ function mapRow(raw: Record<string, any>): ArcubaseRow<${typeName}Fields> {
18807
+ return {
18808
+ id: Number(raw.id),
18809
+ title: typeof raw.title === 'string' ? raw.title : undefined,
18810
+ fields: fromArcubaseFields(raw.fields),
18811
+ raw,
18812
+ }
18813
+ }
18814
+
18815
+ export function create${typeName}SDK(runtime: ArcubaseRuntime) {
18816
+ return {
18817
+ async create(fields: ${typeName}CreateInput): Promise<number> {
18818
+ return runtime.request<number>('POST', \`/entity/${entity.appId}/\${entityId}/insert\`, {
18819
+ fields: toArcubaseFields(fields),
18820
+ })
18821
+ },
18822
+
18823
+ async update(rowId: string | number, fields: ${typeName}UpdateInput): Promise<boolean> {
18824
+ const data = toArcubaseFields(fields)
18825
+ return runtime.request<boolean>('PUT', \`/entity/${entity.appId}/\${entityId}/row/\${rowId}\`, {
18826
+ data,
18827
+ changed_fields: Object.keys(data).map((fieldId) => Number(fieldId)),
18828
+ })
18829
+ },
18830
+
18831
+ async get(rowId: string | number): Promise<ArcubaseRow<${typeName}Fields>> {
18832
+ const data = await runtime.request<{ record?: Record<string, any> }>('GET', \`/entity/${entity.appId}/\${entityId}/row/\${rowId}\`)
18833
+ return mapRow(data.record ?? {})
18834
+ },
18835
+
18836
+ async query(params: { limit?: number; offset?: number; search?: Record<string, any> } = {}): Promise<{ items: ArcubaseRow<${typeName}Fields>[]; total?: number }> {
18837
+ const data = await runtime.request<{ items?: Record<string, any>[]; total?: number }>('POST', \`/entity/${entity.appId}/\${entityId}/data-query\`, params)
18838
+ return {
18839
+ items: (data.items ?? []).map(mapRow),
18840
+ total: data.total,
18841
+ }
18842
+ },
18843
+ }
18844
+ }
18845
+ `;
18846
+ }
18847
+ function emitClient(entities) {
18848
+ const imports = entities.map((entity) => {
18849
+ const typeName = toPascalCase(entity.sdkName);
18850
+ return `import { create${typeName}SDK } from './entities/${entity.sdkName}.js'`;
18851
+ });
18852
+ const properties = entities.map((entity) => ` ${entity.sdkName}: create${toPascalCase(entity.sdkName)}SDK(runtime),`);
18853
+ return `import { createRuntime, type ArcubaseSdkConfig } from './runtime.js'
18854
+ ${imports.join("\n")}
18855
+
18856
+ export function createArcubaseSdk(config: ArcubaseSdkConfig) {
18857
+ const runtime = createRuntime(config)
18858
+ return {
18859
+ ${properties.join("\n")}
18860
+ }
18861
+ }
18862
+ `;
18863
+ }
18864
+ function emitIndex(entities) {
18865
+ return `export { createArcubaseSdk } from './client.js'
18866
+ export type { ArcubaseSdkConfig, ArcubaseRow } from './runtime.js'
18867
+ export { arcubaseSchema } from './schema.js'
18868
+ ${entities.map((entity) => `export type { ${toPascalCase(entity.sdkName)}Fields, ${toPascalCase(entity.sdkName)}CreateInput, ${toPascalCase(entity.sdkName)}UpdateInput } from './entities/${entity.sdkName}.js'`).join("\n")}
18869
+ `;
18870
+ }
18871
+ function generateArcubaseProjectSDK(payload) {
18872
+ const entities = normalizeEntities(payload);
18873
+ return {
18874
+ files: [
18875
+ { path: "runtime.ts", contents: emitRuntime() },
18876
+ { path: "schema.ts", contents: emitSchema(entities) },
18877
+ ...entities.map((entity) => ({ path: `entities/${entity.sdkName}.ts`, contents: emitEntity(entity) })),
18878
+ { path: "client.ts", contents: emitClient(entities) },
18879
+ { path: "index.ts", contents: emitIndex(entities) }
18880
+ ]
18881
+ };
18882
+ }
18883
+
17938
18884
  // src/runtime/execute.ts
17939
18885
  function renderRootHelp(scope) {
17940
18886
  const binary = scope === "admin" ? "arcubase-admin" : "arcubase";
17941
- const items = listModules(scope).map((item) => ` - ${item}`);
18887
+ const modules = scope === "admin" ? [...listModules(scope), "dev"].sort() : listModules(scope);
18888
+ const items = modules.map((item) => ` - ${item}`);
17942
18889
  return [
17943
18890
  `${binary} <command> [subcommand] [flags]`,
17944
18891
  "",
@@ -17949,6 +18896,16 @@ function renderRootHelp(scope) {
17949
18896
  ...items
17950
18897
  ].join("\n");
17951
18898
  }
18899
+ function renderDevModuleHelp() {
18900
+ return [
18901
+ "arcubase-admin dev <command> [flags]",
18902
+ "",
18903
+ "developer commands for local project tooling",
18904
+ "",
18905
+ "commands:",
18906
+ " - sdk-gen"
18907
+ ].join("\n");
18908
+ }
17952
18909
  function renderModuleHelp(scope, moduleName, env = process.env) {
17953
18910
  const items = listModuleCommands(scope, moduleName);
17954
18911
  if (items.length === 0) {
@@ -18126,6 +19083,41 @@ function getFixedValue2(value) {
18126
19083
  const fixedValue = value.fixedValue;
18127
19084
  return typeof fixedValue === "string" ? fixedValue : void 0;
18128
19085
  }
19086
+ function isDevSDKGenCommand(scope, moduleName, commandName) {
19087
+ return scope === "admin" && moduleName === "dev" && commandName === "sdk-gen";
19088
+ }
19089
+ function validateDevSDKGenFlags(flags) {
19090
+ const allowed = /* @__PURE__ */ new Set(["help", "app-id", "out"]);
19091
+ for (const flag of Object.keys(flags)) {
19092
+ if (!allowed.has(flag)) {
19093
+ throw new CLIError("UNKNOWN_FLAG", `unknown flag --${flag} for dev sdk-gen`, 2, {
19094
+ operation: "dev sdk-gen",
19095
+ hint: "run dev sdk-gen --help for the supported flags"
19096
+ });
19097
+ }
19098
+ }
19099
+ }
19100
+ function renderDevSDKGenHelp() {
19101
+ return [
19102
+ "arcubase-admin dev sdk-gen",
19103
+ "method: local generator",
19104
+ "endpoint: /apps/:app_id",
19105
+ "body: none",
19106
+ "path flags: --app-id",
19107
+ "flags: --out",
19108
+ "",
19109
+ "generates typed TypeScript source for the current Web project",
19110
+ "",
19111
+ "example:",
19112
+ " - arcubase-admin dev sdk-gen --app-id <app_id> --out src/arcubase",
19113
+ "",
19114
+ "requirements:",
19115
+ " - missing field.key values are initialized through admin auth as field<id>",
19116
+ " - existing field.key values must be stable unique TypeScript identifiers",
19117
+ " - entity property names use entity.key when available, otherwise a stable entity<id> fallback",
19118
+ " - generated code accepts createArcubaseSdk({ baseURL, accessToken, refreshToken })"
19119
+ ].join("\n");
19120
+ }
18129
19121
  function resolveEndpoint(command, flags) {
18130
19122
  let resolved = command.endpoint;
18131
19123
  for (const mapping of command.pathParams) {
@@ -18222,7 +19214,7 @@ function effectiveQueryParams(command) {
18222
19214
  return true;
18223
19215
  });
18224
19216
  }
18225
- function isRecord3(value) {
19217
+ function isRecord4(value) {
18226
19218
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
18227
19219
  }
18228
19220
  function stringifyUpstreamBody(value) {
@@ -18235,18 +19227,18 @@ function stringifyUpstreamBody(value) {
18235
19227
  }
18236
19228
  }
18237
19229
  function extractTraceID(value) {
18238
- if (!isRecord3(value)) return void 0;
19230
+ if (!isRecord4(value)) return void 0;
18239
19231
  if (typeof value.trace_id === "string") return value.trace_id;
18240
19232
  if (typeof value.request_id === "string") return value.request_id;
18241
19233
  return void 0;
18242
19234
  }
18243
19235
  function upstreamErrorMessage(value) {
18244
- if (isRecord3(value) && typeof value.message === "string") return value.message;
19236
+ if (isRecord4(value) && typeof value.message === "string") return value.message;
18245
19237
  if (typeof value === "string") return value;
18246
19238
  return stringifyUpstreamBody(value);
18247
19239
  }
18248
19240
  function throwUpstreamHTTPError(endpoint, method, response, parsedResponse) {
18249
- const upstreamError = isRecord3(parsedResponse) && parsedResponse.error ? parsedResponse.error : void 0;
19241
+ const upstreamError = isRecord4(parsedResponse) && parsedResponse.error ? parsedResponse.error : void 0;
18250
19242
  const body = stringifyUpstreamBody(parsedResponse);
18251
19243
  throw new CLIError(
18252
19244
  "UPSTREAM_REQUEST_FAILED",
@@ -18274,11 +19266,11 @@ async function fetchUpstream(url2, init, endpoint, method, fetchImpl) {
18274
19266
  }
18275
19267
  }
18276
19268
  function extractEntityFields(payload) {
18277
- const candidate = isRecord3(payload) && isRecord3(payload.data) ? payload.data : payload;
18278
- if (!isRecord3(candidate) || !Array.isArray(candidate.fields)) {
19269
+ const candidate = isRecord4(payload) && isRecord4(payload.data) ? payload.data : payload;
19270
+ if (!isRecord4(candidate) || !Array.isArray(candidate.fields)) {
18279
19271
  return [];
18280
19272
  }
18281
- return candidate.fields.filter((item) => isRecord3(item)).filter((item) => typeof item.id === "number" && typeof item.type === "string").map((item) => ({
19273
+ return candidate.fields.filter((item) => isRecord4(item)).filter((item) => typeof item.id === "number" && typeof item.type === "string").map((item) => ({
18282
19274
  id: item.id,
18283
19275
  type: item.type,
18284
19276
  label: typeof item.label === "string" ? item.label : void 0
@@ -18301,7 +19293,7 @@ async function fetchEntityFields(runtimeEnv, appId, entityId, fetchImpl) {
18301
19293
  if (!response.ok) {
18302
19294
  throwUpstreamHTTPError(endpoint, "GET", response, parsedResponse);
18303
19295
  }
18304
- if (isRecord3(parsedResponse) && parsedResponse.error) {
19296
+ if (isRecord4(parsedResponse) && parsedResponse.error) {
18305
19297
  const upstreamError = parsedResponse.error;
18306
19298
  const upstreamMessage = upstreamErrorMessage(upstreamError);
18307
19299
  throw new CLIError("UPSTREAM_BODY_ERROR", upstreamMessage, 1, {
@@ -18318,7 +19310,7 @@ function looksLikeLocalFilePath(value) {
18318
19310
  return value.startsWith("./") || value.startsWith("../") || value.startsWith("/") || value.startsWith("~/") || /\.(pdf|png|jpe?g|gif|webp|bmp|svg|heic|txt|csv|xlsx?|docx?|pptx?|zip)$/i.test(value);
18319
19311
  }
18320
19312
  function isValidUploadEntry(value) {
18321
- if (!isRecord3(value)) {
19313
+ if (!isRecord4(value)) {
18322
19314
  return false;
18323
19315
  }
18324
19316
  const hasUploadId = typeof value.upload_id === "number" || typeof value.upload_id === "string";
@@ -18326,11 +19318,11 @@ function isValidUploadEntry(value) {
18326
19318
  return (hasUploadId || hasAssetsId) && typeof value.file === "string" && typeof value.file_name === "string";
18327
19319
  }
18328
19320
  async function validateFileFieldPayloads(scope, command, runtimeEnv, flags, body, fetchImpl) {
18329
- if (!isRecord3(body)) {
19321
+ if (!isRecord4(body)) {
18330
19322
  return;
18331
19323
  }
18332
19324
  const container = command.functionName === "updateEntityRow" ? body.data : body.fields;
18333
- if (!isRecord3(container)) {
19325
+ if (!isRecord4(container)) {
18334
19326
  return;
18335
19327
  }
18336
19328
  const appId = flagValue(flags, "app-id");
@@ -18362,7 +19354,7 @@ async function validateFileFieldPayloads(scope, command, runtimeEnv, flags, body
18362
19354
  ]
18363
19355
  });
18364
19356
  }
18365
- if (isRecord3(value)) {
19357
+ if (isRecord4(value)) {
18366
19358
  const guidance = `${fieldName} must be an upload value array. Use the upload token flow and pass the returned array directly`;
18367
19359
  throw new CLIError("BODY_VALIDATION_FAILED", guidance, 2, {
18368
19360
  operation: `${scope}.${command.module}.${command.functionName}`,
@@ -18475,6 +19467,12 @@ function isTableSchemaCommand(scope, command) {
18475
19467
  function isAccessRuleCommand(scope, command) {
18476
19468
  return scope === "admin" && command.commandPath[0] === "access-rule";
18477
19469
  }
19470
+ function isWidgetPreviewDataCommand(scope, command) {
19471
+ return scope === "admin" && command.commandPath[0] === "widget" && command.commandPath[1] === "preview-data";
19472
+ }
19473
+ function isWidgetUpdateCommand(scope, command) {
19474
+ return scope === "admin" && command.commandPath[0] === "widget" && command.commandPath[1] === "update";
19475
+ }
18478
19476
  function isAccessRuleUpdateCommand(scope, command) {
18479
19477
  return scope === "admin" && command.commandPath[0] === "access-rule" && command.commandPath[1] === "update";
18480
19478
  }
@@ -18771,6 +19769,45 @@ function buildBodyGuidance(requestType) {
18771
19769
  ]
18772
19770
  };
18773
19771
  }
19772
+ if (requestType === "AppPreviewWidgetsDataReqVO") {
19773
+ return {
19774
+ shapeHint: {
19775
+ dataSource: 2188891001,
19776
+ dataSourceType: "entity",
19777
+ dimensions: [{ IsField: true, FieldID: 1004, Name: "Source" }],
19778
+ measures: [{ FieldID: 1005, Aggregate: "sum", Name: "Total Amount" }]
19779
+ },
19780
+ commonMistakes: [
19781
+ "widget preview-data body is the chart query itself",
19782
+ "do not send a saved widget object with id, entity_id, or options",
19783
+ "field dimensions with FieldID must set IsField:true",
19784
+ "unsupported aggregates are invalid; use sum, avg, max, min, count, or distinct_count"
19785
+ ],
19786
+ suggestions: [
19787
+ `retry with: arcubase-admin widget preview-data --app-id <app_id> --body-json '{"dataSource":<table_id>,"dataSourceType":"entity","dimensions":[{"IsField":true,"FieldID":<field_id>,"Name":"Source"}],"measures":[{"FieldID":<number_field_id>,"Aggregate":"sum","Name":"Total Amount"}]}'`
19788
+ ]
19789
+ };
19790
+ }
19791
+ if (requestType === "AppUpdateWidgetsReqVO") {
19792
+ return {
19793
+ shapeHint: {
19794
+ entity_id: 2188891001,
19795
+ options: {
19796
+ charts: {
19797
+ entity_id: 2188891001,
19798
+ dimensions: [{ IsField: true, FieldID: 1004, Name: "Source" }],
19799
+ measures: [{ FieldID: 1005, Aggregate: "sum", Name: "Total Amount" }],
19800
+ type: "bar"
19801
+ }
19802
+ }
19803
+ },
19804
+ commonMistakes: [
19805
+ "dashboard chart config belongs in body.options.charts",
19806
+ "field dimensions with FieldID must set IsField:true",
19807
+ "verify persistence with widget get or widget list after update"
19808
+ ]
19809
+ };
19810
+ }
18774
19811
  return {};
18775
19812
  }
18776
19813
  function buildBodyValidationDetails(scope, command, requestType, issues, env = process.env) {
@@ -18790,7 +19827,7 @@ function throwBodyValidationFailure(message, requestType, path3, scope, command,
18790
19827
  throw new CLIError("BODY_VALIDATION_FAILED", message, 2, buildBodyValidationDetails(scope, command, requestType, [{ path: path3, message }], env));
18791
19828
  }
18792
19829
  function requireTableCreateSchemaBody(scope, command, body, env) {
18793
- if (!isRecord3(body)) {
19830
+ if (!isRecord4(body)) {
18794
19831
  throwBodyValidationFailure(
18795
19832
  "table create requires a JSON object with name, fields, field_id_seq, layout, options, and workflow_enabled",
18796
19833
  "AppCreateEntityReqVO",
@@ -18838,7 +19875,7 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
18838
19875
  }
18839
19876
  const allowedTypes = /* @__PURE__ */ new Set(["user", "department", "actor"]);
18840
19877
  for (const [index, item] of userScope.entries()) {
18841
- if (!isRecord3(item)) {
19878
+ if (!isRecord4(item)) {
18842
19879
  throwBodyValidationFailure(
18843
19880
  "access-rule user_scope item must be an object",
18844
19881
  requestType,
@@ -18871,14 +19908,14 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
18871
19908
  }
18872
19909
  }
18873
19910
  function normalizeNumericAccessRuleUserScopeIDs(scope, command, body) {
18874
- if (!isAccessRuleCommand(scope, command) || !isRecord3(body)) {
19911
+ if (!isAccessRuleCommand(scope, command) || !isRecord4(body)) {
18875
19912
  return body;
18876
19913
  }
18877
19914
  const normalizeUserScope = (userScope) => {
18878
19915
  if (!Array.isArray(userScope)) return { value: userScope, changed: false };
18879
19916
  let changed = false;
18880
19917
  const value = userScope.map((item) => {
18881
- if (!isRecord3(item) || typeof item.id !== "string" || !/^\d+$/.test(item.id)) {
19918
+ if (!isRecord4(item) || typeof item.id !== "string" || !/^\d+$/.test(item.id)) {
18882
19919
  return item;
18883
19920
  }
18884
19921
  const id = Number(item.id);
@@ -18899,7 +19936,7 @@ function normalizeNumericAccessRuleUserScopeIDs(scope, command, body) {
18899
19936
  if (isAccessRuleBulkApplyCommand(scope, command) && Array.isArray(body.items)) {
18900
19937
  let changed = false;
18901
19938
  const items = body.items.map((item) => {
18902
- if (!isRecord3(item)) return item;
19939
+ if (!isRecord4(item)) return item;
18903
19940
  let nextItem = item;
18904
19941
  for (const key of ["table_id", "rule_id"]) {
18905
19942
  const normalized = normalizeNumericID(nextItem[key]);
@@ -18908,7 +19945,7 @@ function normalizeNumericAccessRuleUserScopeIDs(scope, command, body) {
18908
19945
  changed = true;
18909
19946
  }
18910
19947
  }
18911
- if (isRecord3(nextItem.options)) {
19948
+ if (isRecord4(nextItem.options)) {
18912
19949
  const normalizedUserScope2 = normalizeUserScope(nextItem.options.user_scope);
18913
19950
  if (normalizedUserScope2.changed) {
18914
19951
  nextItem = {
@@ -18925,7 +19962,7 @@ function normalizeNumericAccessRuleUserScopeIDs(scope, command, body) {
18925
19962
  });
18926
19963
  return changed ? { ...body, items } : body;
18927
19964
  }
18928
- if (!isRecord3(body.options)) {
19965
+ if (!isRecord4(body.options)) {
18929
19966
  return body;
18930
19967
  }
18931
19968
  const normalizedUserScope = normalizeUserScope(body.options.user_scope);
@@ -18953,7 +19990,7 @@ function validateAccessRulePolicyShape(scope, command, requestType, policy, env,
18953
19990
  const fields = policy && Array.isArray(policy.fields) ? policy.fields : [];
18954
19991
  const allowedSystemFieldKeys = /* @__PURE__ */ new Set(["created", "updated", "creator"]);
18955
19992
  for (const [index, field] of fields.entries()) {
18956
- if (!isRecord3(field)) continue;
19993
+ if (!isRecord4(field)) continue;
18957
19994
  if (typeof field.key === "number" || typeof field.key === "string" && /^\d+$/.test(field.key)) {
18958
19995
  throwBodyValidationFailure(
18959
19996
  'access-rule policy.fields[].key must be a string prefixed with colon, for example ":1002"; do not use raw numbers',
@@ -18990,8 +20027,26 @@ function requireUpdateContains(scope, command, body, field, env) {
18990
20027
  );
18991
20028
  }
18992
20029
  }
20030
+ function validateChartFieldDimensions(scope, command, requestType, dimensions, pathPrefix, env) {
20031
+ if (!Array.isArray(dimensions)) return;
20032
+ for (const [index, dimension] of dimensions.entries()) {
20033
+ if (!isRecord4(dimension) || typeof dimension.FieldID !== "number") {
20034
+ continue;
20035
+ }
20036
+ if (dimension.IsField !== true) {
20037
+ throwBodyValidationFailure(
20038
+ "widget chart field dimensions require IsField:true when FieldID is present; otherwise grouped statistics collapse into total rows",
20039
+ requestType,
20040
+ `${pathPrefix}.${index}.IsField`,
20041
+ scope,
20042
+ command,
20043
+ env
20044
+ );
20045
+ }
20046
+ }
20047
+ }
18993
20048
  function validateActionSpecificRawBody(scope, command, body, env) {
18994
- if (!isRecord3(body) || !command.requestType) {
20049
+ if (!isRecord4(body) || !command.requestType) {
18995
20050
  return;
18996
20051
  }
18997
20052
  if (isAssignUsersCommand(scope, command)) {
@@ -19008,7 +20063,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19008
20063
  }
19009
20064
  if (isTableSchemaCommand(scope, command)) {
19010
20065
  const fields = Array.isArray(body.fields) ? body.fields : [];
19011
- const hasPermissionPatch = fields.some((field) => isRecord3(field) && ("permission" in field || "permissions" in field || "field_visibility" in field));
20066
+ const hasPermissionPatch = fields.some((field) => isRecord4(field) && ("permission" in field || "permissions" in field || "field_visibility" in field));
19012
20067
  if (hasPermissionPatch) {
19013
20068
  throwBodyValidationFailure(
19014
20069
  "table schema cannot configure per-user permissions. Use access-rule create/update with options.policy.fields for hidden fields",
@@ -19043,7 +20098,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19043
20098
  );
19044
20099
  }
19045
20100
  for (const [index, item] of body.items.entries()) {
19046
- if (!isRecord3(item)) {
20101
+ if (!isRecord4(item)) {
19047
20102
  throwBodyValidationFailure(
19048
20103
  "access-rule bulk-apply body.items[] must be an object",
19049
20104
  command.requestType,
@@ -19053,7 +20108,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19053
20108
  env
19054
20109
  );
19055
20110
  }
19056
- const options2 = isRecord3(item.options) ? item.options : void 0;
20111
+ const options2 = isRecord4(item.options) ? item.options : void 0;
19057
20112
  if (!options2) {
19058
20113
  throwBodyValidationFailure(
19059
20114
  "access-rule bulk-apply body.items[].options is required and must include the full canonical options object",
@@ -19065,7 +20120,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19065
20120
  );
19066
20121
  }
19067
20122
  validateAccessRuleUserScope(scope, command, command.requestType, options2.user_scope, env, `body.items.${index}.options.user_scope`);
19068
- validateAccessRulePolicyShape(scope, command, command.requestType, isRecord3(options2.policy) ? options2.policy : void 0, env, `body.items.${index}.options.policy`);
20123
+ validateAccessRulePolicyShape(scope, command, command.requestType, isRecord4(options2.policy) ? options2.policy : void 0, env, `body.items.${index}.options.policy`);
19069
20124
  }
19070
20125
  return;
19071
20126
  }
@@ -19090,7 +20145,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19090
20145
  env
19091
20146
  );
19092
20147
  }
19093
- const options = isRecord3(body.options) ? body.options : void 0;
20148
+ const options = isRecord4(body.options) ? body.options : void 0;
19094
20149
  if (options && ("permissions" in options || "field_visibility" in options)) {
19095
20150
  throwBodyValidationFailure(
19096
20151
  "access-rule options only supports user_scope, policy, list_options, i18n_name; use options.policy.actions and options.policy.fields",
@@ -19101,7 +20156,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19101
20156
  env
19102
20157
  );
19103
20158
  }
19104
- const policy = options && isRecord3(options.policy) ? options.policy : void 0;
20159
+ const policy = options && isRecord4(options.policy) ? options.policy : void 0;
19105
20160
  if (isAccessRuleUpdateCommand(scope, command) && update.includes("options") && options?.user_scope !== void 0 && !policy) {
19106
20161
  throwBodyValidationFailure(
19107
20162
  'access-rule update with update:["options"] cannot change only options.user_scope because it overwrites policy. Use access-rule assign-users for user assignment, or include the full options.policy and options.list_options.',
@@ -19115,9 +20170,17 @@ function validateActionSpecificRawBody(scope, command, body, env) {
19115
20170
  validateAccessRuleUserScope(scope, command, command.requestType, options?.user_scope, env);
19116
20171
  validateAccessRulePolicyShape(scope, command, command.requestType, policy, env, "body.options.policy");
19117
20172
  }
20173
+ if (isWidgetPreviewDataCommand(scope, command)) {
20174
+ validateChartFieldDimensions(scope, command, command.requestType, body.dimensions, "body.dimensions", env);
20175
+ }
20176
+ if (isWidgetUpdateCommand(scope, command)) {
20177
+ const options = isRecord4(body.options) ? body.options : void 0;
20178
+ const charts = options && isRecord4(options.charts) ? options.charts : void 0;
20179
+ validateChartFieldDimensions(scope, command, command.requestType, charts?.dimensions, "body.options.charts.dimensions", env);
20180
+ }
19118
20181
  }
19119
20182
  function validateActionSpecificBody(scope, command, flags, body, env) {
19120
- if (!isRecord3(body) || !command.requestType) {
20183
+ if (!isRecord4(body) || !command.requestType) {
19121
20184
  return;
19122
20185
  }
19123
20186
  if (scope === "admin" && command.commandPath[0] === "access-rule" && command.commandPath[1] === "update") {
@@ -19127,7 +20190,7 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
19127
20190
  }
19128
20191
  if (isAssignUsersCommand(scope, command)) {
19129
20192
  const update = stringArray(body.update);
19130
- const options = isRecord3(body.options) ? body.options : void 0;
20193
+ const options = isRecord4(body.options) ? body.options : void 0;
19131
20194
  const userScope = options && Array.isArray(options.user_scope) ? options.user_scope : void 0;
19132
20195
  if ("users" in body || "allowedUsers" in body) {
19133
20196
  throwBodyValidationFailure(
@@ -19162,7 +20225,7 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
19162
20225
  validateAccessRuleUserScope(scope, command, command.requestType, userScope, env);
19163
20226
  const assignedUserScope = userScope;
19164
20227
  for (const [index, item] of assignedUserScope.entries()) {
19165
- if (!isRecord3(item)) {
20228
+ if (!isRecord4(item)) {
19166
20229
  throwBodyValidationFailure(
19167
20230
  "access-rule assign-users requires each body.options.user_scope item to be an object",
19168
20231
  command.requestType,
@@ -19187,11 +20250,11 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
19187
20250
  if (command.commandPath[0] === "row" && command.commandPath[1] === "selection-action") {
19188
20251
  const action = flagValue(flags, "action");
19189
20252
  const selection = body.selection;
19190
- if (!isRecord3(selection) || typeof selection.type !== "string") {
20253
+ if (!isRecord4(selection) || typeof selection.type !== "string") {
19191
20254
  return;
19192
20255
  }
19193
20256
  const type = selection.type;
19194
- const condition = isRecord3(selection.condition) ? selection.condition : void 0;
20257
+ const condition = isRecord4(selection.condition) ? selection.condition : void 0;
19195
20258
  const conditionKeys = condition ? Object.keys(condition).filter((key) => key !== "selectAll") : [];
19196
20259
  if (action === "query") {
19197
20260
  if (type === "condition") {
@@ -19228,10 +20291,10 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
19228
20291
  }
19229
20292
  }
19230
20293
  }
19231
- function unwrapData(value) {
20294
+ function unwrapData2(value) {
19232
20295
  let current = value;
19233
20296
  for (let i = 0; i < 3; i += 1) {
19234
- if (isRecord3(current) && isRecord3(current.data)) {
20297
+ if (isRecord4(current) && isRecord4(current.data)) {
19235
20298
  current = current.data;
19236
20299
  continue;
19237
20300
  }
@@ -19240,23 +20303,23 @@ function unwrapData(value) {
19240
20303
  return current;
19241
20304
  }
19242
20305
  function numericFieldKeys(fields) {
19243
- if (!isRecord3(fields)) return [];
20306
+ if (!isRecord4(fields)) return [];
19244
20307
  return Object.keys(fields).filter((key) => /^\d+$/.test(key)).sort((left, right) => Number(left) - Number(right));
19245
20308
  }
19246
20309
  function permitFieldId(permit) {
19247
- if (!isRecord3(permit) || typeof permit.key !== "string") return void 0;
20310
+ if (!isRecord4(permit) || typeof permit.key !== "string") return void 0;
19248
20311
  const match = /^:(\d+)$/.exec(permit.key);
19249
20312
  return match?.[1];
19250
20313
  }
19251
20314
  function rowFieldPermits(value) {
19252
- const data = unwrapData(value);
19253
- const fieldPermits = isRecord3(data) && isRecord3(data.fieldPermits) ? data.fieldPermits : void 0;
19254
- return fieldPermits && Array.isArray(fieldPermits.fields) ? fieldPermits.fields.filter((item) => isRecord3(item)) : [];
20315
+ const data = unwrapData2(value);
20316
+ const fieldPermits = isRecord4(data) && isRecord4(data.fieldPermits) ? data.fieldPermits : void 0;
20317
+ return fieldPermits && Array.isArray(fieldPermits.fields) ? fieldPermits.fields.filter((item) => isRecord4(item)) : [];
19255
20318
  }
19256
20319
  function buildRowValueEvidence(command, responseBody) {
19257
20320
  if (command.scope !== "user" || command.commandPath[0] !== "row") return void 0;
19258
20321
  const action = command.commandPath[1];
19259
- const data = unwrapData(responseBody);
20322
+ const data = unwrapData2(responseBody);
19260
20323
  const rules = [
19261
20324
  "current row values come only from row query fields or row get record.fields",
19262
20325
  "table schema fields[].value and default_value_mode are schema defaults, not returned row values",
@@ -19264,7 +20327,7 @@ function buildRowValueEvidence(command, responseBody) {
19264
20327
  "read visibility status is fieldPermits read:false; FIELD_PERMISSION_REQUIRED is only a write preflight error"
19265
20328
  ];
19266
20329
  if (action === "get") {
19267
- const record2 = isRecord3(data) && isRecord3(data.record) ? data.record : void 0;
20330
+ const record2 = isRecord4(data) && isRecord4(data.record) ? data.record : void 0;
19268
20331
  const returnedFieldIds = numericFieldKeys(record2?.fields);
19269
20332
  const permits = rowFieldPermits(responseBody);
19270
20333
  const permitFieldIds = permits.map(permitFieldId).filter((id) => Boolean(id));
@@ -19280,10 +20343,10 @@ function buildRowValueEvidence(command, responseBody) {
19280
20343
  };
19281
20344
  }
19282
20345
  if (action === "query") {
19283
- const items = isRecord3(data) && Array.isArray(data.items) ? data.items : [];
20346
+ const items = isRecord4(data) && Array.isArray(data.items) ? data.items : [];
19284
20347
  return {
19285
20348
  source: "row query items[].fields",
19286
- rows: items.filter((item) => isRecord3(item)).map((item) => ({
20349
+ rows: items.filter((item) => isRecord4(item)).map((item) => ({
19287
20350
  rowId: item.id,
19288
20351
  returnedFieldIds: numericFieldKeys(item.fields)
19289
20352
  })),
@@ -19317,14 +20380,14 @@ function rowCommandNeedsPolicy(command) {
19317
20380
  return command.scope === "user" && command.commandPath[0] === "row";
19318
20381
  }
19319
20382
  function extractIngressItems(appDetail) {
19320
- const appData = unwrapData(appDetail);
19321
- const ingress = isRecord3(appData) ? appData.ingress : void 0;
19322
- const groups = isRecord3(ingress) && Array.isArray(ingress.groups) ? ingress.groups : [];
20383
+ const appData = unwrapData2(appDetail);
20384
+ const ingress = isRecord4(appData) ? appData.ingress : void 0;
20385
+ const groups = isRecord4(ingress) && Array.isArray(ingress.groups) ? ingress.groups : [];
19323
20386
  const items = [];
19324
20387
  for (const group of groups) {
19325
- const groupItems = isRecord3(group) && Array.isArray(group.items) ? group.items : [];
20388
+ const groupItems = isRecord4(group) && Array.isArray(group.items) ? group.items : [];
19326
20389
  for (const item of groupItems) {
19327
- if (!isRecord3(item)) continue;
20390
+ if (!isRecord4(item)) continue;
19328
20391
  const id = typeof item.id === "string" ? item.id : typeof item.ID === "string" ? item.ID : "";
19329
20392
  if (id) {
19330
20393
  items.push({ id });
@@ -19334,29 +20397,29 @@ function extractIngressItems(appDetail) {
19334
20397
  return items;
19335
20398
  }
19336
20399
  function ingressMatchesTableAndAction(ingressDetail, tableId, action) {
19337
- const ingressData = unwrapData(ingressDetail);
19338
- if (!isRecord3(ingressData)) return void 0;
20400
+ const ingressData = unwrapData2(ingressDetail);
20401
+ if (!isRecord4(ingressData)) return void 0;
19339
20402
  const id = typeof ingressData.id === "number" || typeof ingressData.id === "string" ? ingressData.id : typeof ingressData.ID === "number" || typeof ingressData.ID === "string" ? ingressData.ID : void 0;
19340
20403
  if (String(id ?? "") !== tableId) return void 0;
19341
20404
  const policyID = typeof ingressData.hash_id === "string" ? ingressData.hash_id : typeof ingressData.hashId === "string" ? ingressData.hashId : void 0;
19342
- const policy = isRecord3(ingressData.policy) ? ingressData.policy : void 0;
20405
+ const policy = isRecord4(ingressData.policy) ? ingressData.policy : void 0;
19343
20406
  if (!action) return { policyID: policyID || "", policy };
19344
20407
  const actions = policy && Array.isArray(policy.actions) ? policy.actions.filter((item) => typeof item === "string") : [];
19345
20408
  if (!actions.includes(action)) return void 0;
19346
20409
  return { policyID: policyID || "", policy };
19347
20410
  }
19348
20411
  function writtenRowFieldIds(command, body) {
19349
- if (!isRecord3(body)) return [];
20412
+ if (!isRecord4(body)) return [];
19350
20413
  const source = command.commandPath[1] === "create" ? body.fields : command.commandPath[1] === "update" ? body.data : void 0;
19351
- if (!isRecord3(source)) return [];
20414
+ if (!isRecord4(source)) return [];
19352
20415
  return Object.keys(source).filter((key) => /^\d+$/.test(key)).map((key) => Number(key));
19353
20416
  }
19354
20417
  function fieldWriteAllowedByPolicy(policy, fieldId) {
19355
20418
  if (!policy) return true;
19356
20419
  const fields = Array.isArray(policy.fields) ? policy.fields : [];
19357
- const explicit = fields.find((item) => isRecord3(item) && item.key === `:${fieldId}`);
19358
- if (isRecord3(explicit) && explicit.write === false) return false;
19359
- if (isRecord3(explicit) && explicit.write === true) return true;
20420
+ const explicit = fields.find((item) => isRecord4(item) && item.key === `:${fieldId}`);
20421
+ if (isRecord4(explicit) && explicit.write === false) return false;
20422
+ if (isRecord4(explicit) && explicit.write === true) return true;
19360
20423
  if (policy.all_fields_write === false) return false;
19361
20424
  return true;
19362
20425
  }
@@ -19427,7 +20490,7 @@ async function injectResolvedPolicyID(command, runtimeEnv, flags, query, body, f
19427
20490
  if (typeof query.policy_id === "string" && query.policy_id) {
19428
20491
  return { query, body };
19429
20492
  }
19430
- if (isRecord3(body) && typeof body.policy_id === "string" && body.policy_id) {
20493
+ if (isRecord4(body) && typeof body.policy_id === "string" && body.policy_id) {
19431
20494
  return { query, body };
19432
20495
  }
19433
20496
  const resolvedPolicy = await resolvePolicyIDForRowCommand(command, runtimeEnv, flags, fetchImpl);
@@ -19436,7 +20499,7 @@ async function injectResolvedPolicyID(command, runtimeEnv, flags, query, body, f
19436
20499
  if (command.commandPath[1] === "get") {
19437
20500
  return { query: { ...query, policy_id: policyID }, body };
19438
20501
  }
19439
- if (isRecord3(body)) {
20502
+ if (isRecord4(body)) {
19440
20503
  return { query, body: { ...body, policy_id: policyID } };
19441
20504
  }
19442
20505
  return { query, body };
@@ -19445,7 +20508,7 @@ function assertNoUserPolicyIDInput(command, runtimeEnv, query, body) {
19445
20508
  if (!rowCommandNeedsPolicy(command)) {
19446
20509
  return;
19447
20510
  }
19448
- if ("policy_id" in query || isRecord3(body) && "policy_id" in body) {
20511
+ if ("policy_id" in query || isRecord4(body) && "policy_id" in body) {
19449
20512
  throw new CLIError("INTERNAL_POLICY_ID_NOT_ALLOWED", "policy_id is an internal Arcubase ingress parameter; use app/table/row ids only", 2, {
19450
20513
  operation: `user.${command.module}.${command.functionName}`,
19451
20514
  issues: [{ path: "policy_id", message: "do not provide policy_id in flags, query file, or body JSON" }],
@@ -19482,6 +20545,151 @@ async function requestJSON(runtimeEnv, method, endpoint, body, fetchImpl) {
19482
20545
  }
19483
20546
  return { status: response.status, data: parsedResponse };
19484
20547
  }
20548
+ function unwrapResponseData(payload) {
20549
+ return isRecord4(payload) && "data" in payload ? payload.data : payload;
20550
+ }
20551
+ function extractSDKGenAppPayload(payload) {
20552
+ const appPayload = unwrapResponseData(payload);
20553
+ if (!isRecord4(appPayload)) {
20554
+ throw new CLIError("SDK_GEN_INVALID_SCHEMA", "sdk-gen expected app detail response data", 2);
20555
+ }
20556
+ return appPayload;
20557
+ }
20558
+ function extractSDKGenEntityRefs(appPayload) {
20559
+ const sourceEntities = Array.isArray(appPayload.entities) ? appPayload.entities : Array.isArray(appPayload.tables) ? appPayload.tables : Array.isArray(appPayload.entitys) ? appPayload.entitys : [];
20560
+ const refs = sourceEntities.filter((item) => isRecord4(item)).map((item) => item.id).filter((id) => typeof id === "string" || typeof id === "number").map((id) => ({ id: String(id) }));
20561
+ return refs;
20562
+ }
20563
+ function resolveSDKGenAppId(flagAppId, appPayload) {
20564
+ const fromPayload = typeof appPayload.id === "number" ? appPayload.id : typeof appPayload.app_id === "number" ? appPayload.app_id : void 0;
20565
+ const fromFlag = Number(flagAppId);
20566
+ if (Number.isFinite(fromFlag)) return fromFlag;
20567
+ if (fromPayload) return fromPayload;
20568
+ throw new CLIError("SDK_GEN_APP_ID_REQUIRED", "sdk-gen expected numeric app id", 2);
20569
+ }
20570
+ function walkSDKGenFields(fields, visit) {
20571
+ if (!Array.isArray(fields)) {
20572
+ return;
20573
+ }
20574
+ for (const field of fields) {
20575
+ if (!isRecord4(field)) {
20576
+ continue;
20577
+ }
20578
+ visit(field);
20579
+ walkSDKGenFields(field.children, visit);
20580
+ }
20581
+ }
20582
+ function collectExistingSDKGenFieldKeys(entity) {
20583
+ const keys = /* @__PURE__ */ new Set();
20584
+ walkSDKGenFields(entity.fields, (field) => {
20585
+ if (typeof field.key === "string" && field.key.trim() !== "") {
20586
+ keys.add(field.key.trim());
20587
+ }
20588
+ });
20589
+ return keys;
20590
+ }
20591
+ function nextSDKGenFallbackFieldKey(fieldId, usedKeys) {
20592
+ const base = `field${fieldId}`;
20593
+ if (!usedKeys.has(base)) {
20594
+ usedKeys.add(base);
20595
+ return base;
20596
+ }
20597
+ let index = 2;
20598
+ while (usedKeys.has(`${base}_${index}`)) {
20599
+ index++;
20600
+ }
20601
+ const key = `${base}_${index}`;
20602
+ usedKeys.add(key);
20603
+ return key;
20604
+ }
20605
+ function initializeMissingSDKGenFieldKeys(entity) {
20606
+ const usedKeys = collectExistingSDKGenFieldKeys(entity);
20607
+ const updates = [];
20608
+ walkSDKGenFields(entity.fields, (field) => {
20609
+ if (typeof field.id !== "number") {
20610
+ return;
20611
+ }
20612
+ if (typeof field.key === "string" && field.key.trim() !== "") {
20613
+ field.key = field.key.trim();
20614
+ return;
20615
+ }
20616
+ const key = nextSDKGenFallbackFieldKey(field.id, usedKeys);
20617
+ field.key = key;
20618
+ updates.push({ id: field.id, key });
20619
+ });
20620
+ return updates;
20621
+ }
20622
+ async function executeDevSDKGen(runtimeEnv, flags, fetchImpl) {
20623
+ validateDevSDKGenFlags(flags);
20624
+ const appId = flagValue(flags, "app-id");
20625
+ const outDir = flagValue(flags, "out");
20626
+ if (!appId) {
20627
+ throw new CLIError("MISSING_PATH_FLAG", "missing required flag --app-id", 2);
20628
+ }
20629
+ if (!outDir) {
20630
+ throw new CLIError("MISSING_FLAG", "missing required flag --out", 2, {
20631
+ operation: "dev sdk-gen",
20632
+ hint: "retry with --out src/arcubase"
20633
+ });
20634
+ }
20635
+ const endpoint = `/api/apps/${encodeURIComponent(appId)}`;
20636
+ const appDetail = await requestJSON(runtimeEnv, "GET", endpoint, void 0, fetchImpl);
20637
+ const appPayload = extractSDKGenAppPayload(appDetail.data);
20638
+ let entityRefs = extractSDKGenEntityRefs(appPayload);
20639
+ if (entityRefs.length === 0) {
20640
+ const entitiesEndpoint = `/api/apps/${encodeURIComponent(appId)}/entities`;
20641
+ const entityList = await requestJSON(runtimeEnv, "GET", entitiesEndpoint, void 0, fetchImpl);
20642
+ const entityListPayload = unwrapResponseData(entityList.data);
20643
+ entityRefs = extractSDKGenEntityRefs({ entities: entityListPayload });
20644
+ }
20645
+ if (entityRefs.length === 0) {
20646
+ throw new CLIError("SDK_GEN_NO_ENTITIES", "sdk-gen could not find entities in app detail response", 2);
20647
+ }
20648
+ const entities = [];
20649
+ const initializedFieldKeys = [];
20650
+ for (const entityRef of entityRefs) {
20651
+ const entityEndpoint = `/api/apps/${encodeURIComponent(appId)}/entity/${encodeURIComponent(entityRef.id)}`;
20652
+ const entityDetail = await requestJSON(runtimeEnv, "GET", entityEndpoint, void 0, fetchImpl);
20653
+ const entityPayload = unwrapResponseData(entityDetail.data);
20654
+ if (!isRecord4(entityPayload)) {
20655
+ throw new CLIError("SDK_GEN_INVALID_SCHEMA", "sdk-gen expected entity detail response data", 2);
20656
+ }
20657
+ const customKeyUpdates = initializeMissingSDKGenFieldKeys(entityPayload);
20658
+ if (customKeyUpdates.length > 0) {
20659
+ const customKeysEndpoint = `/api/apps/${encodeURIComponent(appId)}/entity/${encodeURIComponent(entityRef.id)}/custom-keys`;
20660
+ await requestJSON(runtimeEnv, "PUT", customKeysEndpoint, customKeyUpdates, fetchImpl);
20661
+ initializedFieldKeys.push({
20662
+ entityId: typeof entityPayload.id === "number" ? entityPayload.id : Number(entityRef.id),
20663
+ fields: customKeyUpdates.map((item) => item.key)
20664
+ });
20665
+ }
20666
+ entities.push(entityPayload);
20667
+ }
20668
+ const generated = generateArcubaseProjectSDK({
20669
+ id: resolveSDKGenAppId(appId, appPayload),
20670
+ name: typeof appPayload.name === "string" ? appPayload.name : void 0,
20671
+ entities
20672
+ });
20673
+ const absoluteOutDir = path2.resolve(process.cwd(), outDir);
20674
+ for (const file2 of generated.files) {
20675
+ const targetPath = path2.resolve(absoluteOutDir, file2.path);
20676
+ if (!targetPath.startsWith(`${absoluteOutDir}${path2.sep}`)) {
20677
+ throw new CLIError("SDK_GEN_INVALID_OUTPUT_PATH", `invalid generated file path: ${file2.path}`, 2);
20678
+ }
20679
+ fs3.mkdirSync(path2.dirname(targetPath), { recursive: true });
20680
+ fs3.writeFileSync(targetPath, file2.contents);
20681
+ }
20682
+ return {
20683
+ kind: "result",
20684
+ commandPath: ["dev", "sdk-gen"],
20685
+ status: appDetail.status,
20686
+ data: {
20687
+ out: absoluteOutDir,
20688
+ files: generated.files.map((file2) => file2.path),
20689
+ initializedFieldKeys
20690
+ }
20691
+ };
20692
+ }
19485
20693
  function requiredStringFlag(flags, flag) {
19486
20694
  const value = flagValue(flags, flag);
19487
20695
  if (!value) {
@@ -19547,10 +20755,10 @@ async function executeWatchAppBundleImportTask(runtimeEnv, flags, fetchImpl) {
19547
20755
  while (Date.now() <= deadline) {
19548
20756
  const result = await requestJSON(runtimeEnv, "GET", endpoint, void 0, fetchImpl);
19549
20757
  latest = result.data;
19550
- const payload = isRecord3(latest) && isRecord3(latest.data) ? latest.data : latest;
19551
- const status = isRecord3(payload) ? payload.status : void 0;
20758
+ const payload = isRecord4(latest) && isRecord4(latest.data) ? latest.data : latest;
20759
+ const status = isRecord4(payload) ? payload.status : void 0;
19552
20760
  if (status === "finished") {
19553
- const appID = isRecord3(payload) ? Number(payload.app_id) : 0;
20761
+ const appID = isRecord4(payload) ? Number(payload.app_id) : 0;
19554
20762
  if (!Number.isFinite(appID) || appID <= 0) {
19555
20763
  throw new CLIError("IMPORT_TASK_APP_ID_MISSING", "app bundle import task finished without app_id", 1, {
19556
20764
  endpoint,
@@ -19566,7 +20774,7 @@ async function executeWatchAppBundleImportTask(runtimeEnv, flags, fetchImpl) {
19566
20774
  };
19567
20775
  }
19568
20776
  if (status === "failed") {
19569
- throw new CLIError("IMPORT_TASK_FAILED", isRecord3(payload) && typeof payload.error === "string" ? payload.error : "app bundle import task failed", 1, {
20777
+ throw new CLIError("IMPORT_TASK_FAILED", isRecord4(payload) && typeof payload.error === "string" ? payload.error : "app bundle import task failed", 1, {
19570
20778
  endpoint,
19571
20779
  responseBody: stringifyUpstreamBody(latest)
19572
20780
  });
@@ -19635,25 +20843,25 @@ async function postEntityImportAction(runtimeEnv, appId, entityId, body, fetchIm
19635
20843
  function extractImportTaskID(value) {
19636
20844
  const candidates = [
19637
20845
  value,
19638
- isRecord3(value) ? value.data : void 0
20846
+ isRecord4(value) ? value.data : void 0
19639
20847
  ];
19640
20848
  for (const candidate of candidates) {
19641
- if (isRecord3(candidate) && typeof candidate.taskId === "string") return candidate.taskId;
19642
- if (isRecord3(candidate) && typeof candidate.task_id === "string") return candidate.task_id;
20849
+ if (isRecord4(candidate) && typeof candidate.taskId === "string") return candidate.taskId;
20850
+ if (isRecord4(candidate) && typeof candidate.task_id === "string") return candidate.task_id;
19643
20851
  if (typeof candidate === "string") return candidate;
19644
20852
  }
19645
20853
  throw new CLIError("UPSTREAM_RESPONSE_INVALID", "import response did not include taskId", 1);
19646
20854
  }
19647
20855
  function extractUploadToken(value) {
19648
- const payload = isRecord3(value) && isRecord3(value.data) ? value.data : value;
19649
- if (isRecord3(payload) && isRecord3(payload.token)) return payload.token;
20856
+ const payload = isRecord4(value) && isRecord4(value.data) ? value.data : value;
20857
+ if (isRecord4(payload) && isRecord4(payload.token)) return payload.token;
19650
20858
  throw new CLIError("UPSTREAM_RESPONSE_INVALID", "import init-token response did not include upload token", 1);
19651
20859
  }
19652
20860
  function compileEntityImportConfig(format, mapping, filePath) {
19653
20861
  if (format === "excel") {
19654
20862
  return compileExcelImportMapping(mapping);
19655
20863
  }
19656
- const delimiter = isRecord3(mapping) && typeof mapping.delimiter === "string" ? mapping.delimiter : ",";
20864
+ const delimiter = isRecord4(mapping) && typeof mapping.delimiter === "string" ? mapping.delimiter : ",";
19657
20865
  return compileCSVImportMapping(mapping, csvHeadersFromLocalFile(filePath, delimiter));
19658
20866
  }
19659
20867
  async function executeEntityRecordImport(command, runtimeEnv, flags, fetchImpl) {
@@ -19680,8 +20888,8 @@ async function executeEntityRecordImport(command, runtimeEnv, flags, fetchImpl)
19680
20888
  let latest = null;
19681
20889
  while (Date.now() <= deadline) {
19682
20890
  latest = await postEntityImportAction(runtimeEnv, appId, entityId, { _import_action: "get-state", task_id: taskId }, fetchImpl);
19683
- const payload = isRecord3(latest) && isRecord3(latest.data) ? latest.data : latest;
19684
- const status = isRecord3(payload) ? payload.status : void 0;
20891
+ const payload = isRecord4(latest) && isRecord4(latest.data) ? latest.data : latest;
20892
+ const status = isRecord4(payload) ? payload.status : void 0;
19685
20893
  if (status === "finished") {
19686
20894
  return {
19687
20895
  kind: "result",
@@ -19704,11 +20912,11 @@ async function executeEntityRecordImport(command, runtimeEnv, flags, fetchImpl)
19704
20912
  function extractCreatedTableID(value) {
19705
20913
  const candidates = [
19706
20914
  value,
19707
- isRecord3(value) ? value.data : void 0,
19708
- isRecord3(value) && isRecord3(value.data) ? value.data.data : void 0
20915
+ isRecord4(value) ? value.data : void 0,
20916
+ isRecord4(value) && isRecord4(value.data) ? value.data.data : void 0
19709
20917
  ];
19710
20918
  for (const candidate of candidates) {
19711
- if (isRecord3(candidate) && typeof candidate.id === "number") {
20919
+ if (isRecord4(candidate) && typeof candidate.id === "number") {
19712
20920
  return candidate.id;
19713
20921
  }
19714
20922
  }
@@ -19722,7 +20930,7 @@ function normalizeTableCreateSchemaBody(body, appId, tableId) {
19722
20930
  app_id: Number.isFinite(Number(appId)) ? Number(appId) : body.app_id,
19723
20931
  schema_version: typeof body.schema_version === "number" ? body.schema_version : 0,
19724
20932
  layout: Array.isArray(body.layout) ? body.layout : [],
19725
- options: isRecord3(body.options) ? body.options : { Buttons: [], CustomActions: [], FrontendEvents: [], TitleFormat: { Fields: [], Parts: [], Body: "" }, misc: {} },
20933
+ options: isRecord4(body.options) ? body.options : { Buttons: [], CustomActions: [], FrontendEvents: [], TitleFormat: { Fields: [], Parts: [], Body: "" }, misc: {} },
19726
20934
  workflow_enabled: typeof body.workflow_enabled === "boolean" ? body.workflow_enabled : false
19727
20935
  };
19728
20936
  }
@@ -19731,7 +20939,7 @@ async function executeTableCreateWithSchema(command, runtimeEnv, flags, body, fe
19731
20939
  if (!appId) {
19732
20940
  throw new CLIError("MISSING_PATH_FLAG", "missing required flag --app-id", 2);
19733
20941
  }
19734
- if (!isRecord3(body)) {
20942
+ if (!isRecord4(body)) {
19735
20943
  throw new CLIError("BODY_VALIDATION_FAILED", "table create body must be an object", 2);
19736
20944
  }
19737
20945
  const createBody = {
@@ -19801,6 +21009,16 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
19801
21009
  }
19802
21010
  return { kind: "help", text: renderRootHelp(scope) };
19803
21011
  }
21012
+ if (isDevSDKGenCommand(scope, moduleName, commandName)) {
21013
+ if (hasFlag(parsed.flags, "help")) {
21014
+ return { kind: "help", text: renderDevSDKGenHelp() };
21015
+ }
21016
+ const runtimeEnv2 = env ?? loadRuntimeEnv(scope);
21017
+ return executeDevSDKGen(runtimeEnv2, parsed.flags, fetchImpl);
21018
+ }
21019
+ if (scope === "admin" && moduleName === "dev" && !commandName) {
21020
+ return { kind: "help", text: renderDevModuleHelp() };
21021
+ }
19804
21022
  const singleTokenCommand = !commandName ? findCommand(scope, moduleName) : null;
19805
21023
  if (!commandName && !singleTokenCommand) {
19806
21024
  if (hasFlag(parsed.flags, "help-examples")) {
@@ -19863,7 +21081,7 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
19863
21081
  if (isTableCreateCommand(scope, command)) {
19864
21082
  requireTableCreateSchemaBody(scope, command, body, runtimeEnv);
19865
21083
  validateActionSpecificRawBody(scope, command, body, runtimeEnv);
19866
- const { parent: _parent, ...schemaBody } = isRecord3(body) ? body : {};
21084
+ const { parent: _parent, ...schemaBody } = isRecord4(body) ? body : {};
19867
21085
  const parsedBody = getBodySchema("EntitySaveReqVO")?.safeParse(schemaBody);
19868
21086
  if (!parsedBody?.success) {
19869
21087
  const message = parsedBody ? parsedBody.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; ") : "EntitySaveReqVO schema is not available";