@carthooks/arcubase-cli 0.1.4 → 0.1.5
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 +188 -210
- package/bundle/arcubase.mjs +188 -210
- package/dist/generated/command_registry.generated.d.ts +36 -112
- package/dist/generated/command_registry.generated.d.ts.map +1 -1
- package/dist/generated/command_registry.generated.js +40 -163
- package/dist/generated/type_index.generated.d.ts +0 -12
- package/dist/generated/type_index.generated.d.ts.map +1 -1
- package/dist/generated/type_index.generated.js +0 -12
- package/dist/generated/zod_registry.generated.d.ts +1 -19
- package/dist/generated/zod_registry.generated.d.ts.map +1 -1
- package/dist/generated/zod_registry.generated.js +0 -21
- package/dist/runtime/command_registry.d.ts +19 -1
- package/dist/runtime/command_registry.d.ts.map +1 -1
- package/dist/runtime/command_registry.js +19 -1
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +119 -9
- package/dist/runtime/zod_registry.d.ts.map +1 -1
- package/dist/runtime/zod_registry.js +24 -7
- package/dist/tests/command_registry.test.js +11 -4
- package/dist/tests/execute_validation.test.js +72 -17
- package/dist/tests/help.test.js +16 -9
- package/package.json +1 -1
- package/sdk-dist/api/admin/app.ts +8 -1
- package/sdk-dist/docs/runtime-reference/README.md +24 -16
- package/sdk-dist/docs/runtime-reference/app-discovery.md +68 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/README.md +2 -2
- package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +2 -2
- package/sdk-dist/docs/runtime-reference/entity-schema.md +2 -2
- package/sdk-dist/docs/runtime-reference/examples/README.md +1 -1
- package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +4 -4
- package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +1 -1
- package/sdk-dist/docs/runtime-reference/row-crud.md +6 -6
- package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +5 -5
- package/sdk-dist/docs/runtime-reference/table-lifecycle.md +24 -8
- package/sdk-dist/docs/runtime-reference/uploads.md +1 -1
- package/sdk-dist/generated/command_registry.generated.ts +40 -163
- package/sdk-dist/generated/type_index.generated.ts +0 -12
- package/sdk-dist/generated/zod_registry.generated.ts +0 -36
- package/sdk-dist/types/app.ts +7 -0
- package/src/generated/command_registry.generated.ts +40 -163
- package/src/generated/type_index.generated.ts +0 -12
- package/src/generated/zod_registry.generated.ts +0 -36
- package/src/runtime/command_registry.ts +38 -2
- package/src/runtime/execute.ts +127 -9
- package/src/runtime/zod_registry.ts +25 -7
- package/src/tests/command_registry.test.ts +13 -4
- package/src/tests/execute_validation.test.ts +78 -17
- package/src/tests/help.test.ts +17 -9
- package/sdk-dist/docs/runtime-reference/workflow/README.md +0 -19
|
@@ -67,12 +67,19 @@ const examplesIndexDocHint: RuntimeDocHint = {
|
|
|
67
67
|
file: '/opt/arcubase-sdk/docs/runtime-reference/examples/README.md',
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
const appDiscoveryDocHint: RuntimeDocHint = {
|
|
71
|
+
title: 'App discovery',
|
|
72
|
+
file: '/opt/arcubase-sdk/docs/runtime-reference/app-discovery.md',
|
|
73
|
+
}
|
|
74
|
+
|
|
70
75
|
const docHintIndex: Record<string, RuntimeDocHint[]> = {
|
|
71
76
|
AppCreateByTenantsReqVO: [
|
|
77
|
+
appDiscoveryDocHint,
|
|
72
78
|
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
73
79
|
examplesIndexDocHint,
|
|
74
80
|
],
|
|
75
81
|
AppCreateEntityReqVO: [
|
|
82
|
+
appDiscoveryDocHint,
|
|
76
83
|
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
77
84
|
examplesIndexDocHint,
|
|
78
85
|
],
|
|
@@ -148,14 +155,25 @@ export function getDocHints(typeName: string): RuntimeDocHint[] {
|
|
|
148
155
|
|
|
149
156
|
const commandDocHintIndex: Record<string, RuntimeDocHint[]> = {
|
|
150
157
|
'admin.app.createAppByTenants': [
|
|
158
|
+
appDiscoveryDocHint,
|
|
151
159
|
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
152
160
|
examplesIndexDocHint,
|
|
153
161
|
],
|
|
162
|
+
'admin.app.listApps': [
|
|
163
|
+
appDiscoveryDocHint,
|
|
164
|
+
examplesIndexDocHint,
|
|
165
|
+
],
|
|
166
|
+
'admin.app.inventory': [
|
|
167
|
+
appDiscoveryDocHint,
|
|
168
|
+
examplesIndexDocHint,
|
|
169
|
+
],
|
|
154
170
|
'admin.app.createEntity': [
|
|
171
|
+
appDiscoveryDocHint,
|
|
155
172
|
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
156
173
|
examplesIndexDocHint,
|
|
157
174
|
],
|
|
158
175
|
'admin.entity.adminGetEntityInfo': [
|
|
176
|
+
appDiscoveryDocHint,
|
|
159
177
|
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
160
178
|
examplesIndexDocHint,
|
|
161
179
|
],
|
|
@@ -165,34 +183,34 @@ const commandDocHintIndex: Record<string, RuntimeDocHint[]> = {
|
|
|
165
183
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
166
184
|
examplesIndexDocHint,
|
|
167
185
|
],
|
|
168
|
-
'user.
|
|
186
|
+
'user.rows.insertEntity': [
|
|
169
187
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
170
188
|
{ title: 'Uploads', file: '/opt/arcubase-sdk/docs/runtime-reference/uploads.md' },
|
|
171
189
|
examplesIndexDocHint,
|
|
172
190
|
],
|
|
173
|
-
'user.
|
|
191
|
+
'user.rows.queryEntity': [
|
|
174
192
|
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
175
193
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
176
194
|
examplesIndexDocHint,
|
|
177
195
|
],
|
|
178
|
-
'user.
|
|
196
|
+
'user.rows.getEntityRow': [
|
|
179
197
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
180
198
|
examplesIndexDocHint,
|
|
181
199
|
],
|
|
182
|
-
'user.
|
|
200
|
+
'user.rows.updateEntityRow': [
|
|
183
201
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
184
202
|
{ title: 'Uploads', file: '/opt/arcubase-sdk/docs/runtime-reference/uploads.md' },
|
|
185
203
|
examplesIndexDocHint,
|
|
186
204
|
],
|
|
187
|
-
'user.
|
|
205
|
+
'user.rows.queryEntitySelection': [
|
|
188
206
|
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
189
207
|
examplesIndexDocHint,
|
|
190
208
|
],
|
|
191
|
-
'user.
|
|
209
|
+
'user.rows.deleteEntityRow': [
|
|
192
210
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
193
211
|
examplesIndexDocHint,
|
|
194
212
|
],
|
|
195
|
-
'user.
|
|
213
|
+
'user.rows.restoreEntityRow': [
|
|
196
214
|
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
197
215
|
examplesIndexDocHint,
|
|
198
216
|
],
|
|
@@ -8,8 +8,17 @@ test('admin app create-entity command exists', () => {
|
|
|
8
8
|
assert.ok(adminCommands.some((c) => c.commandPath.join(' ') === 'app create-entity'))
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
-
test('
|
|
12
|
-
assert.ok(
|
|
11
|
+
test('admin app list-apps command exists', () => {
|
|
12
|
+
assert.ok(adminCommands.some((c) => c.commandPath.join(' ') === 'app list-apps'))
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('admin app inventory command exists', () => {
|
|
16
|
+
const suggestions = findCommandSuggestions('app', 'inventory', 20)
|
|
17
|
+
assert.ok(suggestions.some((item) => item.binary === 'arcubase-admin' && item.moduleName === 'app' && item.commandName === 'inventory'))
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('user rows query-entity command exists', () => {
|
|
21
|
+
assert.ok(userCommands.some((c) => c.commandPath.join(' ') === 'rows query-entity'))
|
|
13
22
|
})
|
|
14
23
|
|
|
15
24
|
test('inline request type keeps full object text instead of truncated brace', () => {
|
|
@@ -27,7 +36,7 @@ test('tag commands no longer emit truncated inline request type', () => {
|
|
|
27
36
|
assert.equal(typed.scalarParams.length, 0)
|
|
28
37
|
})
|
|
29
38
|
|
|
30
|
-
test('suggestions can point wrong admin delete guess to user
|
|
39
|
+
test('suggestions can point wrong admin delete guess to user rows delete command', () => {
|
|
31
40
|
const suggestions = findCommandSuggestions('entity', 'admin-delete-entity-row')
|
|
32
|
-
assert.ok(suggestions.some((item) => item.binary === 'arcubase' && item.moduleName === '
|
|
41
|
+
assert.ok(suggestions.some((item) => item.binary === 'arcubase' && item.moduleName === 'rows' && item.commandName === 'delete-entity-row'))
|
|
33
42
|
})
|
|
@@ -82,6 +82,67 @@ test('admin api-prefixed command executes against external root path', async ()
|
|
|
82
82
|
assert.equal(out.data.url, 'https://arcubase.example.com/apps/app_1/entity-shares')
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
+
test('app inventory returns apps with entity lists', async () => {
|
|
86
|
+
const calls: string[] = []
|
|
87
|
+
const out = await executeCLI(
|
|
88
|
+
'admin',
|
|
89
|
+
['app', 'inventory'],
|
|
90
|
+
env as any,
|
|
91
|
+
async (url, init) => {
|
|
92
|
+
calls.push(`${init?.method ?? 'GET'} ${String(url)}`)
|
|
93
|
+
if (String(url) === 'https://arcubase.example.com/apps') {
|
|
94
|
+
return new Response(JSON.stringify({
|
|
95
|
+
data: [
|
|
96
|
+
{ id: 101, name: 'Workspace' },
|
|
97
|
+
{ id: 102, name: 'CRM' },
|
|
98
|
+
],
|
|
99
|
+
}), { status: 200 })
|
|
100
|
+
}
|
|
101
|
+
if (String(url) === 'https://arcubase.example.com/apps/101/entities') {
|
|
102
|
+
return new Response(JSON.stringify({
|
|
103
|
+
data: [
|
|
104
|
+
{ id: 201, name: 'Orders' },
|
|
105
|
+
{ id: 202, name: 'Customers' },
|
|
106
|
+
],
|
|
107
|
+
}), { status: 200 })
|
|
108
|
+
}
|
|
109
|
+
if (String(url) === 'https://arcubase.example.com/apps/102/entities') {
|
|
110
|
+
return new Response(JSON.stringify({
|
|
111
|
+
data: [
|
|
112
|
+
{ id: 203, name: 'Leads' },
|
|
113
|
+
],
|
|
114
|
+
}), { status: 200 })
|
|
115
|
+
}
|
|
116
|
+
return new Response('{}', { status: 404 })
|
|
117
|
+
},
|
|
118
|
+
)
|
|
119
|
+
assert.equal(out.kind, 'result')
|
|
120
|
+
assert.deepEqual(out.data, {
|
|
121
|
+
apps: [
|
|
122
|
+
{
|
|
123
|
+
id: '101',
|
|
124
|
+
name: 'Workspace',
|
|
125
|
+
entities: [
|
|
126
|
+
{ id: '201', name: 'Orders' },
|
|
127
|
+
{ id: '202', name: 'Customers' },
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: '102',
|
|
132
|
+
name: 'CRM',
|
|
133
|
+
entities: [
|
|
134
|
+
{ id: '203', name: 'Leads' },
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
})
|
|
139
|
+
assert.deepEqual(calls, [
|
|
140
|
+
'GET https://arcubase.example.com/apps',
|
|
141
|
+
'POST https://arcubase.example.com/apps/101/entities',
|
|
142
|
+
'POST https://arcubase.example.com/apps/102/entities',
|
|
143
|
+
])
|
|
144
|
+
})
|
|
145
|
+
|
|
85
146
|
test('admin save entity treats top-level error body as failure even on http 200', async () => {
|
|
86
147
|
const bodyFile = tempJSONFile({
|
|
87
148
|
id: 2188889845,
|
|
@@ -224,7 +285,7 @@ test('delete entity row rejects selection type outside ids', async () => {
|
|
|
224
285
|
await assert.rejects(async () => {
|
|
225
286
|
await executeCLI(
|
|
226
287
|
'user',
|
|
227
|
-
['
|
|
288
|
+
['rows', 'delete-entity-row', '--app-id', 'app_1', '--entity-id', 'entity_1', '--body-file', bodyFile],
|
|
228
289
|
env as any,
|
|
229
290
|
async () => new Response('{}', { status: 200 }),
|
|
230
291
|
)
|
|
@@ -283,7 +344,7 @@ test('selection action accepts condition selection with selectAll', async () =>
|
|
|
283
344
|
|
|
284
345
|
const out = await executeCLI(
|
|
285
346
|
'user',
|
|
286
|
-
['
|
|
347
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
287
348
|
env as any,
|
|
288
349
|
async (_url, init) => new Response(String(init?.body ?? '{}'), { status: 200 }),
|
|
289
350
|
)
|
|
@@ -306,7 +367,7 @@ test('selection action accepts condition selection with filter_* keys', async ()
|
|
|
306
367
|
|
|
307
368
|
const out = await executeCLI(
|
|
308
369
|
'user',
|
|
309
|
-
['
|
|
370
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
310
371
|
env as any,
|
|
311
372
|
async (_url, init) => new Response(String(init?.body ?? '{}'), { status: 200 }),
|
|
312
373
|
)
|
|
@@ -328,7 +389,7 @@ test('selection action accepts condition selection with selectAll only for batch
|
|
|
328
389
|
|
|
329
390
|
const out = await executeCLI(
|
|
330
391
|
'user',
|
|
331
|
-
['
|
|
392
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'batch_print', '--body-file', bodyFile],
|
|
332
393
|
env as any,
|
|
333
394
|
async (_url, init) => new Response(String(init?.body ?? '{}'), { status: 200 }),
|
|
334
395
|
)
|
|
@@ -346,7 +407,7 @@ test('selection action accepts all selection for query-style actions', async ()
|
|
|
346
407
|
|
|
347
408
|
const out = await executeCLI(
|
|
348
409
|
'user',
|
|
349
|
-
['
|
|
410
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'query', '--body-file', bodyFile],
|
|
350
411
|
env as any,
|
|
351
412
|
async (_url, init) => new Response(String(init?.body ?? '{}'), { status: 200 }),
|
|
352
413
|
)
|
|
@@ -369,7 +430,7 @@ test('selection action rejects condition selection for query action', async () =
|
|
|
369
430
|
await assert.rejects(async () => {
|
|
370
431
|
await executeCLI(
|
|
371
432
|
'user',
|
|
372
|
-
['
|
|
433
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'query', '--body-file', bodyFile],
|
|
373
434
|
env as any,
|
|
374
435
|
async () => new Response('{}', { status: 200 }),
|
|
375
436
|
)
|
|
@@ -391,7 +452,7 @@ test('selection action rejects all selection for archive action', async () => {
|
|
|
391
452
|
await assert.rejects(async () => {
|
|
392
453
|
await executeCLI(
|
|
393
454
|
'user',
|
|
394
|
-
['
|
|
455
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
395
456
|
env as any,
|
|
396
457
|
async () => new Response('{}', { status: 200 }),
|
|
397
458
|
)
|
|
@@ -417,7 +478,7 @@ test('selection action rejects selectAll-only condition for archive action', asy
|
|
|
417
478
|
await assert.rejects(async () => {
|
|
418
479
|
await executeCLI(
|
|
419
480
|
'user',
|
|
420
|
-
['
|
|
481
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
421
482
|
env as any,
|
|
422
483
|
async () => new Response('{}', { status: 200 }),
|
|
423
484
|
)
|
|
@@ -441,7 +502,7 @@ test('insert entity rejects local file path for file field and points to arcubas
|
|
|
441
502
|
await assert.rejects(async () => {
|
|
442
503
|
await executeCLI(
|
|
443
504
|
'user',
|
|
444
|
-
['
|
|
505
|
+
['rows', 'insert-entity', '--app-id', 'app_1', '--entity-id', 'entity_1', '--body-file', bodyFile],
|
|
445
506
|
env as any,
|
|
446
507
|
async (url, init) => {
|
|
447
508
|
calls.push({ url: String(url), method: init?.method })
|
|
@@ -490,7 +551,7 @@ test('update row rejects object value for image field and requires upload array'
|
|
|
490
551
|
await assert.rejects(async () => {
|
|
491
552
|
await executeCLI(
|
|
492
553
|
'user',
|
|
493
|
-
['
|
|
554
|
+
['rows', 'update-entity-row', '--app-id', 'app_1', '--entity-id', 'entity_1', '--row-id', 'row_1', '--body-file', bodyFile],
|
|
494
555
|
env as any,
|
|
495
556
|
async (url, init) => {
|
|
496
557
|
if (String(url) === 'https://arcubase.example.com/entity/app_1/entity_1' && init?.method === 'GET') {
|
|
@@ -535,7 +596,7 @@ test('insert entity accepts upload array for file field after schema preflight',
|
|
|
535
596
|
|
|
536
597
|
const out = await executeCLI(
|
|
537
598
|
'user',
|
|
538
|
-
['
|
|
599
|
+
['rows', 'insert-entity', '--app-id', 'app_1', '--entity-id', 'entity_1', '--body-file', bodyFile],
|
|
539
600
|
env as any,
|
|
540
601
|
async (url, init) => {
|
|
541
602
|
calls.push({ url: String(url), method: init?.method })
|
|
@@ -581,7 +642,7 @@ test('insert entity decorates upload bind failures with actionable guidance', as
|
|
|
581
642
|
await assert.rejects(async () => {
|
|
582
643
|
await executeCLI(
|
|
583
644
|
'user',
|
|
584
|
-
['
|
|
645
|
+
['rows', 'insert-entity', '--app-id', 'app_1', '--entity-id', 'entity_1', '--body-file', bodyFile],
|
|
585
646
|
env as any,
|
|
586
647
|
async (url, init) => {
|
|
587
648
|
if (String(url) === 'https://arcubase.example.com/entity/app_1/entity_1' && init?.method === 'GET') {
|
|
@@ -626,7 +687,7 @@ test('selection action rejects condition selection without selectAll', async ()
|
|
|
626
687
|
await assert.rejects(async () => {
|
|
627
688
|
await executeCLI(
|
|
628
689
|
'user',
|
|
629
|
-
['
|
|
690
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
630
691
|
env as any,
|
|
631
692
|
async () => new Response('{}', { status: 200 }),
|
|
632
693
|
)
|
|
@@ -653,7 +714,7 @@ test('selection action rejects condition selection that uses text_search instead
|
|
|
653
714
|
await assert.rejects(async () => {
|
|
654
715
|
await executeCLI(
|
|
655
716
|
'user',
|
|
656
|
-
['
|
|
717
|
+
['rows', 'query-entity-selection', '--app-id', 'app_1', '--entity-id', 'entity_1', '--action', 'archive', '--body-file', bodyFile],
|
|
657
718
|
env as any,
|
|
658
719
|
async () => new Response('{}', { status: 200 }),
|
|
659
720
|
)
|
|
@@ -780,7 +841,7 @@ test('query entity rejects camelCase viewMode and points to row crud doc', async
|
|
|
780
841
|
await assert.rejects(async () => {
|
|
781
842
|
await executeCLI(
|
|
782
843
|
'user',
|
|
783
|
-
['
|
|
844
|
+
['rows', 'query-entity', '--app-id', 'app_1', '--entity-id', 'entity_1', '--body-file', bodyFile],
|
|
784
845
|
env as any,
|
|
785
846
|
async () => new Response('{}', { status: 200 }),
|
|
786
847
|
)
|
|
@@ -807,7 +868,7 @@ test('update entity row rejects fields key', async () => {
|
|
|
807
868
|
await assert.rejects(async () => {
|
|
808
869
|
await executeCLI(
|
|
809
870
|
'user',
|
|
810
|
-
['
|
|
871
|
+
['rows', 'update-entity-row', '--app-id', 'app_1', '--entity-id', 'entity_1', '--row-id', 'row_1', '--body-file', bodyFile],
|
|
811
872
|
env as any,
|
|
812
873
|
async () => new Response('{}', { status: 200 }),
|
|
813
874
|
)
|
|
@@ -831,7 +892,7 @@ test('update entity row rejects changed_fields that are missing from data', asyn
|
|
|
831
892
|
await assert.rejects(async () => {
|
|
832
893
|
await executeCLI(
|
|
833
894
|
'user',
|
|
834
|
-
['
|
|
895
|
+
['rows', 'update-entity-row', '--app-id', 'app_1', '--entity-id', 'entity_1', '--row-id', 'row_1', '--body-file', bodyFile],
|
|
835
896
|
env as any,
|
|
836
897
|
async () => new Response('{}', { status: 200 }),
|
|
837
898
|
)
|
package/src/tests/help.test.ts
CHANGED
|
@@ -28,10 +28,11 @@ test('module help prints create-entity command', async () => {
|
|
|
28
28
|
const out = await executeCLI('admin', ['app', '--help'], env as any, async () => new Response('{}'))
|
|
29
29
|
assert.equal(out.kind, 'help')
|
|
30
30
|
assert.match(out.text, /create-entity/)
|
|
31
|
+
assert.match(out.text, /inventory/)
|
|
31
32
|
})
|
|
32
33
|
|
|
33
34
|
test('module help does not require runtime env', async () => {
|
|
34
|
-
const out = await executeCLI('user', ['
|
|
35
|
+
const out = await executeCLI('user', ['rows', '--help'], undefined, async () => new Response('{}'))
|
|
35
36
|
assert.equal(out.kind, 'help')
|
|
36
37
|
assert.match(out.text, /delete-entity-row/)
|
|
37
38
|
})
|
|
@@ -44,13 +45,13 @@ test('command help prints normalized external endpoint', async () => {
|
|
|
44
45
|
})
|
|
45
46
|
|
|
46
47
|
test('command help does not require runtime env', async () => {
|
|
47
|
-
const out = await executeCLI('user', ['
|
|
48
|
+
const out = await executeCLI('user', ['rows', 'delete-entity-row', '--help'], undefined, async () => new Response('{}'))
|
|
48
49
|
assert.equal(out.kind, 'help')
|
|
49
50
|
assert.match(out.text, /endpoint: \/entity\/:app_id\/:entity_id\/delete-item/)
|
|
50
51
|
})
|
|
51
52
|
|
|
52
53
|
test('command help prints runtime doc hints for request body commands', async () => {
|
|
53
|
-
const out = await executeCLI('user', ['
|
|
54
|
+
const out = await executeCLI('user', ['rows', 'update-entity-row', '--help'], undefined, async () => new Response('{}'))
|
|
54
55
|
assert.equal(out.kind, 'help')
|
|
55
56
|
assert.match(out.text, /docs:/)
|
|
56
57
|
assert.match(out.text, /\/opt\/arcubase-sdk\/docs\/runtime-reference\/row-crud\.md/)
|
|
@@ -58,7 +59,7 @@ test('command help prints runtime doc hints for request body commands', async ()
|
|
|
58
59
|
})
|
|
59
60
|
|
|
60
61
|
test('command help prints query-file support', async () => {
|
|
61
|
-
const out = await executeCLI('user', ['
|
|
62
|
+
const out = await executeCLI('user', ['rows', 'query-entity', '--help'], undefined, async () => new Response('{}'))
|
|
62
63
|
assert.equal(out.kind, 'help')
|
|
63
64
|
assert.match(out.text, /query flags: --query-file/)
|
|
64
65
|
})
|
|
@@ -70,12 +71,19 @@ test('command help without request body can still point to lifecycle and example
|
|
|
70
71
|
assert.match(out.text, /\/opt\/arcubase-sdk\/docs\/runtime-reference\/examples\/README\.md/)
|
|
71
72
|
})
|
|
72
73
|
|
|
74
|
+
test('app inventory help explains app discovery purpose', async () => {
|
|
75
|
+
const out = await executeCLI('admin', ['app', 'inventory', '--help'], undefined, async () => new Response('{}'))
|
|
76
|
+
assert.equal(out.kind, 'help')
|
|
77
|
+
assert.match(out.text, /list all accessible apps and each app entity list/)
|
|
78
|
+
assert.match(out.text, /use this before asking the user for app_id/)
|
|
79
|
+
})
|
|
80
|
+
|
|
73
81
|
test('admin-save-entity help prints row-operation next step', async () => {
|
|
74
82
|
const out = await executeCLI('admin', ['entity', 'admin-save-entity', '--help'], undefined, async () => new Response('{}'))
|
|
75
83
|
assert.equal(out.kind, 'help')
|
|
76
84
|
assert.match(out.text, /switch to arcubase for row operations/)
|
|
77
|
-
assert.match(out.text, /arcubase
|
|
78
|
-
assert.match(out.text, /arcubase
|
|
85
|
+
assert.match(out.text, /arcubase rows insert-entity/)
|
|
86
|
+
assert.match(out.text, /arcubase rows query-entity/)
|
|
79
87
|
})
|
|
80
88
|
|
|
81
89
|
test('wrong admin workflow command points to arcubase row command', async () => {
|
|
@@ -83,9 +91,9 @@ test('wrong admin workflow command points to arcubase row command', async () =>
|
|
|
83
91
|
() => executeCLI('admin', ['workflow', 'insert-entity'], env as any, async () => new Response('{}')),
|
|
84
92
|
(error: any) => {
|
|
85
93
|
assert.equal(error.code, 'UNKNOWN_COMMAND')
|
|
86
|
-
assert.equal(error.details?.reason, 'workflow insert-entity is a
|
|
87
|
-
assert.equal(error.details?.hint, 'use: arcubase
|
|
88
|
-
assert.ok((error.details?.suggestions ?? []).includes('arcubase
|
|
94
|
+
assert.equal(error.details?.reason, 'workflow insert-entity is not a valid command group; use arcubase rows for row operations')
|
|
95
|
+
assert.equal(error.details?.hint, 'use: arcubase rows insert-entity')
|
|
96
|
+
assert.ok((error.details?.suggestions ?? []).includes('arcubase rows insert-entity'))
|
|
89
97
|
return true
|
|
90
98
|
}
|
|
91
99
|
)
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Workflow Runtime Reference
|
|
2
|
-
|
|
3
|
-
This directory is reserved for future workflow runtime docs.
|
|
4
|
-
|
|
5
|
-
It will follow the same single-path distribution model as entity schema docs:
|
|
6
|
-
|
|
7
|
-
- Development source of truth:
|
|
8
|
-
- `misc/packages/@carthooks/arcubase-cli/docs/runtime-reference/workflow/`
|
|
9
|
-
- Runtime location:
|
|
10
|
-
- `/opt/arcubase-sdk/docs/runtime-reference/workflow/`
|
|
11
|
-
- Distribution path:
|
|
12
|
-
- `sdk-dist/docs/runtime-reference/workflow/`
|
|
13
|
-
|
|
14
|
-
Expected coverage later:
|
|
15
|
-
|
|
16
|
-
- workflow configuration lifecycle
|
|
17
|
-
- real writable structure for nodes, edges, actions, and conditions
|
|
18
|
-
- integration points between workflow and entity schema
|
|
19
|
-
- common failure cases and debugging guidance
|