@carthooks/arcubase-cli 0.1.22 → 0.1.24
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 +158 -2
- package/bundle/arcubase.mjs +158 -2
- 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 +53 -0
- package/dist/generated/help_examples.generated.d.ts.map +1 -1
- package/dist/generated/help_examples.generated.js +89 -0
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +46 -0
- package/package.json +3 -3
- package/sdk-dist/docs/runtime-reference/dashboard.md +16 -1
- package/sdk-dist/docs/runtime-reference/help-examples/admin/dashboard/update-options.json +23 -0
- package/sdk-dist/docs/runtime-reference/help-examples/admin/widget/preview-data.json +24 -0
- package/sdk-dist/docs/runtime-reference/help-examples/admin/widget/update-ingress-options.json +21 -0
- package/sdk-dist/docs/runtime-reference/widgets.md +24 -0
- package/sdk-dist/generated/command_registry.generated.ts +21 -0
- package/sdk-dist/generated/help_examples.generated.ts +89 -0
- package/src/generated/command_registry.generated.ts +21 -0
- package/src/generated/help_examples.generated.ts +89 -0
- package/src/runtime/execute.ts +46 -0
- package/src/tests/command_registry.test.ts +2 -1
- package/src/tests/execute_validation.test.ts +97 -0
- package/src/tests/help.test.ts +27 -0
|
@@ -1095,6 +1095,16 @@ test('entry fixed app tables query cannot be disabled by query file', async () =
|
|
|
1095
1095
|
})
|
|
1096
1096
|
|
|
1097
1097
|
test('dashboard and widget commands map to approved endpoints', async () => {
|
|
1098
|
+
const userAppGet = await executeCLI(
|
|
1099
|
+
'user',
|
|
1100
|
+
['app', 'get', '--app-id', 'app_1'],
|
|
1101
|
+
env as any,
|
|
1102
|
+
async (url, init) => new Response(JSON.stringify({ url, method: init?.method }), { status: 200 }),
|
|
1103
|
+
)
|
|
1104
|
+
assert.equal(userAppGet.kind, 'result')
|
|
1105
|
+
assert.equal(userAppGet.data.url, 'https://arcubase.example.com/api/apps/app_1')
|
|
1106
|
+
assert.equal(userAppGet.data.method, 'GET')
|
|
1107
|
+
|
|
1098
1108
|
const adminWidgetList = await executeCLI(
|
|
1099
1109
|
'admin',
|
|
1100
1110
|
['widget', 'list', '--app-id', 'app_1', '--type', 'dashboard', '--dashboard-id', '100'],
|
|
@@ -1131,6 +1141,61 @@ test('dashboard and widget commands map to approved endpoints', async () => {
|
|
|
1131
1141
|
assert.deepEqual(userWidgetData.data.body, { dashboard_id: 100, type: 1 })
|
|
1132
1142
|
})
|
|
1133
1143
|
|
|
1144
|
+
test('widget create ingress mistakes suggest ingress widget shape before request', async () => {
|
|
1145
|
+
let called = false
|
|
1146
|
+
await assert.rejects(async () => {
|
|
1147
|
+
await executeCLI(
|
|
1148
|
+
'admin',
|
|
1149
|
+
['widget', 'create', '--app-id', 'app_1', '--body-json', '{"type":"list","options":{"entity_id":2188891001}}'],
|
|
1150
|
+
env as any,
|
|
1151
|
+
async () => {
|
|
1152
|
+
called = true
|
|
1153
|
+
return new Response('{}', { status: 200 })
|
|
1154
|
+
},
|
|
1155
|
+
)
|
|
1156
|
+
}, (error: unknown) => {
|
|
1157
|
+
assert.ok(error instanceof CLIError)
|
|
1158
|
+
assert.equal(error.code, 'BODY_VALIDATION_FAILED')
|
|
1159
|
+
assert.equal(error.details?.requestType, 'AppNewWidgetsReqVO')
|
|
1160
|
+
assert.ok((error.details?.commonMistakes ?? []).includes('ingress widgets use options.ingress_id'))
|
|
1161
|
+
assert.ok((error.details?.commonMistakes ?? []).includes('after creating an ingress widget, use widget update-ingress-options to adjust display configuration'))
|
|
1162
|
+
return true
|
|
1163
|
+
})
|
|
1164
|
+
assert.equal(called, false)
|
|
1165
|
+
})
|
|
1166
|
+
|
|
1167
|
+
test('widget update ingress list options points to update-ingress-options before request', async () => {
|
|
1168
|
+
let called = false
|
|
1169
|
+
await assert.rejects(async () => {
|
|
1170
|
+
await executeCLI(
|
|
1171
|
+
'admin',
|
|
1172
|
+
[
|
|
1173
|
+
'widget',
|
|
1174
|
+
'update',
|
|
1175
|
+
'--app-id',
|
|
1176
|
+
'app_1',
|
|
1177
|
+
'--widget-id',
|
|
1178
|
+
'widget_1',
|
|
1179
|
+
'--body-json',
|
|
1180
|
+
'{"ingress_id":2188893001,"options":{"list":{"default_cols":[1001,1002],"page_size":10}}}',
|
|
1181
|
+
],
|
|
1182
|
+
env as any,
|
|
1183
|
+
async () => {
|
|
1184
|
+
called = true
|
|
1185
|
+
return new Response('{}', { status: 200 })
|
|
1186
|
+
},
|
|
1187
|
+
)
|
|
1188
|
+
}, (error: unknown) => {
|
|
1189
|
+
assert.ok(error instanceof CLIError)
|
|
1190
|
+
assert.equal(error.code, 'BODY_VALIDATION_FAILED')
|
|
1191
|
+
assert.equal(error.details?.requestType, 'AppUpdateWidgetsReqVO')
|
|
1192
|
+
assert.ok((error.details?.commonMistakes ?? []).includes('ingress/list display settings use widget update-ingress-options, not widget update'))
|
|
1193
|
+
assert.ok((error.details?.suggestions ?? []).some((item) => item.includes('widget update-ingress-options')))
|
|
1194
|
+
return true
|
|
1195
|
+
})
|
|
1196
|
+
assert.equal(called, false)
|
|
1197
|
+
})
|
|
1198
|
+
|
|
1134
1199
|
test('widget preview-data rejects unsupported aggregate before request', async () => {
|
|
1135
1200
|
let called = false
|
|
1136
1201
|
await assert.rejects(async () => {
|
|
@@ -1191,6 +1256,38 @@ test('widget preview-data rejects field dimensions without IsField true before r
|
|
|
1191
1256
|
assert.equal(called, false)
|
|
1192
1257
|
})
|
|
1193
1258
|
|
|
1259
|
+
test('widget preview-data filter mistakes suggest chart conditions before request', async () => {
|
|
1260
|
+
let called = false
|
|
1261
|
+
await assert.rejects(async () => {
|
|
1262
|
+
await executeCLI(
|
|
1263
|
+
'admin',
|
|
1264
|
+
[
|
|
1265
|
+
'widget',
|
|
1266
|
+
'preview-data',
|
|
1267
|
+
'--app-id',
|
|
1268
|
+
'app_1',
|
|
1269
|
+
'--body-json',
|
|
1270
|
+
'{"dataSource":2188891001,"dataSourceType":"entity","dimensions":[{"IsField":true,"FieldID":1004,"Name":"Source"}],"filters":[{"FieldID":1006,"Operator":"$eq","Value":"yes"}],"measures":[{"Name":"Distinct Customers","FieldID":1002,"Aggregate":"distinct_count"}]}',
|
|
1271
|
+
],
|
|
1272
|
+
env as any,
|
|
1273
|
+
async () => {
|
|
1274
|
+
called = true
|
|
1275
|
+
return new Response('{}', { status: 200 })
|
|
1276
|
+
},
|
|
1277
|
+
)
|
|
1278
|
+
}, (error: unknown) => {
|
|
1279
|
+
assert.ok(error instanceof CLIError)
|
|
1280
|
+
assert.equal(error.code, 'BODY_VALIDATION_FAILED')
|
|
1281
|
+
assert.equal(error.details?.requestType, 'AppPreviewWidgetsDataReqVO')
|
|
1282
|
+
assert.ok((error.details?.issues ?? []).some((item) => item.path === 'body'))
|
|
1283
|
+
assert.ok((error.details?.commonMistakes ?? []).includes('use conditions, not filters, for chart data filtering'))
|
|
1284
|
+
assert.ok((error.details?.commonMistakes ?? []).includes('do not retry without conditions and then hand-calculate filtered statistics'))
|
|
1285
|
+
assert.ok((error.details?.suggestions ?? []).some((item) => item.includes('"conditions":{"mode":"and","conditions":[{"column":":1006","operator":"$eq","value":"yes"}]}')))
|
|
1286
|
+
return true
|
|
1287
|
+
})
|
|
1288
|
+
assert.equal(called, false)
|
|
1289
|
+
})
|
|
1290
|
+
|
|
1194
1291
|
test('widget update rejects chart field dimensions without IsField true before request', async () => {
|
|
1195
1292
|
let called = false
|
|
1196
1293
|
await assert.rejects(async () => {
|
package/src/tests/help.test.ts
CHANGED
|
@@ -136,6 +136,12 @@ test('dashboard and widget help exposes agent-readable body docs and flags', asy
|
|
|
136
136
|
assert.match(userWidgetData.text, /body: FetchWidgetsDataReqVO via --body-json/)
|
|
137
137
|
assert.match(userWidgetData.text, /^types:$/m)
|
|
138
138
|
assert.match(userWidgetData.text, /^docs:$/m)
|
|
139
|
+
|
|
140
|
+
const userAppGet = await executeCLI('user', ['app', 'get', '--help'], env as any, async () => new Response('{}'))
|
|
141
|
+
assert.equal(userAppGet.kind, 'help')
|
|
142
|
+
assert.match(userAppGet.text, /arcubase app get/)
|
|
143
|
+
assert.match(userAppGet.text, /endpoint: \/apps\/:id/)
|
|
144
|
+
assert.match(userAppGet.text, /path flags: --app-id/)
|
|
139
145
|
})
|
|
140
146
|
|
|
141
147
|
test('admin access-rule help gives update whitelist and assign-users body-json examples', async () => {
|
|
@@ -214,6 +220,17 @@ test('admin dashboard update-layout help-examples show top-level layout array',
|
|
|
214
220
|
assert.match(out.text, /do not wrap the array/)
|
|
215
221
|
})
|
|
216
222
|
|
|
223
|
+
test('admin dashboard update-options help-examples show user visibility scope', async () => {
|
|
224
|
+
const out = await executeCLI('admin', ['dashboard', 'update-options', '--help-examples'], env as any, async () => new Response('{}'))
|
|
225
|
+
assert.equal(out.kind, 'help')
|
|
226
|
+
assert.match(out.text, /arcubase-admin dashboard update-options --help-examples/)
|
|
227
|
+
assert.match(out.text, /"changed":\["users"\]/)
|
|
228
|
+
assert.match(out.text, /"users":\[\{"type":"user","id":2188889901\}\]/)
|
|
229
|
+
assert.match(out.text, /currentSpeaker\.arcubaseUserId/)
|
|
230
|
+
assert.match(out.text, /verify from the user side with arcubase app get/)
|
|
231
|
+
assert.doesNotMatch(out.text, /"type":"member"/)
|
|
232
|
+
})
|
|
233
|
+
|
|
217
234
|
test('admin widget preview-data help-examples show chart query body without widget id', async () => {
|
|
218
235
|
const out = await executeCLI('admin', ['widget', 'preview-data', '--help-examples'], env as any, async () => new Response('{}'))
|
|
219
236
|
assert.equal(out.kind, 'help')
|
|
@@ -221,6 +238,8 @@ test('admin widget preview-data help-examples show chart query body without widg
|
|
|
221
238
|
assert.match(out.text, /"dataSource":2188891001/)
|
|
222
239
|
assert.match(out.text, /"dataSourceType":"entity"/)
|
|
223
240
|
assert.match(out.text, /"Aggregate":"sum"/)
|
|
241
|
+
assert.match(out.text, /"conditions":\{"mode":"and","conditions":\[\{"column":":1006","operator":"\$eq","value":"yes"\}\]\}/)
|
|
242
|
+
assert.match(out.text, /use conditions, not filters/)
|
|
224
243
|
assert.match(out.text, /preview-data does not accept --widget-id/)
|
|
225
244
|
assert.match(out.text, /do not send widget_id or id/)
|
|
226
245
|
assert.doesNotMatch(out.text, /--widget-id <widget_id>/)
|
|
@@ -236,6 +255,14 @@ test('admin widget create help-examples avoid manual options type', async () =>
|
|
|
236
255
|
assert.doesNotMatch(out.text, /"options":\{"dashboard_id":2188892001,"type":/)
|
|
237
256
|
})
|
|
238
257
|
|
|
258
|
+
test('admin widget update-ingress-options help-examples show ingress display body', async () => {
|
|
259
|
+
const out = await executeCLI('admin', ['widget', 'update-ingress-options', '--help-examples'], env as any, async () => new Response('{}'))
|
|
260
|
+
assert.equal(out.kind, 'help')
|
|
261
|
+
assert.match(out.text, /arcubase-admin widget update-ingress-options --help-examples/)
|
|
262
|
+
assert.match(out.text, /"cond_follow":true/)
|
|
263
|
+
assert.match(out.text, /verify with widget get/)
|
|
264
|
+
})
|
|
265
|
+
|
|
239
266
|
test('user row bulk-update help-examples show ids and condition selection bodies', async () => {
|
|
240
267
|
const out = await executeCLI('user', ['row', 'bulk-update', '--help-examples'], env as any, async () => new Response('{}'))
|
|
241
268
|
assert.equal(out.kind, 'help')
|