@carthooks/arcubase-cli 0.1.7 → 0.1.9

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 (66) hide show
  1. package/bundle/arcubase-admin.mjs +1042 -5056
  2. package/bundle/arcubase.mjs +1042 -5056
  3. package/dist/generated/command_registry.generated.d.ts +693 -2812
  4. package/dist/generated/command_registry.generated.d.ts.map +1 -1
  5. package/dist/generated/command_registry.generated.js +812 -4100
  6. package/dist/generated/type_index.generated.d.ts +8 -397
  7. package/dist/generated/type_index.generated.d.ts.map +1 -1
  8. package/dist/generated/type_index.generated.js +8 -403
  9. package/dist/generated/zod_registry.generated.d.ts +33 -261
  10. package/dist/generated/zod_registry.generated.d.ts.map +1 -1
  11. package/dist/generated/zod_registry.generated.js +36 -365
  12. package/dist/runtime/body_loader.d.ts.map +1 -1
  13. package/dist/runtime/body_loader.js +12 -0
  14. package/dist/runtime/command_registry.d.ts +3 -21
  15. package/dist/runtime/command_registry.d.ts.map +1 -1
  16. package/dist/runtime/command_registry.js +17 -23
  17. package/dist/runtime/execute.d.ts +3 -3
  18. package/dist/runtime/execute.d.ts.map +1 -1
  19. package/dist/runtime/execute.js +53 -157
  20. package/dist/runtime/http.js +1 -1
  21. package/dist/runtime/upload.js +3 -3
  22. package/dist/runtime/zod_registry.d.ts.map +1 -1
  23. package/dist/runtime/zod_registry.js +7 -24
  24. package/dist/tests/command_registry.test.js +81 -28
  25. package/dist/tests/execute_validation.test.js +175 -510
  26. package/dist/tests/help.test.js +39 -62
  27. package/dist/tests/upload.test.js +4 -4
  28. package/dist/tests/zod_registry.test.js +0 -10
  29. package/package.json +1 -1
  30. package/sdk-dist/docs/runtime-reference/README.md +20 -30
  31. package/sdk-dist/docs/runtime-reference/entity-schema/README.md +4 -5
  32. package/sdk-dist/docs/runtime-reference/entity-schema/linkto.md +3 -3
  33. package/sdk-dist/docs/runtime-reference/entity-schema/query.md +3 -3
  34. package/sdk-dist/docs/runtime-reference/entity-schema/relation.md +3 -3
  35. package/sdk-dist/docs/runtime-reference/entity-schema/relationfield.md +3 -3
  36. package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +2 -2
  37. package/sdk-dist/docs/runtime-reference/entity-schema.md +4 -4
  38. package/sdk-dist/docs/runtime-reference/examples/README.md +2 -2
  39. package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +12 -12
  40. package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +1 -1
  41. package/sdk-dist/docs/runtime-reference/row-crud.md +11 -32
  42. package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +16 -47
  43. package/sdk-dist/docs/runtime-reference/table-lifecycle.md +11 -27
  44. package/sdk-dist/docs/runtime-reference/uploads.md +1 -1
  45. package/sdk-dist/docs/runtime-reference/workflow/README.md +19 -0
  46. package/sdk-dist/generated/command_registry.generated.ts +814 -4102
  47. package/sdk-dist/generated/type_index.generated.ts +8 -403
  48. package/sdk-dist/generated/zod_registry.generated.ts +44 -500
  49. package/sdk-dist/types/app.ts +3 -10
  50. package/sdk-dist/types/common.ts +7 -0
  51. package/sdk-dist/types/global-action.ts +2 -1
  52. package/src/generated/command_registry.generated.ts +814 -4102
  53. package/src/generated/type_index.generated.ts +8 -403
  54. package/src/generated/zod_registry.generated.ts +44 -500
  55. package/src/runtime/body_loader.ts +11 -0
  56. package/src/runtime/command_registry.ts +22 -44
  57. package/src/runtime/execute.ts +157 -165
  58. package/src/runtime/http.ts +1 -1
  59. package/src/runtime/upload.ts +3 -3
  60. package/src/runtime/zod_registry.ts +7 -25
  61. package/src/tests/command_registry.test.ts +81 -31
  62. package/src/tests/execute_validation.test.ts +236 -603
  63. package/src/tests/help.test.ts +47 -66
  64. package/src/tests/upload.test.ts +4 -4
  65. package/src/tests/zod_registry.test.ts +0 -13
  66. package/sdk-dist/docs/runtime-reference/app-discovery.md +0 -68
@@ -1,33 +1,15 @@
1
1
  import { adminCommands, userCommands } from '../generated/command_registry.generated.js';
