@carthooks/arcubase-cli 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/arcubase-admin.mjs +727 -45
- package/bundle/arcubase.mjs +727 -45
- package/dist/generated/command_registry.generated.d.ts +15 -0
- package/dist/generated/command_registry.generated.d.ts.map +1 -1
- package/dist/generated/command_registry.generated.js +21 -0
- package/dist/generated/help_examples.generated.d.ts +319 -0
- package/dist/generated/help_examples.generated.d.ts.map +1 -0
- package/dist/generated/help_examples.generated.js +437 -0
- package/dist/generated/type_index.generated.d.ts +4 -0
- package/dist/generated/type_index.generated.d.ts.map +1 -1
- package/dist/generated/type_index.generated.js +4 -0
- package/dist/generated/zod_registry.generated.d.ts +4 -1
- package/dist/generated/zod_registry.generated.d.ts.map +1 -1
- package/dist/generated/zod_registry.generated.js +4 -0
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +155 -17
- package/dist/runtime/help_examples.d.ts +10 -0
- package/dist/runtime/help_examples.d.ts.map +1 -0
- package/dist/runtime/help_examples.js +48 -0
- package/dist/runtime/zod_registry.d.ts.map +1 -1
- package/dist/runtime/zod_registry.js +8 -0
- package/package.json +4 -3
- package/sdk-dist/api/admin/ingress.ts +11 -0
- package/sdk-dist/docs/runtime-reference/access-rule.md +19 -0
- package/sdk-dist/docs/runtime-reference/help-examples/admin/access-rule/assign-users.json +23 -0
- package/sdk-dist/docs/runtime-reference/help-examples/admin/access-rule/bulk-apply.json +105 -0
- package/sdk-dist/docs/runtime-reference/help-examples/admin/access-rule/create.json +95 -0
- package/sdk-dist/docs/runtime-reference/help-examples/user/row/bulk-update.json +23 -0
- package/sdk-dist/docs/runtime-reference/help-examples/user/row/selection-action.json +25 -0
- package/sdk-dist/generated/command_registry.generated.ts +21 -0
- package/sdk-dist/generated/help_examples.generated.ts +444 -0
- package/sdk-dist/generated/type_index.generated.ts +4 -0
- package/sdk-dist/generated/zod_registry.generated.ts +6 -0
- package/sdk-dist/types/ingress.ts +31 -0
- package/src/generated/command_registry.generated.ts +21 -0
- package/src/generated/help_examples.generated.ts +444 -0
- package/src/generated/type_index.generated.ts +4 -0
- package/src/generated/zod_registry.generated.ts +6 -0
- package/src/runtime/execute.ts +223 -37
- package/src/runtime/help_examples.ts +61 -0
- package/src/runtime/zod_registry.ts +8 -0
- package/src/tests/command_registry.test.ts +1 -0
- package/src/tests/execute_validation.test.ts +113 -0
- package/src/tests/help.test.ts +45 -0
|
@@ -605,6 +605,27 @@ var adminCommands = [
|
|
|
605
605
|
"queryParams": [],
|
|
606
606
|
"responseType": "AppIngressUpdateRespVO"
|
|
607
607
|
},
|
|
608
|
+
{
|
|
609
|
+
"scope": "admin",
|
|
610
|
+
"module": "access-rule",
|
|
611
|
+
"functionName": "bulkApplyEntityIngress",
|
|
612
|
+
"commandPath": [
|
|
613
|
+
"access-rule",
|
|
614
|
+
"bulk-apply"
|
|
615
|
+
],
|
|
616
|
+
"method": "POST",
|
|
617
|
+
"endpoint": "/api/apps/:app_id/access-rules/bulk-apply",
|
|
618
|
+
"pathParams": [
|
|
619
|
+
{
|
|
620
|
+
"param": "app_id",
|
|
621
|
+
"flag": "app-id"
|
|
622
|
+
}
|
|
623
|
+
],
|
|
624
|
+
"controller": "App.IngressBulkApply",
|
|
625
|
+
"requestType": "AppIngressBulkApplyReqVO",
|
|
626
|
+
"queryParams": [],
|
|
627
|
+
"responseType": "AppIngressBulkApplyRespVO"
|
|
628
|
+
},
|
|
608
629
|
{
|
|
609
630
|
"scope": "admin",
|
|
610
631
|
"module": "workflow",
|
|
@@ -16092,6 +16113,8 @@ var PermitFieldPermitSchema = external_exports.lazy(() => external_exports.objec
|
|
|
16092
16113
|
var PermitPolicySchema = external_exports.lazy(() => external_exports.object({ "actions": external_exports.array(external_exports.string()).optional(), "all_fields_read": external_exports.boolean().optional(), "all_fields_write": external_exports.boolean().optional(), "condition": PermitConditionSetSchema.optional(), "description": external_exports.string().optional(), "fields": external_exports.array(PermitFieldPermitSchema).optional(), "id": external_exports.string().optional(), "key": external_exports.string().optional(), "name": external_exports.string().optional() }).strict());
|
|
16093
16114
|
var PermitUserScopeSchema = external_exports.lazy(() => external_exports.object({ "data": external_exports.object({ "name": external_exports.string().optional() }).strict().optional(), "id": external_exports.number().optional(), "type": external_exports.string().optional() }).strict());
|
|
16094
16115
|
var EntityIngressOptionsSchema = external_exports.lazy(() => external_exports.object({ "i18n_name": I18NTextSchema.optional(), "list_options": PermitEntityListOptionsSchema.optional(), "policy": PermitPolicySchema.optional(), "user_scope": external_exports.array(PermitUserScopeSchema).optional() }).strict());
|
|
16116
|
+
var AppIngressBulkApplyItemVOSchema = external_exports.lazy(() => external_exports.object({ "enabled": external_exports.boolean().optional(), "name": external_exports.string().optional(), "options": EntityIngressOptionsSchema.optional(), "rule_id": external_exports.number().optional(), "table_id": external_exports.number().optional(), "type": external_exports.string().optional() }).strict());
|
|
16117
|
+
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());
|
|
16095
16118
|
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());
|
|
16096
16119
|
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());
|
|
16097
16120
|
var GormDeletedAtSchema = external_exports.lazy(() => external_exports.object({ "Time": external_exports.string().optional(), "Valid": external_exports.boolean().optional() }).strict());
|
|
@@ -16159,6 +16182,7 @@ var UserProfileUpdateReqVOSchema = external_exports.lazy(() => external_exports.
|
|
|
16159
16182
|
var bodySchemas = {
|
|
16160
16183
|
"AppCreateByTenantsReqVO": AppCreateByTenantsReqVOSchema,
|
|
16161
16184
|
"AppCreateEntityReqVO": AppCreateEntityReqVOSchema,
|
|
16185
|
+
"AppIngressBulkApplyReqVO": AppIngressBulkApplyReqVOSchema,
|
|
16162
16186
|
"AppIngressCreateReqVO": AppIngressCreateReqVOSchema,
|
|
16163
16187
|
"AppIngressUpdateReqVO": AppIngressUpdateReqVOSchema,
|
|
16164
16188
|
"AppUpdateAppReqVO": AppUpdateAppReqVOSchema,
|
|
@@ -16193,6 +16217,10 @@ var typeIndex = {
|
|
|
16193
16217
|
"file": "types/app.ts",
|
|
16194
16218
|
"dependencies": []
|
|
16195
16219
|
},
|
|
16220
|
+
"AppIngressBulkApplyReqVO": {
|
|
16221
|
+
"file": "types/ingress.ts",
|
|
16222
|
+
"dependencies": []
|
|
16223
|
+
},
|
|
16196
16224
|
"AppIngressCreateReqVO": {
|
|
16197
16225
|
"file": "types/ingress.ts",
|
|
16198
16226
|
"dependencies": []
|
|
@@ -17053,6 +17081,10 @@ var docHintIndex = {
|
|
|
17053
17081
|
{ title: "Access rule", file: "docs/runtime-reference/access-rule.md" },
|
|
17054
17082
|
examplesIndexDocHint
|
|
17055
17083
|
],
|
|
17084
|
+
AppIngressBulkApplyReqVO: [
|
|
17085
|
+
{ title: "Access rule", file: "docs/runtime-reference/access-rule.md" },
|
|
17086
|
+
examplesIndexDocHint
|
|
17087
|
+
],
|
|
17056
17088
|
EntitySaveReqVO: [
|
|
17057
17089
|
{ title: "Table schema cheatsheet", file: "docs/runtime-reference/entity-schema.md" },
|
|
17058
17090
|
{ title: "Field type index", file: "docs/runtime-reference/entity-schema/README.md" },
|
|
@@ -17166,6 +17198,10 @@ var commandDocHintIndex = {
|
|
|
17166
17198
|
{ title: "Access rule", file: "docs/runtime-reference/access-rule.md" },
|
|
17167
17199
|
examplesIndexDocHint
|
|
17168
17200
|
],
|
|
17201
|
+
"admin.access-rule.bulkApplyEntityIngress": [
|
|
17202
|
+
{ title: "Access rule", file: "docs/runtime-reference/access-rule.md" },
|
|
17203
|
+
examplesIndexDocHint
|
|
17204
|
+
],
|
|
17169
17205
|
"user.row.insertEntity": [
|
|
17170
17206
|
{ title: "Row CRUD", file: "docs/runtime-reference/row-crud.md" },
|
|
17171
17207
|
{ title: "Uploads", file: "docs/runtime-reference/uploads.md" },
|
|
@@ -17416,6 +17452,489 @@ async function uploadLocalFileWithToken(filePath, token, fetchImpl = fetch) {
|
|
|
17416
17452
|
return { objectKey };
|
|
17417
17453
|
}
|
|
17418
17454
|
|
|
17455
|
+
// src/generated/help_examples.generated.ts
|
|
17456
|
+
var helpExamplesIndex = {
|
|
17457
|
+
"admin.access-rule.assign-users": {
|
|
17458
|
+
"command": [
|
|
17459
|
+
"access-rule",
|
|
17460
|
+
"assign-users"
|
|
17461
|
+
],
|
|
17462
|
+
"examples": [
|
|
17463
|
+
{
|
|
17464
|
+
"title": "replace user_scope with user, department, and actor scopes",
|
|
17465
|
+
"body": {
|
|
17466
|
+
"update": [
|
|
17467
|
+
"user_scope"
|
|
17468
|
+
],
|
|
17469
|
+
"options": {
|
|
17470
|
+
"user_scope": [
|
|
17471
|
+
{
|
|
17472
|
+
"type": "user",
|
|
17473
|
+
"id": 2188889901
|
|
17474
|
+
},
|
|
17475
|
+
{
|
|
17476
|
+
"type": "department",
|
|
17477
|
+
"id": 2188881201
|
|
17478
|
+
},
|
|
17479
|
+
{
|
|
17480
|
+
"type": "actor",
|
|
17481
|
+
"id": 2188883301
|
|
17482
|
+
}
|
|
17483
|
+
]
|
|
17484
|
+
}
|
|
17485
|
+
},
|
|
17486
|
+
"notes": [
|
|
17487
|
+
"id must be numeric arcubaseUserId, department ID, or actor ID",
|
|
17488
|
+
"assign-users updates user_scope only and preserves the existing policy"
|
|
17489
|
+
]
|
|
17490
|
+
}
|
|
17491
|
+
]
|
|
17492
|
+
},
|
|
17493
|
+
"admin.access-rule.bulk-apply": {
|
|
17494
|
+
"command": [
|
|
17495
|
+
"access-rule",
|
|
17496
|
+
"bulk-apply"
|
|
17497
|
+
],
|
|
17498
|
+
"examples": [
|
|
17499
|
+
{
|
|
17500
|
+
"title": "upsert permission matrix by rule name in one transaction",
|
|
17501
|
+
"body": {
|
|
17502
|
+
"mode": "upsert_by_name",
|
|
17503
|
+
"items": [
|
|
17504
|
+
{
|
|
17505
|
+
"table_id": 2188893443,
|
|
17506
|
+
"name": "Customer archive - sales owns rows",
|
|
17507
|
+
"enabled": true,
|
|
17508
|
+
"type": "form",
|
|
17509
|
+
"options": {
|
|
17510
|
+
"user_scope": [
|
|
17511
|
+
{
|
|
17512
|
+
"type": "department",
|
|
17513
|
+
"id": 2188881201
|
|
17514
|
+
}
|
|
17515
|
+
],
|
|
17516
|
+
"policy": {
|
|
17517
|
+
"key": "custom",
|
|
17518
|
+
"actions": [
|
|
17519
|
+
"view",
|
|
17520
|
+
"add",
|
|
17521
|
+
"edit"
|
|
17522
|
+
],
|
|
17523
|
+
"all_fields_read": true,
|
|
17524
|
+
"all_fields_write": true,
|
|
17525
|
+
"condition": {
|
|
17526
|
+
"mode": "and",
|
|
17527
|
+
"conditions": [
|
|
17528
|
+
{
|
|
17529
|
+
"column": "creator",
|
|
17530
|
+
"operator": "$eq",
|
|
17531
|
+
"value": "[[current_user]]",
|
|
17532
|
+
"value_from": 0,
|
|
17533
|
+
"value_relation": ""
|
|
17534
|
+
}
|
|
17535
|
+
]
|
|
17536
|
+
}
|
|
17537
|
+
},
|
|
17538
|
+
"list_options": {}
|
|
17539
|
+
}
|
|
17540
|
+
},
|
|
17541
|
+
{
|
|
17542
|
+
"table_id": 2188893444,
|
|
17543
|
+
"name": "Lead review - manager queue",
|
|
17544
|
+
"enabled": true,
|
|
17545
|
+
"type": "form",
|
|
17546
|
+
"options": {
|
|
17547
|
+
"user_scope": [
|
|
17548
|
+
{
|
|
17549
|
+
"type": "actor",
|
|
17550
|
+
"id": 2188883301
|
|
17551
|
+
}
|
|
17552
|
+
],
|
|
17553
|
+
"policy": {
|
|
17554
|
+
"key": "custom",
|
|
17555
|
+
"actions": [
|
|
17556
|
+
"view",
|
|
17557
|
+
"edit"
|
|
17558
|
+
],
|
|
17559
|
+
"all_fields_read": true,
|
|
17560
|
+
"all_fields_write": true,
|
|
17561
|
+
"condition": {
|
|
17562
|
+
"mode": "and",
|
|
17563
|
+
"conditions": [
|
|
17564
|
+
{
|
|
17565
|
+
"column": ":1004",
|
|
17566
|
+
"operator": "$eq",
|
|
17567
|
+
"value": "pending",
|
|
17568
|
+
"value_from": 0,
|
|
17569
|
+
"value_relation": ""
|
|
17570
|
+
},
|
|
17571
|
+
{
|
|
17572
|
+
"column": "",
|
|
17573
|
+
"operator": "",
|
|
17574
|
+
"value": null,
|
|
17575
|
+
"value_from": 0,
|
|
17576
|
+
"value_relation": "",
|
|
17577
|
+
"subset": {
|
|
17578
|
+
"mode": "or",
|
|
17579
|
+
"conditions": [
|
|
17580
|
+
{
|
|
17581
|
+
"column": "creator",
|
|
17582
|
+
"operator": "$eq",
|
|
17583
|
+
"value": "[[current_user]]",
|
|
17584
|
+
"value_from": 0,
|
|
17585
|
+
"value_relation": ""
|
|
17586
|
+
},
|
|
17587
|
+
{
|
|
17588
|
+
"column": ":1005",
|
|
17589
|
+
"operator": "$eq",
|
|
17590
|
+
"value": "high",
|
|
17591
|
+
"value_from": 0,
|
|
17592
|
+
"value_relation": ""
|
|
17593
|
+
}
|
|
17594
|
+
]
|
|
17595
|
+
}
|
|
17596
|
+
}
|
|
17597
|
+
]
|
|
17598
|
+
}
|
|
17599
|
+
},
|
|
17600
|
+
"list_options": {}
|
|
17601
|
+
}
|
|
17602
|
+
}
|
|
17603
|
+
]
|
|
17604
|
+
},
|
|
17605
|
+
"notes": [
|
|
17606
|
+
"mode upsert_by_name is for idempotent setup; rule names must be unique within each table",
|
|
17607
|
+
"department, actor, and specific user scopes all use options.user_scope",
|
|
17608
|
+
"row-owner isolation uses [[current_user]] in policy.condition"
|
|
17609
|
+
]
|
|
17610
|
+
},
|
|
17611
|
+
{
|
|
17612
|
+
"title": "preview updates for existing rule ids",
|
|
17613
|
+
"body": {
|
|
17614
|
+
"mode": "update_existing",
|
|
17615
|
+
"dry_run": true,
|
|
17616
|
+
"items": [
|
|
17617
|
+
{
|
|
17618
|
+
"table_id": 2188893443,
|
|
17619
|
+
"rule_id": 2188893557,
|
|
17620
|
+
"enabled": true,
|
|
17621
|
+
"options": {
|
|
17622
|
+
"user_scope": [
|
|
17623
|
+
{
|
|
17624
|
+
"type": "user",
|
|
17625
|
+
"id": 2188889901
|
|
17626
|
+
}
|
|
17627
|
+
],
|
|
17628
|
+
"policy": {
|
|
17629
|
+
"key": "custom",
|
|
17630
|
+
"actions": [
|
|
17631
|
+
"view"
|
|
17632
|
+
],
|
|
17633
|
+
"all_fields_read": true,
|
|
17634
|
+
"all_fields_write": false
|
|
17635
|
+
},
|
|
17636
|
+
"list_options": {}
|
|
17637
|
+
}
|
|
17638
|
+
}
|
|
17639
|
+
]
|
|
17640
|
+
},
|
|
17641
|
+
"notes": [
|
|
17642
|
+
"dry_run true returns the planned operations without writing",
|
|
17643
|
+
"update_existing requires rule_id on every item"
|
|
17644
|
+
]
|
|
17645
|
+
}
|
|
17646
|
+
]
|
|
17647
|
+
},
|
|
17648
|
+
"admin.access-rule.create": {
|
|
17649
|
+
"command": [
|
|
17650
|
+
"access-rule",
|
|
17651
|
+
"create"
|
|
17652
|
+
],
|
|
17653
|
+
"examples": [
|
|
17654
|
+
{
|
|
17655
|
+
"title": "full access for a specific arcubaseUserId",
|
|
17656
|
+
"body": {
|
|
17657
|
+
"name": "Admin full access",
|
|
17658
|
+
"enabled": true,
|
|
17659
|
+
"type": "form",
|
|
17660
|
+
"options": {
|
|
17661
|
+
"user_scope": [
|
|
17662
|
+
{
|
|
17663
|
+
"type": "user",
|
|
17664
|
+
"id": 2188889977
|
|
17665
|
+
}
|
|
17666
|
+
],
|
|
17667
|
+
"policy": {
|
|
17668
|
+
"key": "custom",
|
|
17669
|
+
"actions": [
|
|
17670
|
+
"view",
|
|
17671
|
+
"add",
|
|
17672
|
+
"edit",
|
|
17673
|
+
"delete"
|
|
17674
|
+
],
|
|
17675
|
+
"all_fields_read": true,
|
|
17676
|
+
"all_fields_write": true
|
|
17677
|
+
},
|
|
17678
|
+
"list_options": {}
|
|
17679
|
+
}
|
|
17680
|
+
}
|
|
17681
|
+
},
|
|
17682
|
+
{
|
|
17683
|
+
"title": "department can view/add/edit only rows created by themselves",
|
|
17684
|
+
"body": {
|
|
17685
|
+
"name": "Sales own rows",
|
|
17686
|
+
"enabled": true,
|
|
17687
|
+
"type": "form",
|
|
17688
|
+
"options": {
|
|
17689
|
+
"user_scope": [
|
|
17690
|
+
{
|
|
17691
|
+
"type": "department",
|
|
17692
|
+
"id": 2188881201
|
|
17693
|
+
}
|
|
17694
|
+
],
|
|
17695
|
+
"policy": {
|
|
17696
|
+
"key": "custom",
|
|
17697
|
+
"actions": [
|
|
17698
|
+
"view",
|
|
17699
|
+
"add",
|
|
17700
|
+
"edit"
|
|
17701
|
+
],
|
|
17702
|
+
"all_fields_read": true,
|
|
17703
|
+
"all_fields_write": true,
|
|
17704
|
+
"condition": {
|
|
17705
|
+
"mode": "and",
|
|
17706
|
+
"conditions": [
|
|
17707
|
+
{
|
|
17708
|
+
"column": "creator",
|
|
17709
|
+
"operator": "$eq",
|
|
17710
|
+
"value": "[[current_user]]",
|
|
17711
|
+
"value_from": 0,
|
|
17712
|
+
"value_relation": ""
|
|
17713
|
+
}
|
|
17714
|
+
]
|
|
17715
|
+
}
|
|
17716
|
+
},
|
|
17717
|
+
"list_options": {}
|
|
17718
|
+
}
|
|
17719
|
+
},
|
|
17720
|
+
"notes": [
|
|
17721
|
+
"department scope includes child departments",
|
|
17722
|
+
"row-owner isolation uses [[current_user]] on creator"
|
|
17723
|
+
]
|
|
17724
|
+
},
|
|
17725
|
+
{
|
|
17726
|
+
"title": "role actor can view rows matching a complex AND/OR condition",
|
|
17727
|
+
"body": {
|
|
17728
|
+
"name": "Sales manager review queue",
|
|
17729
|
+
"enabled": true,
|
|
17730
|
+
"type": "form",
|
|
17731
|
+
"options": {
|
|
17732
|
+
"user_scope": [
|
|
17733
|
+
{
|
|
17734
|
+
"type": "actor",
|
|
17735
|
+
"id": 2188883301
|
|
17736
|
+
}
|
|
17737
|
+
],
|
|
17738
|
+
"policy": {
|
|
17739
|
+
"key": "custom",
|
|
17740
|
+
"actions": [
|
|
17741
|
+
"view",
|
|
17742
|
+
"edit"
|
|
17743
|
+
],
|
|
17744
|
+
"all_fields_read": true,
|
|
17745
|
+
"all_fields_write": true,
|
|
17746
|
+
"condition": {
|
|
17747
|
+
"mode": "and",
|
|
17748
|
+
"conditions": [
|
|
17749
|
+
{
|
|
17750
|
+
"column": ":1004",
|
|
17751
|
+
"operator": "$eq",
|
|
17752
|
+
"value": "pending",
|
|
17753
|
+
"value_from": 0,
|
|
17754
|
+
"value_relation": ""
|
|
17755
|
+
},
|
|
17756
|
+
{
|
|
17757
|
+
"column": "",
|
|
17758
|
+
"operator": "",
|
|
17759
|
+
"value": null,
|
|
17760
|
+
"value_from": 0,
|
|
17761
|
+
"value_relation": "",
|
|
17762
|
+
"subset": {
|
|
17763
|
+
"mode": "or",
|
|
17764
|
+
"conditions": [
|
|
17765
|
+
{
|
|
17766
|
+
"column": "creator",
|
|
17767
|
+
"operator": "$eq",
|
|
17768
|
+
"value": "[[current_user]]",
|
|
17769
|
+
"value_from": 0,
|
|
17770
|
+
"value_relation": ""
|
|
17771
|
+
},
|
|
17772
|
+
{
|
|
17773
|
+
"column": ":1005",
|
|
17774
|
+
"operator": "$eq",
|
|
17775
|
+
"value": "high",
|
|
17776
|
+
"value_from": 0,
|
|
17777
|
+
"value_relation": ""
|
|
17778
|
+
}
|
|
17779
|
+
]
|
|
17780
|
+
}
|
|
17781
|
+
}
|
|
17782
|
+
]
|
|
17783
|
+
}
|
|
17784
|
+
},
|
|
17785
|
+
"list_options": {}
|
|
17786
|
+
}
|
|
17787
|
+
},
|
|
17788
|
+
"notes": [
|
|
17789
|
+
"actor means Arcubase role id",
|
|
17790
|
+
'condition mode "and" and "or" are canonical; legacy "all" also reads as AND',
|
|
17791
|
+
"nested OR uses subset and leaves the wrapper column/operator empty"
|
|
17792
|
+
]
|
|
17793
|
+
}
|
|
17794
|
+
]
|
|
17795
|
+
},
|
|
17796
|
+
"user.row.bulk-update": {
|
|
17797
|
+
"command": [
|
|
17798
|
+
"row",
|
|
17799
|
+
"bulk-update"
|
|
17800
|
+
],
|
|
17801
|
+
"examples": [
|
|
17802
|
+
{
|
|
17803
|
+
"title": "bulk update explicit row ids",
|
|
17804
|
+
"body": {
|
|
17805
|
+
"selection": {
|
|
17806
|
+
"type": "ids",
|
|
17807
|
+
"ids": [
|
|
17808
|
+
2188890411,
|
|
17809
|
+
2188890412
|
|
17810
|
+
],
|
|
17811
|
+
"length": 2
|
|
17812
|
+
},
|
|
17813
|
+
"fields": [
|
|
17814
|
+
{
|
|
17815
|
+
"id": 1003,
|
|
17816
|
+
"action": {
|
|
17817
|
+
"type": "set",
|
|
17818
|
+
"value": 2
|
|
17819
|
+
}
|
|
17820
|
+
}
|
|
17821
|
+
]
|
|
17822
|
+
}
|
|
17823
|
+
},
|
|
17824
|
+
{
|
|
17825
|
+
"title": "bulk update rows selected by a search condition",
|
|
17826
|
+
"body": {
|
|
17827
|
+
"selection": {
|
|
17828
|
+
"type": "condition",
|
|
17829
|
+
"condition": {
|
|
17830
|
+
"selectAll": true,
|
|
17831
|
+
"q": "SO-1001"
|
|
17832
|
+
},
|
|
17833
|
+
"length": 0
|
|
17834
|
+
},
|
|
17835
|
+
"fields": [
|
|
17836
|
+
{
|
|
17837
|
+
"id": 1003,
|
|
17838
|
+
"action": {
|
|
17839
|
+
"type": "set",
|
|
17840
|
+
"value": 2
|
|
17841
|
+
}
|
|
17842
|
+
}
|
|
17843
|
+
]
|
|
17844
|
+
},
|
|
17845
|
+
"notes": [
|
|
17846
|
+
"condition selection uses row-query style keys such as q, tab, and filter_:1002"
|
|
17847
|
+
]
|
|
17848
|
+
}
|
|
17849
|
+
]
|
|
17850
|
+
},
|
|
17851
|
+
"user.row.selection-action": {
|
|
17852
|
+
"command": [
|
|
17853
|
+
"row",
|
|
17854
|
+
"selection-action"
|
|
17855
|
+
],
|
|
17856
|
+
"examples": [
|
|
17857
|
+
{
|
|
17858
|
+
"title": "run a custom action against explicit row ids",
|
|
17859
|
+
"body": {
|
|
17860
|
+
"selection": {
|
|
17861
|
+
"type": "ids",
|
|
17862
|
+
"ids": [
|
|
17863
|
+
2188890411
|
|
17864
|
+
],
|
|
17865
|
+
"length": 1
|
|
17866
|
+
}
|
|
17867
|
+
},
|
|
17868
|
+
"notes": [
|
|
17869
|
+
"pass the backend action code with --action",
|
|
17870
|
+
"for query action, use ids or all selection instead of condition selection"
|
|
17871
|
+
]
|
|
17872
|
+
},
|
|
17873
|
+
{
|
|
17874
|
+
"title": "run a custom action against a filtered selection",
|
|
17875
|
+
"body": {
|
|
17876
|
+
"selection": {
|
|
17877
|
+
"type": "condition",
|
|
17878
|
+
"condition": {
|
|
17879
|
+
"selectAll": true,
|
|
17880
|
+
"q": "SO-1001"
|
|
17881
|
+
},
|
|
17882
|
+
"length": 0
|
|
17883
|
+
}
|
|
17884
|
+
},
|
|
17885
|
+
"notes": [
|
|
17886
|
+
"condition selection uses row-query style keys such as q, tab, and filter_:1002"
|
|
17887
|
+
]
|
|
17888
|
+
}
|
|
17889
|
+
]
|
|
17890
|
+
}
|
|
17891
|
+
};
|
|
17892
|
+
|
|
17893
|
+
// src/runtime/help_examples.ts
|
|
17894
|
+
function binaryForScope(scope) {
|
|
17895
|
+
return scope === "admin" ? "arcubase-admin" : "arcubase";
|
|
17896
|
+
}
|
|
17897
|
+
function getFixedValue(value) {
|
|
17898
|
+
if (!("fixedValue" in value)) {
|
|
17899
|
+
return void 0;
|
|
17900
|
+
}
|
|
17901
|
+
const fixedValue = value.fixedValue;
|
|
17902
|
+
return typeof fixedValue === "string" ? fixedValue : void 0;
|
|
17903
|
+
}
|
|
17904
|
+
function pathFlagPlaceholders(command) {
|
|
17905
|
+
const parts = command.pathParams.filter((item) => !getFixedValue(item)).map((item) => `--${item.flag} <${item.flag.replace(/-/g, "_")}>`);
|
|
17906
|
+
return parts.length > 0 ? `${parts.join(" ")} ` : "";
|
|
17907
|
+
}
|
|
17908
|
+
function helpExampleKey(scope, command) {
|
|
17909
|
+
return `${scope}.${command.commandPath.join(".")}`;
|
|
17910
|
+
}
|
|
17911
|
+
function getCommandHelpExamples(scope, command) {
|
|
17912
|
+
return helpExamplesIndex[helpExampleKey(scope, command)]?.examples ?? [];
|
|
17913
|
+
}
|
|
17914
|
+
function renderCommandHelpExamples(scope, command) {
|
|
17915
|
+
const binary = binaryForScope(scope);
|
|
17916
|
+
const examples = getCommandHelpExamples(scope, command);
|
|
17917
|
+
const header = `${binary} ${command.commandPath.join(" ")} --help-examples`;
|
|
17918
|
+
if (examples.length === 0) {
|
|
17919
|
+
return [
|
|
17920
|
+
header,
|
|
17921
|
+
"",
|
|
17922
|
+
"No dedicated examples for this final command yet.",
|
|
17923
|
+
`Use ${binary} ${command.commandPath.join(" ")} --help for flags, docs, and type paths.`
|
|
17924
|
+
].join("\n");
|
|
17925
|
+
}
|
|
17926
|
+
return [
|
|
17927
|
+
header,
|
|
17928
|
+
"",
|
|
17929
|
+
...examples.flatMap((example) => [
|
|
17930
|
+
`${example.title}:`,
|
|
17931
|
+
...example.body === void 0 ? [] : [` ${binary} ${command.commandPath.join(" ")} ${pathFlagPlaceholders(command)}--body-json '${JSON.stringify(example.body)}'`.replace(/\s+/g, " ").trim()],
|
|
17932
|
+
...(example.notes ?? []).map((note) => ` - ${note}`),
|
|
17933
|
+
""
|
|
17934
|
+
])
|
|
17935
|
+
].join("\n").trimEnd();
|
|
17936
|
+
}
|
|
17937
|
+
|
|
17419
17938
|
// src/runtime/execute.ts
|
|
17420
17939
|
function renderRootHelp(scope) {
|
|
17421
17940
|
const binary = scope === "admin" ? "arcubase-admin" : "arcubase";
|
|
@@ -17453,9 +17972,32 @@ function buildUnknownCommandDetails(scope, moduleName, commandName) {
|
|
|
17453
17972
|
const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName}${item.commandName ? ` ${item.commandName}` : ""}`);
|
|
17454
17973
|
return suggestions.length > 0 ? { suggestions } : void 0;
|
|
17455
17974
|
}
|
|
17975
|
+
function throwHelpExamplesRequiresCommand(scope, moduleName) {
|
|
17976
|
+
const binary = binaryForScope2(scope);
|
|
17977
|
+
const suggestions = scope === "admin" ? [
|
|
17978
|
+
`${binary} access-rule create --help-examples`,
|
|
17979
|
+
`${binary} access-rule assign-users --help-examples`
|
|
17980
|
+
] : [
|
|
17981
|
+
`${binary} row bulk-update --help-examples`,
|
|
17982
|
+
`${binary} row selection-action --help-examples`
|
|
17983
|
+
];
|
|
17984
|
+
throw new CLIError(
|
|
17985
|
+
"HELP_EXAMPLES_REQUIRES_COMMAND",
|
|
17986
|
+
"--help-examples must follow a final command",
|
|
17987
|
+
2,
|
|
17988
|
+
{
|
|
17989
|
+
operation: moduleName ? `${binary} ${moduleName} --help-examples` : `${binary} --help-examples`,
|
|
17990
|
+
hint: `retry with a final command, for example: ${suggestions[0]}`,
|
|
17991
|
+
suggestions
|
|
17992
|
+
}
|
|
17993
|
+
);
|
|
17994
|
+
}
|
|
17456
17995
|
function sdkPath2(file2, env = process.env) {
|
|
17457
17996
|
return resolveArcubaseSDKPath(file2, env);
|
|
17458
17997
|
}
|
|
17998
|
+
function binaryForScope2(scope) {
|
|
17999
|
+
return scope === "admin" ? "arcubase-admin" : "arcubase";
|
|
18000
|
+
}
|
|
17459
18001
|
function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
17460
18002
|
const command = findCommand(scope, moduleName, commandName);
|
|
17461
18003
|
if (!command) {
|
|
@@ -17466,7 +18008,7 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17466
18008
|
...command.requestType ? getDocHints(command.requestType, env) : []
|
|
17467
18009
|
].filter((item, index, list) => list.findIndex((candidate) => candidate.file === item.file) === index);
|
|
17468
18010
|
const typeHints = command.requestType ? getTypeHints(command.requestType, env) : [];
|
|
17469
|
-
const pathFlags = command.pathParams.filter((item) => !
|
|
18011
|
+
const pathFlags = command.pathParams.filter((item) => !getFixedValue2(item)).map((item) => `--${item.flag}`);
|
|
17470
18012
|
const queryFlags = visibleQueryParams(command).map((item) => `--${item.flag}`);
|
|
17471
18013
|
const isTableCreate = scope === "admin" && command.commandPath[0] === "table" && command.commandPath[1] === "create";
|
|
17472
18014
|
const bodyTypeText = isTableCreate ? "TableCreateWithSchema" : command.requestType;
|
|
@@ -17478,6 +18020,7 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17478
18020
|
command.requestType ? `body: ${bodyTypeText} via --body-json <json-string> | --body-file <file>.json` : "body: none",
|
|
17479
18021
|
queryFlags.length ? `query flags: ${queryFlags.join(", ")}, --query-file` : "query flags: --query-file",
|
|
17480
18022
|
pathFlags.length ? `path flags: ${pathFlags.join(", ")}` : "path flags: none",
|
|
18023
|
+
`copyable examples: ${scope === "admin" ? "arcubase-admin" : "arcubase"} ${command.commandPath.join(" ")} --help-examples`,
|
|
17481
18024
|
...isTableCreate ? [
|
|
17482
18025
|
"body-json example:",
|
|
17483
18026
|
` - ${tableCreateExampleBody}`,
|
|
@@ -17576,7 +18119,7 @@ function coerceScalar(value, typeText) {
|
|
|
17576
18119
|
}
|
|
17577
18120
|
return value;
|
|
17578
18121
|
}
|
|
17579
|
-
function
|
|
18122
|
+
function getFixedValue2(value) {
|
|
17580
18123
|
if (!("fixedValue" in value)) {
|
|
17581
18124
|
return void 0;
|
|
17582
18125
|
}
|
|
@@ -17586,7 +18129,7 @@ function getFixedValue(value) {
|
|
|
17586
18129
|
function resolveEndpoint(command, flags) {
|
|
17587
18130
|
let resolved = command.endpoint;
|
|
17588
18131
|
for (const mapping of command.pathParams) {
|
|
17589
|
-
const value =
|
|
18132
|
+
const value = getFixedValue2(mapping) ?? flagValue(flags, mapping.flag);
|
|
17590
18133
|
if (!value) {
|
|
17591
18134
|
throw new CLIError("MISSING_PATH_FLAG", `missing required flag --${mapping.flag}`, 2);
|
|
17592
18135
|
}
|
|
@@ -17600,21 +18143,21 @@ function buildScalarQuery(command, flags) {
|
|
|
17600
18143
|
}
|
|
17601
18144
|
const out = {};
|
|
17602
18145
|
for (const scalar of effectiveQueryParams(command)) {
|
|
17603
|
-
const value =
|
|
18146
|
+
const value = getFixedValue2(scalar) ?? flagValue(flags, scalar.flag);
|
|
17604
18147
|
if (value === void 0) continue;
|
|
17605
18148
|
out[scalar.key] = coerceScalar(value, scalar.type);
|
|
17606
18149
|
}
|
|
17607
18150
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
17608
18151
|
}
|
|
17609
18152
|
function validateKnownFlags(command, flags, env = process.env) {
|
|
17610
|
-
const allowed = /* @__PURE__ */ new Set(["help", "body-file", "body-json", "query-file"]);
|
|
18153
|
+
const allowed = /* @__PURE__ */ new Set(["help", "help-examples", "body-file", "body-json", "query-file"]);
|
|
17611
18154
|
for (const mapping of command.pathParams) {
|
|
17612
|
-
if (!
|
|
18155
|
+
if (!getFixedValue2(mapping)) {
|
|
17613
18156
|
allowed.add(mapping.flag);
|
|
17614
18157
|
}
|
|
17615
18158
|
}
|
|
17616
18159
|
for (const query of visibleQueryParams(command)) {
|
|
17617
|
-
if (!
|
|
18160
|
+
if (!getFixedValue2(query)) {
|
|
17618
18161
|
allowed.add(query.flag);
|
|
17619
18162
|
}
|
|
17620
18163
|
}
|
|
@@ -17652,7 +18195,7 @@ function buildUnknownFlagDetails(command, flag, env = process.env) {
|
|
|
17652
18195
|
`do not pass request body fields as --${flag}`,
|
|
17653
18196
|
"put request body fields inside --body-json <json-string>"
|
|
17654
18197
|
];
|
|
17655
|
-
details.suggestions = [`retry with: ${command.commandPath.join(" ")} ${command.pathParams.filter((item) => !
|
|
18198
|
+
details.suggestions = [`retry with: ${command.commandPath.join(" ")} ${command.pathParams.filter((item) => !getFixedValue2(item)).map((item) => `--${item.flag} <${item.flag.replace(/-/g, "_")}>`).join(" ")} --body-json '<json>'`.replace(/\s+/g, " ").trim()];
|
|
17656
18199
|
}
|
|
17657
18200
|
if (command.commandPath[0] === "row" && command.commandPath[1] === "query" && ["limit", "offset", "search", "sorts", "view-mode"].includes(flag)) {
|
|
17658
18201
|
Object.assign(details, buildBodyGuidance("EntityQueryReqVO"));
|
|
@@ -17668,7 +18211,7 @@ function buildUnknownFlagDetails(command, flag, env = process.env) {
|
|
|
17668
18211
|
}
|
|
17669
18212
|
function visibleQueryParams(command) {
|
|
17670
18213
|
if (!command) return [];
|
|
17671
|
-
return effectiveQueryParams(command).filter((item) => !
|
|
18214
|
+
return effectiveQueryParams(command).filter((item) => !getFixedValue2(item));
|
|
17672
18215
|
}
|
|
17673
18216
|
function effectiveQueryParams(command) {
|
|
17674
18217
|
if (!command) return [];
|
|
@@ -17917,6 +18460,9 @@ function buildTableCreateExampleBody() {
|
|
|
17917
18460
|
function isAssignUsersCommand(scope, command) {
|
|
17918
18461
|
return scope === "admin" && command.commandPath[0] === "access-rule" && command.commandPath[1] === "assign-users";
|
|
17919
18462
|
}
|
|
18463
|
+
function isAccessRuleBulkApplyCommand(scope, command) {
|
|
18464
|
+
return scope === "admin" && command.commandPath[0] === "access-rule" && command.commandPath[1] === "bulk-apply";
|
|
18465
|
+
}
|
|
17920
18466
|
function isTableCreateCommand(scope, command) {
|
|
17921
18467
|
return scope === "admin" && command.commandPath[0] === "table" && command.commandPath[1] === "create";
|
|
17922
18468
|
}
|
|
@@ -18324,6 +18870,112 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
|
|
|
18324
18870
|
}
|
|
18325
18871
|
}
|
|
18326
18872
|
}
|
|
18873
|
+
function normalizeNumericAccessRuleUserScopeIDs(scope, command, body) {
|
|
18874
|
+
if (!isAccessRuleCommand(scope, command) || !isRecord3(body)) {
|
|
18875
|
+
return body;
|
|
18876
|
+
}
|
|
18877
|
+
const normalizeUserScope = (userScope) => {
|
|
18878
|
+
if (!Array.isArray(userScope)) return { value: userScope, changed: false };
|
|
18879
|
+
let changed = false;
|
|
18880
|
+
const value = userScope.map((item) => {
|
|
18881
|
+
if (!isRecord3(item) || typeof item.id !== "string" || !/^\d+$/.test(item.id)) {
|
|
18882
|
+
return item;
|
|
18883
|
+
}
|
|
18884
|
+
const id = Number(item.id);
|
|
18885
|
+
if (!Number.isFinite(id) || !Number.isInteger(id)) {
|
|
18886
|
+
return item;
|
|
18887
|
+
}
|
|
18888
|
+
changed = true;
|
|
18889
|
+
return { ...item, id };
|
|
18890
|
+
});
|
|
18891
|
+
return { value, changed };
|
|
18892
|
+
};
|
|
18893
|
+
const normalizeNumericID = (value) => {
|
|
18894
|
+
if (typeof value !== "string" || !/^\d+$/.test(value)) return { value, changed: false };
|
|
18895
|
+
const id = Number(value);
|
|
18896
|
+
if (!Number.isFinite(id) || !Number.isInteger(id)) return { value, changed: false };
|
|
18897
|
+
return { value: id, changed: true };
|
|
18898
|
+
};
|
|
18899
|
+
if (isAccessRuleBulkApplyCommand(scope, command) && Array.isArray(body.items)) {
|
|
18900
|
+
let changed = false;
|
|
18901
|
+
const items = body.items.map((item) => {
|
|
18902
|
+
if (!isRecord3(item)) return item;
|
|
18903
|
+
let nextItem = item;
|
|
18904
|
+
for (const key of ["table_id", "rule_id"]) {
|
|
18905
|
+
const normalized = normalizeNumericID(nextItem[key]);
|
|
18906
|
+
if (normalized.changed) {
|
|
18907
|
+
nextItem = { ...nextItem, [key]: normalized.value };
|
|
18908
|
+
changed = true;
|
|
18909
|
+
}
|
|
18910
|
+
}
|
|
18911
|
+
if (isRecord3(nextItem.options)) {
|
|
18912
|
+
const normalizedUserScope2 = normalizeUserScope(nextItem.options.user_scope);
|
|
18913
|
+
if (normalizedUserScope2.changed) {
|
|
18914
|
+
nextItem = {
|
|
18915
|
+
...nextItem,
|
|
18916
|
+
options: {
|
|
18917
|
+
...nextItem.options,
|
|
18918
|
+
user_scope: normalizedUserScope2.value
|
|
18919
|
+
}
|
|
18920
|
+
};
|
|
18921
|
+
changed = true;
|
|
18922
|
+
}
|
|
18923
|
+
}
|
|
18924
|
+
return nextItem;
|
|
18925
|
+
});
|
|
18926
|
+
return changed ? { ...body, items } : body;
|
|
18927
|
+
}
|
|
18928
|
+
if (!isRecord3(body.options)) {
|
|
18929
|
+
return body;
|
|
18930
|
+
}
|
|
18931
|
+
const normalizedUserScope = normalizeUserScope(body.options.user_scope);
|
|
18932
|
+
if (!normalizedUserScope.changed) return body;
|
|
18933
|
+
return {
|
|
18934
|
+
...body,
|
|
18935
|
+
options: {
|
|
18936
|
+
...body.options,
|
|
18937
|
+
user_scope: normalizedUserScope.value
|
|
18938
|
+
}
|
|
18939
|
+
};
|
|
18940
|
+
}
|
|
18941
|
+
function validateAccessRulePolicyShape(scope, command, requestType, policy, env, pathPrefix) {
|
|
18942
|
+
const actions = policy && Array.isArray(policy.actions) ? policy.actions : [];
|
|
18943
|
+
if (actions.includes("read") || actions.includes("write")) {
|
|
18944
|
+
throwBodyValidationFailure(
|
|
18945
|
+
'access-rule policy.actions must use Arcubase action codes: use "view" for read and "add","edit" for write; do not use "read", "write", or "insert"',
|
|
18946
|
+
requestType,
|
|
18947
|
+
`${pathPrefix}.actions`,
|
|
18948
|
+
scope,
|
|
18949
|
+
command,
|
|
18950
|
+
env
|
|
18951
|
+
);
|
|
18952
|
+
}
|
|
18953
|
+
const fields = policy && Array.isArray(policy.fields) ? policy.fields : [];
|
|
18954
|
+
const allowedSystemFieldKeys = /* @__PURE__ */ new Set(["created", "updated", "creator"]);
|
|
18955
|
+
for (const [index, field] of fields.entries()) {
|
|
18956
|
+
if (!isRecord3(field)) continue;
|
|
18957
|
+
if (typeof field.key === "number" || typeof field.key === "string" && /^\d+$/.test(field.key)) {
|
|
18958
|
+
throwBodyValidationFailure(
|
|
18959
|
+
'access-rule policy.fields[].key must be a string prefixed with colon, for example ":1002"; do not use raw numbers',
|
|
18960
|
+
requestType,
|
|
18961
|
+
`${pathPrefix}.fields.${index}.key`,
|
|
18962
|
+
scope,
|
|
18963
|
+
command,
|
|
18964
|
+
env
|
|
18965
|
+
);
|
|
18966
|
+
}
|
|
18967
|
+
if (typeof field.key === "string" && !field.key.startsWith(":") && !allowedSystemFieldKeys.has(field.key)) {
|
|
18968
|
+
throwBodyValidationFailure(
|
|
18969
|
+
'access-rule policy.fields[].key must use Arcubase permission keys such as ":1002"; do not use FieldVO.key values such as "vote_name"',
|
|
18970
|
+
requestType,
|
|
18971
|
+
`${pathPrefix}.fields.${index}.key`,
|
|
18972
|
+
scope,
|
|
18973
|
+
command,
|
|
18974
|
+
env
|
|
18975
|
+
);
|
|
18976
|
+
}
|
|
18977
|
+
}
|
|
18978
|
+
}
|
|
18327
18979
|
function requireUpdateContains(scope, command, body, field, env) {
|
|
18328
18980
|
if (!(field in body)) return;
|
|
18329
18981
|
const update = stringArray(body.update);
|
|
@@ -18369,6 +19021,54 @@ function validateActionSpecificRawBody(scope, command, body, env) {
|
|
|
18369
19021
|
}
|
|
18370
19022
|
}
|
|
18371
19023
|
if (isAccessRuleCommand(scope, command)) {
|
|
19024
|
+
if (isAccessRuleBulkApplyCommand(scope, command)) {
|
|
19025
|
+
if (!Array.isArray(body.items) || body.items.length === 0) {
|
|
19026
|
+
throwBodyValidationFailure(
|
|
19027
|
+
"access-rule bulk-apply requires non-empty body.items; put every table/rule assignment in body.items",
|
|
19028
|
+
command.requestType,
|
|
19029
|
+
"body.items",
|
|
19030
|
+
scope,
|
|
19031
|
+
command,
|
|
19032
|
+
env
|
|
19033
|
+
);
|
|
19034
|
+
}
|
|
19035
|
+
if (body.mode !== void 0 && body.mode !== "update_existing" && body.mode !== "upsert_by_name") {
|
|
19036
|
+
throwBodyValidationFailure(
|
|
19037
|
+
'access-rule bulk-apply body.mode must be "update_existing" or "upsert_by_name"',
|
|
19038
|
+
command.requestType,
|
|
19039
|
+
"body.mode",
|
|
19040
|
+
scope,
|
|
19041
|
+
command,
|
|
19042
|
+
env
|
|
19043
|
+
);
|
|
19044
|
+
}
|
|
19045
|
+
for (const [index, item] of body.items.entries()) {
|
|
19046
|
+
if (!isRecord3(item)) {
|
|
19047
|
+
throwBodyValidationFailure(
|
|
19048
|
+
"access-rule bulk-apply body.items[] must be an object",
|
|
19049
|
+
command.requestType,
|
|
19050
|
+
`body.items.${index}`,
|
|
19051
|
+
scope,
|
|
19052
|
+
command,
|
|
19053
|
+
env
|
|
19054
|
+
);
|
|
19055
|
+
}
|
|
19056
|
+
const options2 = isRecord3(item.options) ? item.options : void 0;
|
|
19057
|
+
if (!options2) {
|
|
19058
|
+
throwBodyValidationFailure(
|
|
19059
|
+
"access-rule bulk-apply body.items[].options is required and must include the full canonical options object",
|
|
19060
|
+
command.requestType,
|
|
19061
|
+
`body.items.${index}.options`,
|
|
19062
|
+
scope,
|
|
19063
|
+
command,
|
|
19064
|
+
env
|
|
19065
|
+
);
|
|
19066
|
+
}
|
|
19067
|
+
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`);
|
|
19069
|
+
}
|
|
19070
|
+
return;
|
|
19071
|
+
}
|
|
18372
19072
|
const update = stringArray(body.update);
|
|
18373
19073
|
if (isAccessRuleUpdateCommand(scope, command) && update.some((item) => item.startsWith("options."))) {
|
|
18374
19074
|
throwBodyValidationFailure(
|
|
@@ -18413,42 +19113,7 @@ function validateActionSpecificRawBody(scope, command, body, env) {
|
|
|
18413
19113
|
);
|
|
18414
19114
|
}
|
|
18415
19115
|
validateAccessRuleUserScope(scope, command, command.requestType, options?.user_scope, env);
|
|
18416
|
-
|
|
18417
|
-
if (actions.includes("read") || actions.includes("write")) {
|
|
18418
|
-
throwBodyValidationFailure(
|
|
18419
|
-
'access-rule policy.actions must use Arcubase action codes: use "view" for read and "add","edit" for write; do not use "read", "write", or "insert"',
|
|
18420
|
-
command.requestType,
|
|
18421
|
-
"body.options.policy.actions",
|
|
18422
|
-
scope,
|
|
18423
|
-
command,
|
|
18424
|
-
env
|
|
18425
|
-
);
|
|
18426
|
-
}
|
|
18427
|
-
const fields = policy && Array.isArray(policy.fields) ? policy.fields : [];
|
|
18428
|
-
const allowedSystemFieldKeys = /* @__PURE__ */ new Set(["created", "updated", "creator"]);
|
|
18429
|
-
for (const [index, field] of fields.entries()) {
|
|
18430
|
-
if (!isRecord3(field)) continue;
|
|
18431
|
-
if (typeof field.key === "number" || typeof field.key === "string" && /^\d+$/.test(field.key)) {
|
|
18432
|
-
throwBodyValidationFailure(
|
|
18433
|
-
'access-rule policy.fields[].key must be a string prefixed with colon, for example ":1002"; do not use raw numbers',
|
|
18434
|
-
command.requestType,
|
|
18435
|
-
`body.options.policy.fields.${index}.key`,
|
|
18436
|
-
scope,
|
|
18437
|
-
command,
|
|
18438
|
-
env
|
|
18439
|
-
);
|
|
18440
|
-
}
|
|
18441
|
-
if (typeof field.key === "string" && !field.key.startsWith(":") && !allowedSystemFieldKeys.has(field.key)) {
|
|
18442
|
-
throwBodyValidationFailure(
|
|
18443
|
-
'access-rule policy.fields[].key must use Arcubase permission keys such as ":1002"; do not use FieldVO.key values such as "vote_name"',
|
|
18444
|
-
command.requestType,
|
|
18445
|
-
`body.options.policy.fields.${index}.key`,
|
|
18446
|
-
scope,
|
|
18447
|
-
command,
|
|
18448
|
-
env
|
|
18449
|
-
);
|
|
18450
|
-
}
|
|
18451
|
-
}
|
|
19116
|
+
validateAccessRulePolicyShape(scope, command, command.requestType, policy, env, "body.options.policy");
|
|
18452
19117
|
}
|
|
18453
19118
|
}
|
|
18454
19119
|
function validateActionSpecificBody(scope, command, flags, body, env) {
|
|
@@ -19124,16 +19789,32 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
|
19124
19789
|
const parsed = parseCLIArgs(argv);
|
|
19125
19790
|
const envInput = env ?? process.env;
|
|
19126
19791
|
if (parsed.commandTokens.length === 0) {
|
|
19792
|
+
if (hasFlag(parsed.flags, "help-examples")) {
|
|
19793
|
+
throwHelpExamplesRequiresCommand(scope);
|
|
19794
|
+
}
|
|
19127
19795
|
return { kind: "help", text: renderRootHelp(scope) };
|
|
19128
19796
|
}
|
|
19129
19797
|
const [moduleName, commandName] = parsed.commandTokens;
|
|
19130
19798
|
if (!moduleName) {
|
|
19799
|
+
if (hasFlag(parsed.flags, "help-examples")) {
|
|
19800
|
+
throwHelpExamplesRequiresCommand(scope);
|
|
19801
|
+
}
|
|
19131
19802
|
return { kind: "help", text: renderRootHelp(scope) };
|
|
19132
19803
|
}
|
|
19133
19804
|
const singleTokenCommand = !commandName ? findCommand(scope, moduleName) : null;
|
|
19134
19805
|
if (!commandName && !singleTokenCommand) {
|
|
19806
|
+
if (hasFlag(parsed.flags, "help-examples")) {
|
|
19807
|
+
throwHelpExamplesRequiresCommand(scope, moduleName);
|
|
19808
|
+
}
|
|
19135
19809
|
return { kind: "help", text: renderModuleHelp(scope, moduleName, envInput) };
|
|
19136
19810
|
}
|
|
19811
|
+
if (hasFlag(parsed.flags, "help-examples")) {
|
|
19812
|
+
const command2 = commandName ? findCommand(scope, moduleName, commandName) : singleTokenCommand;
|
|
19813
|
+
if (!command2) {
|
|
19814
|
+
throw new CLIError("UNKNOWN_COMMAND", `unknown command: ${moduleName}${commandName ? ` ${commandName}` : ""}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName ?? ""));
|
|
19815
|
+
}
|
|
19816
|
+
return { kind: "help", text: renderCommandHelpExamples(scope, command2) };
|
|
19817
|
+
}
|
|
19137
19818
|
if (hasFlag(parsed.flags, "help")) {
|
|
19138
19819
|
return { kind: "help", text: renderCommandHelp(scope, moduleName, commandName, envInput) };
|
|
19139
19820
|
}
|
|
@@ -19178,6 +19859,7 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
|
19178
19859
|
if (body === void 0) {
|
|
19179
19860
|
throw new CLIError("MISSING_BODY_FILE", `command requires --body-json or --body-file for ${command.requestType}; prefer --body-json to avoid file creation`, 2);
|
|
19180
19861
|
}
|
|
19862
|
+
body = normalizeNumericAccessRuleUserScopeIDs(scope, command, body);
|
|
19181
19863
|
if (isTableCreateCommand(scope, command)) {
|
|
19182
19864
|
requireTableCreateSchemaBody(scope, command, body, runtimeEnv);
|
|
19183
19865
|
validateActionSpecificRawBody(scope, command, body, runtimeEnv);
|