2
2
  export { adminCommands, userCommands };
3
3
  export type CommandScope = 'admin' | 'user';
4
- type GeneratedCommandDef = (typeof adminCommands)[number] | (typeof userCommands)[number];
5
- type CustomCommandDef = {
6
- scope: CommandScope;
7
- module: string;
8
- functionName: string;
9
- commandPath: readonly [string, string];
10
- method: string;
11
- endpoint: string;
12
- endpointParams: readonly string[];
13
- controller: string;
14
- requestType: string | null;
15
- scalarParams: readonly {
16
- name: string;
17
- type: string;
18
- hasDefault: boolean;
19
- }[];
20
- responseType: string;
21
- };
22
- export type CommandDef = GeneratedCommandDef | CustomCommandDef;
4
+ export type CommandDef = (typeof adminCommands)[number] | (typeof userCommands)[number];
23
5
  export declare function listCommands(scope: CommandScope): readonly CommandDef[];
24
- export declare function findCommand(scope: CommandScope, moduleName: string, commandName: string): CommandDef | null;
6
+ export declare function findCommand(scope: CommandScope, moduleName: string, commandName?: string | null): CommandDef | null;
25
7
  export declare function listModules(scope: CommandScope): string[];
26
8
  export declare function listModuleCommands(scope: CommandScope, moduleName: string): readonly CommandDef[];
27
9
  export type CommandSuggestion = {
28
10
  scope: CommandScope;
29
11
  moduleName: string;
30
- commandName: string;
12
+ commandName: string | null;
31
13
  binary: 'arcubase-admin' | 'arcubase';
32
14
  score: number;
33
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"command_registry.d.ts","sourceRoot":"","sources":["../../src/runtime/command_registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAA;AAExF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA;AAEtC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAC3C,KAAK,mBAAmB,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzF,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC5E,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,mBAAmB,GAAG,gBAAgB,CAAA;AAoB/D,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,UAAU,EAAE,CAIvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAE3G;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE,CAEjG;AAmBD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,iBAAiB,EAAE,CAoB9G"}
1
+ {"version":3,"file":"command_registry.d.ts","sourceRoot":"","sources":["../../src/runtime/command_registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAA;AAExF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA;AAEtC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAC3C,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvF,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,UAAU,EAAE,CAEvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CAUnH;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE,CAEjG;AAmBD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,iBAAiB,EAAE,CA0B9G"}
@@ -1,28 +1,18 @@
1
1
  import { adminCommands, userCommands } from '../generated/command_registry.generated.js';
2
2
  export { adminCommands, userCommands };
3
- const customAdminCommands = [
4
- {
5
- scope: 'admin',
6
- module: 'app',
7
- functionName: 'inventory',
8
- commandPath: ['app', 'inventory'],
9
- method: 'GET',
10
- endpoint: '/apps',
11
- endpointParams: [],
12
- controller: 'Runtime.AppInventory',
13
- requestType: null,
14
- scalarParams: [],
15
- responseType: 'AppInventoryRespVO',
16
- },
17
- ];
18
- const customUserCommands = [];
19
3
  export function listCommands(scope) {
20
- return scope === 'admin'
21
- ? [...adminCommands, ...customAdminCommands]
22
- : [...userCommands, ...customUserCommands];
4
+ return scope === 'admin' ? adminCommands : userCommands;
23
5
  }
24
6
  export function findCommand(scope, moduleName, commandName) {
25
- return listCommands(scope).find((item) => item.commandPath[0] === moduleName && item.commandPath[1] === commandName) ?? null;
7
+ return listCommands(scope).find((item) => {
8
+ if (item.commandPath[0] !== moduleName) {
9
+ return false;
10
+ }
11
+ if (item.commandPath.length === 1) {
12
+ return !commandName;
13
+ }
14
+ return item.commandPath[1] === commandName;
15
+ }) ?? null;
26
16
  }
27
17
  export function listModules(scope) {
28
18
  return [...new Set(listCommands(scope).map((item) => item.commandPath[0]))].sort();
@@ -48,9 +38,10 @@ export function findCommandSuggestions(moduleName, commandName, limit = 3) {
48
38
  const suggestions = [];
49
39
  for (const scope of ['admin', 'user']) {
50
40
  for (const command of listCommands(scope)) {
51
- const [candidateModule, candidateCommand] = command.commandPath;
41
+ const candidateModule = command.commandPath[0];
42
+ const candidateCommand = command.commandPath.length > 1 ? command.commandPath[1] ?? null : null;
52
43
  const moduleScore = candidateModule === moduleName ? 0 : levenshtein(candidateModule, moduleName || '');
53
- const commandScore = candidateCommand === commandName ? 0 : levenshtein(candidateCommand, commandName || '');
44
+ const commandScore = candidateCommand === commandName ? 0 : levenshtein(candidateCommand ?? '', commandName || '');
54
45
  const score = commandScore * 3 + moduleScore;
55
46
  suggestions.push({
56
47
  scope,
@@ -62,6 +53,9 @@ export function findCommandSuggestions(moduleName, commandName, limit = 3) {
62
53
  }
63
54
  }
64
55
  return suggestions
65
- .sort((a, b) => a.score - b.score || a.binary.localeCompare(b.binary) || a.moduleName.localeCompare(b.moduleName) || a.commandName.localeCompare(b.commandName))
56
+ .sort((a, b) => a.score - b.score ||
57
+ a.binary.localeCompare(b.binary) ||
58
+ a.moduleName.localeCompare(b.moduleName) ||
59
+ (a.commandName ?? '').localeCompare(b.commandName ?? ''))
66
60
  .slice(0, limit);
67
61
  }
@@ -2,16 +2,16 @@ import { type RuntimeEnv } from './env.js';
2
2
  import { type CommandScope } from './command_registry.js';
3
3
  export type CommandExecutionSummary = {
4
4
  scope: CommandScope;
5
- commandPath: readonly [string, string];
5
+ commandPath: readonly string[];
6
6
  method: string;
7
7
  endpoint: string;
8
8
  requestType: string | null;
9
9
  pathFlags: readonly string[];
10
- scalarFlags: readonly string[];
10
+ queryFlags: readonly string[];
11
11
  };
12
12
  export declare function renderRootHelp(scope: CommandScope): string;
13
13
  export declare function renderModuleHelp(scope: CommandScope, moduleName: string): string;
14
- export declare function renderCommandHelp(scope: CommandScope, moduleName: string, commandName: string): string;
14
+ export declare function renderCommandHelp(scope: CommandScope, moduleName: string, commandName?: string): string;
15
15
  export declare function summarizeCommand(scope: CommandScope, moduleName: string, commandName: string): CommandExecutionSummary;
16
16
  export declare function executeCLI(scope: CommandScope, argv: string[], env?: RuntimeEnv, fetchImpl?: typeof fetch): Promise<any>;
17
17
  //# sourceMappingURL=execute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/runtime/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1D,OAAO,EAAwE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAK/H,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B,CAAA;AAwHD,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAa1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAehF;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAoCtG;AA8RD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,uBAAuB,CActH;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CA+JrI"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/runtime/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1D,OAAO,EAAwE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAK/H,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CAC9B,CAAA;AAYD,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAa1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAkBhF;AAOD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BvG;AAoSD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,uBAAuB,CActH;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAiKrI"}
@@ -9,115 +9,15 @@ import { renderUploadHelp, uploadLocalFile } from './upload.js';
9
9
  function summarizeUploadResult(value) {
10
10
  return value;
11
11
  }
12
- function parseJSONResponse(raw) {
13
- if (!raw)
14
- return null;
15
- try {
16
- return JSON.parse(raw);
17
- }
18
- catch {
19
- return raw;
20
- }
21
- }
22
- function unwrapResponseData(payload) {
23
- return isRecord(payload) && 'data' in payload ? payload.data : payload;
24
- }
25
- function formatUpstreamError(payload) {
26
- if (typeof payload === 'string') {
27
- return payload;
28
- }
29
- if (isRecord(payload) && isRecord(payload.error) && typeof payload.error.message === 'string') {
30
- return payload.error.message;
31
- }
32
- return JSON.stringify(payload);
33
- }
34
- function extractApps(payload) {
35
- const data = unwrapResponseData(payload);
36
- if (!Array.isArray(data))
37
- return [];
38
- return data
39
- .filter((item) => isRecord(item))
40
- .filter((item) => item.id !== undefined && typeof item.name === 'string')
41
- .map((item) => ({
42
- id: String(item.id),
43
- name: item.name,
44
- }));
45
- }
46
- function extractEntities(payload) {
47
- const data = unwrapResponseData(payload);
48
- if (!Array.isArray(data))
49
- return [];
50
- return data
51
- .filter((item) => isRecord(item))
52
- .filter((item) => item.id !== undefined && typeof item.name === 'string')
53
- .map((item) => ({
54
- id: String(item.id),
55
- name: item.name,
56
- }));
57
- }
58
- async function executeAppInventory(runtimeEnv, fetchImpl) {
59
- const appsResponse = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, '/apps'), {
60
- method: 'GET',
61
- headers: buildRequestHeaders(runtimeEnv),
62
- });
63
- const appsRaw = await appsResponse.text();
64
- const appsPayload = parseJSONResponse(appsRaw);
65
- if (!appsResponse.ok) {
66
- throw new CLIError('UPSTREAM_REQUEST_FAILED', formatUpstreamError(appsPayload), 1);
67
- }
68
- if (isRecord(appsPayload) && appsPayload.error) {
69
- throw new CLIError('UPSTREAM_BODY_ERROR', formatUpstreamError(appsPayload), 1, {
70
- endpoint: '/apps',
71
- method: 'GET',
72
- upstreamError: appsPayload.error,
73
- });
74
- }
75
- const apps = extractApps(appsPayload);
76
- const items = [];
77
- for (const app of apps) {
78
- const entitiesResponse = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, `/apps/${encodeURIComponent(app.id)}/entities`), {
79
- method: 'POST',
80
- headers: {
81
- ...buildRequestHeaders(runtimeEnv),
82
- 'Content-Type': 'application/json',
83
- },
84
- body: JSON.stringify({}),
85
- });
86
- const entitiesRaw = await entitiesResponse.text();
87
- const entitiesPayload = parseJSONResponse(entitiesRaw);
88
- if (!entitiesResponse.ok) {
89
- throw new CLIError('UPSTREAM_REQUEST_FAILED', formatUpstreamError(entitiesPayload), 1);
90
- }
91
- if (isRecord(entitiesPayload) && entitiesPayload.error) {
92
- throw new CLIError('UPSTREAM_BODY_ERROR', formatUpstreamError(entitiesPayload), 1, {
93
- endpoint: `/apps/${app.id}/entities`,
94
- method: 'POST',
95
- upstreamError: entitiesPayload.error,
96
- });
97
- }
98
- items.push({
99
- ...app,
100
- entities: extractEntities(entitiesPayload),
101
- });
102
- }
103
- return {
104
- kind: 'result',
105
- commandPath: ['app', 'inventory'],
106
- status: 200,
107
- data: {
108
- apps: items,
109
- },
110
- };
111
- }
112
12
  export function renderRootHelp(scope) {
113
13
  const binary = scope === 'admin' ? 'arcubase-admin' : 'arcubase';
114
14
  const items = listModules(scope).map((item) => ` - ${item}`);
115
15
  return [
116
- `${binary} <module> <command> [flags]`,
16
+ `${binary} <command> [subcommand] [flags]`,
117
17
  '',
118
18
  ...(scope === 'admin'
119
- ? ['use arcubase-admin for app, entity shell, and schema management', '']
120
- : ['use arcubase for rows, search, selection actions, and bulk actions', '']),
19
+ ? ['use arcubase-admin for app, table, access-rule, and workflow management', '']
20
+ : ['use arcubase for entry, table, row, upload, profile, and workflow actions', '']),
121
21
  'modules:',
122
22
  ...items,
123
23
  ...(scope === 'user' ? ['', 'special commands:', ' - upload <local-file>'] : []),
@@ -126,60 +26,50 @@ export function renderRootHelp(scope) {
126
26
  export function renderModuleHelp(scope, moduleName) {
127
27
  const items = listModuleCommands(scope, moduleName);
128
28
  if (items.length === 0) {
129
- const suggestions = findCommandSuggestions(moduleName, '').map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
29
+ const suggestions = findCommandSuggestions(moduleName, '').map((item) => `${item.binary} ${item.moduleName}${item.commandName ? ` ${item.commandName}` : ''}`);
130
30
  throw new CLIError('UNKNOWN_MODULE', `unknown module: ${moduleName}`, 2, suggestions.length > 0 ? { suggestions } : undefined);
131
31
  }
32
+ if (items.length === 1 && items[0].commandPath.length === 1) {
33
+ return renderCommandHelp(scope, moduleName);
34
+ }
132
35
  return [
133
36
  `${scope === 'admin' ? 'arcubase-admin' : 'arcubase'} ${moduleName} <command> [flags]`,
134
37
  '',
135
38
  ...(scope === 'admin'
136
- ? ['use arcubase-admin for app, entity shell, and schema management', '']
137
- : ['use arcubase for rows, search, selection actions, and bulk actions', '']),
39
+ ? ['use arcubase-admin for app, table, access-rule, and workflow management', '']
40
+ : ['use arcubase for entry, table, row, upload, profile, and workflow actions', '']),
138
41
  'commands:',
139
- ...items.map((item) => ` - ${item.commandPath[1]}`),
42
+ ...items.filter((item) => item.commandPath.length > 1).map((item) => ` - ${item.commandPath[1]}`),
140
43
  ].join('\n');
141
44
  }
142
45
  function buildUnknownCommandDetails(scope, moduleName, commandName) {
143
- const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
144
- if (scope === 'admin' && moduleName === 'workflow' && suggestions.some((item) => item.startsWith('arcubase rows '))) {
145
- return {
146
- suggestions,
147
- reason: `${moduleName} ${commandName} is not a valid command group; use arcubase rows for row operations`,
148
- hint: `use: arcubase rows ${commandName}`,
149
- };
150
- }
46
+ const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName}${item.commandName ? ` ${item.commandName}` : ''}`);
151
47
  return suggestions.length > 0 ? { suggestions } : undefined;
152
48
  }
153
49
  export function renderCommandHelp(scope, moduleName, commandName) {
154
50
  const command = findCommand(scope, moduleName, commandName);
155
51
  if (!command) {
156
- throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName} ${commandName}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName));
52
+ throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName}${commandName ? ` ${commandName}` : ''}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName ?? ''));
157
53
  }
158
54
  const docHints = [
159
55
  ...getCommandDocHints(`${scope}.${command.module}.${command.functionName}`),
160
56
  ...(command.requestType ? getDocHints(command.requestType) : []),
161
57
  ].filter((item, index, list) => list.findIndex((candidate) => candidate.file === item.file) === index);
58
+ const pathFlags = command.pathParams.filter((item) => !getFixedValue(item)).map((item) => `--${item.flag}`);
59
+ const queryFlags = command.queryParams.filter((item) => !getFixedValue(item)).map((item) => `--${item.flag}`);
162
60
  return [
163
- `${scope === 'admin' ? 'arcubase-admin' : 'arcubase'} ${moduleName} ${commandName}`,
61
+ `${scope === 'admin' ? 'arcubase-admin' : 'arcubase'} ${command.commandPath.join(' ')}`,
164
62
  `method: ${command.method}`,
165
63
  `endpoint: ${normalizeExternalEndpoint(command.endpoint)}`,
166
- command.requestType ? `body: ${command.requestType} via --body-file` : 'body: none',
167
- 'query flags: --query-file',
168
- command.endpointParams.length ? `path flags: ${command.endpointParams.map((item) => `--${item.replace(/_/g, '-')}`).join(', ')}` : 'path flags: none',
169
- command.scalarParams.length ? `scalar flags: ${command.scalarParams.map((item) => `--${item.name.replace(/([A-Z])/g, '-$1').toLowerCase()}`).join(', ')}` : 'scalar flags: none',
170
- ...(scope === 'admin' && moduleName === 'entity' && commandName === 'admin-save-entity'
64
+ command.requestType ? `body: ${command.requestType} via --body-file or --body-json` : 'body: none',
65
+ queryFlags.length ? `query flags: ${queryFlags.join(', ')}, --query-file` : 'query flags: --query-file',
66
+ pathFlags.length ? `path flags: ${pathFlags.join(', ')}` : 'path flags: none',
67
+ ...(scope === 'admin' && command.commandPath[0] === 'table' && command.commandPath[1] === 'update-schema'
171
68
  ? [
172
69
  'next step:',
173
70
  ' - switch to arcubase for row operations',
174
- ' - row insert: arcubase rows insert-entity --app-id <app_id> --entity-id <entity_id> --body-file insert.json',
175
- ' - row query: arcubase rows query-entity --app-id <app_id> --entity-id <entity_id> --body-file query.json',
176
- ]
177
- : []),
178
- ...(scope === 'admin' && moduleName === 'app' && commandName === 'inventory'
179
- ? [
180
- 'purpose:',
181
- ' - list all accessible apps and each app entity list in one call sequence',
182
- ' - use this before asking the user for app_id',
71
+ ' - row create: arcubase row create --app-id <app_id> --table-id <table_id> --body-file insert.json',
72
+ ' - row query: arcubase row query --app-id <app_id> --table-id <table_id> --body-file query.json',
183
73
  ]
184
74
  : []),
185
75
  ...(docHints.length > 0
@@ -205,15 +95,21 @@ function coerceScalar(value, typeText) {
205
95
  }
206
96
  return value;
207
97
  }
208
- function resolveEndpoint(endpoint, flags) {
209
- let resolved = endpoint;
210
- for (const placeholder of [...endpoint.matchAll(/:([A-Za-z0-9_]+)/g)].map((match) => match[1])) {
211
- const flagName = placeholder.replace(/_/g, '-');
212
- const value = flagValue(flags, flagName);
98
+ function getFixedValue(value) {
99
+ if (!('fixedValue' in value)) {
100
+ return undefined;
101
+ }
102
+ const fixedValue = value.fixedValue;
103
+ return typeof fixedValue === 'string' ? fixedValue : undefined;
104
+ }
105
+ function resolveEndpoint(command, flags) {
106
+ let resolved = command.endpoint;
107
+ for (const mapping of command.pathParams) {
108
+ const value = getFixedValue(mapping) ?? flagValue(flags, mapping.flag);
213
109
  if (!value) {
214
- throw new CLIError('MISSING_PATH_FLAG', `missing required flag --${flagName}`, 2);
110
+ throw new CLIError('MISSING_PATH_FLAG', `missing required flag --${mapping.flag}`, 2);
215
111
  }
216
- resolved = resolved.replace(`:${placeholder}`, encodeURIComponent(value));
112
+ resolved = resolved.replace(`:${mapping.param}`, encodeURIComponent(value));
217
113
  }
218
114
  return resolved;
219
115
  }
@@ -222,12 +118,11 @@ function buildScalarQuery(command, flags) {
222
118
  return undefined;
223
119
  }
224
120
  const out = {};
225
- for (const scalar of command.scalarParams) {
226
- const flagName = scalar.name.replace(/([A-Z])/g, '-$1').toLowerCase();
227
- const value = flagValue(flags, flagName);
121
+ for (const scalar of command.queryParams) {
122
+ const value = getFixedValue(scalar) ?? flagValue(flags, scalar.flag);
228
123
  if (value === undefined)
229
124
  continue;
230
- out[scalar.name] = coerceScalar(value, scalar.type);
125
+ out[scalar.key] = coerceScalar(value, scalar.type);
231
126
  }
232
127
  return Object.keys(out).length > 0 ? out : undefined;
233
128
  }
@@ -249,7 +144,7 @@ function extractEntityFields(payload) {
249
144
  }));
250
145
  }
251
146
  async function fetchEntityFields(runtimeEnv, appId, entityId, fetchImpl) {
252
- const response = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, `/entity/${encodeURIComponent(appId)}/${encodeURIComponent(entityId)}`), {
147
+ const response = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, `/api/entity/${encodeURIComponent(appId)}/${encodeURIComponent(entityId)}`), {
253
148
  method: 'GET',
254
149
  headers: buildRequestHeaders(runtimeEnv),
255
150
  });
@@ -272,7 +167,7 @@ async function fetchEntityFields(runtimeEnv, appId, entityId, fetchImpl) {
272
167
  ? upstreamError
273
168
  : JSON.stringify(upstreamError);
274
169
  throw new CLIError('UPSTREAM_BODY_ERROR', upstreamMessage, 1, {
275
- endpoint: `/entity/${appId}/${entityId}`,
170
+ endpoint: `/api/entity/${appId}/${entityId}`,
276
171
  method: 'GET',
277
172
  upstreamError,
278
173
  });
@@ -304,7 +199,7 @@ async function validateFileFieldPayloads(scope, command, runtimeEnv, flags, body
304
199
  return;
305
200
  }
306
201
  const appId = flagValue(flags, 'app-id');
307
- const entityId = flagValue(flags, 'entity-id');
202
+ const entityId = flagValue(flags, 'table-id');
308
203
  if (!appId || !entityId) {
309
204
  return;
310
205
  }
@@ -392,7 +287,7 @@ function validateActionSpecificBody(scope, command, flags, body) {
392
287
  if (!isRecord(body) || !command.requestType) {
393
288
  return;
394
289
  }
395
- if (command.module === 'rows' && command.functionName === 'queryEntitySelection') {
290
+ if (command.commandPath[0] === 'row' && command.commandPath[1] === 'selection-action') {
396
291
  const action = flagValue(flags, 'action');
397
292
  const selection = body.selection;
398
293
  if (!isRecord(selection) || typeof selection.type !== 'string') {
@@ -403,7 +298,7 @@ function validateActionSpecificBody(scope, command, flags, body) {
403
298
  const conditionKeys = condition ? Object.keys(condition).filter((key) => key !== 'selectAll') : [];
404
299
  if (action === 'query') {
405
300
  if (type === 'condition') {
406
- throwBodyValidationFailure('selection.type=condition is not supported for action=query; use selection.type=ids or selection.type=all, or use rows query-entity for search conditions', command.requestType, 'body.selection.type', scope, command);
301
+ throwBodyValidationFailure('selection.type=condition is not supported for action=query; use selection.type=ids or selection.type=all, or use row query for search conditions', command.requestType, 'body.selection.type', scope, command);
407
302
  }
408
303
  return;
409
304
  }
@@ -424,10 +319,10 @@ export function summarizeCommand(scope, moduleName, commandName) {
424
319
  scope,
425
320
  commandPath: command.commandPath,
426
321
  method: command.method,
427
- endpoint: normalizeExternalEndpoint(command.endpoint),
322
+ endpoint: command.endpoint,
428
323
  requestType: command.requestType,
429
- pathFlags: command.endpointParams,
430
- scalarFlags: command.scalarParams.map((item) => item.name.replace(/([A-Z])/g, '-$1').toLowerCase()),
324
+ pathFlags: command.pathParams.filter((item) => !getFixedValue(item)).map((item) => item.flag),
325
+ queryFlags: command.queryParams.filter((item) => !getFixedValue(item)).map((item) => item.flag),
431
326
  };
432
327
  }
433
328
  export async function executeCLI(scope, argv, env, fetchImpl = fetch) {
@@ -459,7 +354,8 @@ export async function executeCLI(scope, argv, env, fetchImpl = fetch) {
459
354
  if (!moduleName) {
460
355
  return { kind: 'help', text: renderRootHelp(scope) };
461
356
  }
462
- if (!commandName) {
357
+ const singleTokenCommand = !commandName ? findCommand(scope, moduleName) : null;
358
+ if (!commandName && !singleTokenCommand) {
463
359
  return { kind: 'help', text: renderModuleHelp(scope, moduleName) };
464
360
  }
465
361
  if (hasFlag(parsed.flags, 'help')) {
@@ -468,20 +364,20 @@ export async function executeCLI(scope, argv, env, fetchImpl = fetch) {
468
364
  const runtimeEnv = env ?? loadRuntimeEnv(scope);
469
365
  const command = findCommand(scope, moduleName, commandName);
470
366
  if (!command) {
471
- throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName} ${commandName}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName));
472
- }
473
- if (scope === 'admin' && moduleName === 'app' && commandName === 'inventory') {
474
- return executeAppInventory(runtimeEnv, fetchImpl);
367
+ throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName}${commandName ? ` ${commandName}` : ''}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName ?? ''));
475
368
  }
476
- const endpoint = normalizeExternalEndpoint(resolveEndpoint(command.endpoint, parsed.flags));
369
+ const endpoint = resolveEndpoint(command, parsed.flags);
477
370
  const scalarQuery = buildScalarQuery(command, parsed.flags);
478
371
  const fileQuery = loadQueryFromFlags(parsed.flags);
479
372
  const query = { ...(scalarQuery ?? {}), ...(fileQuery ?? {}) };
480
373
  const body = loadBodyFromFlags(parsed.flags);
481
374
  let validatedBody = body;
375
+ if (!command.requestType && body !== undefined) {
376
+ throw new CLIError('BODY_JSON_NOT_SUPPORTED', `command does not accept a request body: ${moduleName} ${commandName}`, 2);
377
+ }
482
378
  if (command.requestType) {
483
379
  if (body === undefined) {
484
- throw new CLIError('MISSING_BODY_FILE', `command requires --body-file for ${command.requestType}`, 2);
380
+ throw new CLIError('MISSING_BODY_FILE', `command requires --body-file or --body-json for ${command.requestType}`, 2);
485
381
  }
486
382
  const schema = getBodySchema(command.requestType);
487
383
  if (schema) {
@@ -18,7 +18,7 @@ export function normalizeExternalEndpoint(endpoint) {
18
18
  return trimmed;
19
19
  }
20
20
  export function buildURL(baseURL, endpoint, query) {
21
- const url = new URL(normalizeExternalEndpoint(endpoint), baseURL.endsWith('/') ? baseURL : `${baseURL}/`);
21
+ const url = new URL(endpoint, baseURL.endsWith('/') ? baseURL : `${baseURL}/`);
22
22
  if (query) {
23
23
  for (const [key, value] of Object.entries(query)) {
24
24
  if (value === undefined || value === null)
@@ -33,7 +33,7 @@ function requireTokenPayload(payload) {
33
33
  ? upstreamError
34
34
  : JSON.stringify(upstreamError);
35
35
  throw new CLIError('UPSTREAM_BODY_ERROR', message, 1, {
36
- endpoint: '/upload/token',
36
+ endpoint: '/api/upload/token',
37
37
  method: 'POST',
38
38
  traceId: typeof payload.trace_id === 'string' ? payload.trace_id : undefined,
39
39
  upstreamError,
@@ -74,7 +74,7 @@ export function renderUploadHelp() {
74
74
  export async function uploadLocalFile(env, sourcePath, options, fetchImpl = fetch) {
75
75
  const { absolutePath, bytes } = readUploadSource(sourcePath);
76
76
  const filename = (options.filename && options.filename.trim()) || path.basename(absolutePath);
77
- const tokenResponse = await fetchImpl(buildURL(env.ARCUBASE_BASE_URL, '/upload/token'), {
77
+ const tokenResponse = await fetchImpl(buildURL(env.ARCUBASE_BASE_URL, '/api/upload/token'), {
78
78
  method: 'POST',
79
79
  headers: {
80
80
  ...buildRequestHeaders(env),
@@ -88,7 +88,7 @@ export async function uploadLocalFile(env, sourcePath, options, fetchImpl = fetc
88
88
  const tokenParsed = parseJSONResponse(tokenRaw);
89
89
  if (!tokenResponse.ok) {
90
90
  throw new CLIError('UPLOAD_TOKEN_REQUEST_FAILED', typeof tokenParsed === 'string' ? tokenParsed : JSON.stringify(tokenParsed), 1, {
91
- endpoint: '/upload/token',
91
+ endpoint: '/api/upload/token',
92
92
  method: 'POST',
93
93
  });
94
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"zod_registry.d.ts","sourceRoot":"","sources":["../../src/runtime/zod_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AA6BrC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAOjE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAQ9D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAgED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAqBhE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAI9D;AAqED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,CAItE"}
1
+ {"version":3,"file":"zod_registry.d.ts","sourceRoot":"","sources":["../../src/runtime/zod_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AA6BrC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAOjE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAQ9D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAyDD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAqBhE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAI9D;AA0DD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,CAItE"}
@@ -42,18 +42,12 @@ const examplesIndexDocHint = {
42
42
  title: 'Examples index',
43
43
  file: '/opt/arcubase-sdk/docs/runtime-reference/examples/README.md',
44
44
  };
45
- const appDiscoveryDocHint = {
46
- title: 'App discovery',
47
- file: '/opt/arcubase-sdk/docs/runtime-reference/app-discovery.md',
48
- };
49
45
  const docHintIndex = {
50
46
  AppCreateByTenantsReqVO: [
51
- appDiscoveryDocHint,
52
47
  { title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
53
48
  examplesIndexDocHint,
54
49
  ],
55
50
  AppCreateEntityReqVO: [
56
- appDiscoveryDocHint,
57
51
  { title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
58
52
  examplesIndexDocHint,
59
53
  ],
@@ -131,25 +125,14 @@ export function getDocHints(typeName) {
131
125
  }
132
126
  const commandDocHintIndex = {
133
127
  'admin.app.createAppByTenants': [
134
- appDiscoveryDocHint,
135
128
  { title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
136
129
  examplesIndexDocHint,
137
130
  ],
138
- 'admin.app.listApps': [
139
- appDiscoveryDocHint,
140
- examplesIndexDocHint,
141
- ],
142
- 'admin.app.inventory': [
143
- appDiscoveryDocHint,
144
- examplesIndexDocHint,
145
- ],
146
131
  'admin.app.createEntity': [
147
- appDiscoveryDocHint,
148
132
  { title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
149
133
  examplesIndexDocHint,
150
134
  ],
151
135
  'admin.entity.adminGetEntityInfo': [
152
- appDiscoveryDocHint,
153
136
  { title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
154
137
  examplesIndexDocHint,
155
138
  ],
@@ -159,34 +142,34 @@ const commandDocHintIndex = {
159
142
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
160
143
  examplesIndexDocHint,
161
144
  ],
162
- 'user.rows.insertEntity': [
145
+ 'user.workflow.insertEntity': [
163
146
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
164
147
  { title: 'Uploads', file: '/opt/arcubase-sdk/docs/runtime-reference/uploads.md' },
165
148
  examplesIndexDocHint,
166
149
  ],
167
- 'user.rows.queryEntity': [
150
+ 'user.workflow.queryEntity': [
168
151
  { title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
169
152
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
170
153
  examplesIndexDocHint,
171
154
  ],
172
- 'user.rows.getEntityRow': [
155
+ 'user.workflow.getEntityRow': [
173
156
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
174
157
  examplesIndexDocHint,
175
158
  ],
176
- 'user.rows.updateEntityRow': [
159
+ 'user.workflow.updateEntityRow': [
177
160
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
178
161
  { title: 'Uploads', file: '/opt/arcubase-sdk/docs/runtime-reference/uploads.md' },
179
162
  examplesIndexDocHint,
180
163
  ],
181
- 'user.rows.queryEntitySelection': [
164
+ 'user.workflow.queryEntitySelection': [
182
165
  { title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
183
166
  examplesIndexDocHint,
184
167
  ],
185
- 'user.rows.deleteEntityRow': [
168
+ 'user.workflow.deleteEntityRow': [
186
169
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
187
170
  examplesIndexDocHint,
188
171
  ],
189
- 'user.rows.restoreEntityRow': [
172
+ 'user.workflow.restoreEntityRow': [
190
173
  { title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
191
174
  examplesIndexDocHint,
192
175
  ],