@carthooks/arcubase-cli 0.1.1 → 0.1.3
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 +911 -10
- package/bundle/arcubase.mjs +911 -10
- package/dist/runtime/command_registry.d.ts +8 -0
- package/dist/runtime/command_registry.d.ts.map +1 -1
- package/dist/runtime/command_registry.js +35 -0
- package/dist/runtime/entity_save_schema.d.ts +15 -0
- package/dist/runtime/entity_save_schema.d.ts.map +1 -0
- package/dist/runtime/entity_save_schema.js +641 -0
- package/dist/runtime/env.d.ts +1 -0
- package/dist/runtime/env.d.ts.map +1 -1
- package/dist/runtime/env.js +1 -0
- package/dist/runtime/errors.d.ts +10 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +89 -10
- package/dist/runtime/http.d.ts +1 -1
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +3 -0
- package/dist/runtime/zod_registry.d.ts +6 -0
- package/dist/runtime/zod_registry.d.ts.map +1 -1
- package/dist/runtime/zod_registry.js +133 -0
- package/dist/tests/bootstrap.test.js +5 -0
- package/dist/tests/command_registry.test.js +5 -0
- package/dist/tests/entity_save_schema.test.d.ts +2 -0
- package/dist/tests/entity_save_schema.test.d.ts.map +1 -0
- package/dist/tests/entity_save_schema.test.js +221 -0
- package/dist/tests/execute_validation.test.js +453 -1
- package/dist/tests/help.test.js +33 -0
- package/package.json +1 -1
- package/sdk-dist/docs/runtime-reference/README.md +177 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/README.md +120 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/address.md +34 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/boolean.md +37 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/button.md +47 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/checkbox.md +61 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/datasets.md +35 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/datetime.md +40 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/department.md +33 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/departments.md +34 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/divider.md +39 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/file.md +44 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/formula.md +44 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/image.md +43 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/linkto.md +67 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/location.md +32 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/lookup.md +41 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/member.md +37 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/members.md +31 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/number.md +70 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/query.md +50 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/radio.md +53 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/relation.md +55 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/relationfield.md +38 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/rollup.md +54 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/select.md +63 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/selects.md +51 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/serialnumber.md +48 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/signature.md +31 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/status.md +70 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +74 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/tags.md +19 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/text.md +76 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/textarea.md +47 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/workflow_status.md +17 -0
- package/sdk-dist/docs/runtime-reference/entity-schema.md +197 -0
- package/sdk-dist/docs/runtime-reference/examples/README.md +51 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/README.md +20 -0
- package/sdk-dist/docs/runtime-reference/examples/mes-01/README.md +21 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +164 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +79 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/create-app.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.schema.json +159 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.schema.json +179 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.schema.json +168 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.schema.json +417 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.bulk-update.json +22 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.query.json +10 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.row.insert.json +28 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.schema.json +398 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.condition.json +13 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.ids.json +7 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.schema.json +137 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/README.md +21 -0
- package/sdk-dist/docs/runtime-reference/row-crud.md +186 -0
- package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +494 -0
- package/sdk-dist/docs/runtime-reference/table-lifecycle.md +123 -0
- package/sdk-dist/docs/runtime-reference/workflow/README.md +19 -0
- package/src/runtime/command_registry.ts +47 -0
- package/src/runtime/entity_save_schema.ts +708 -0
- package/src/runtime/env.ts +2 -0
- package/src/runtime/errors.ts +11 -0
- package/src/runtime/execute.ts +123 -10
- package/src/runtime/http.ts +4 -1
- package/src/runtime/zod_registry.ts +154 -0
- package/src/tests/bootstrap.test.ts +5 -0
- package/src/tests/command_registry.test.ts +6 -0
- package/src/tests/entity_save_schema.test.ts +236 -0
- package/src/tests/execute_validation.test.ts +601 -1
- package/src/tests/help.test.ts +39 -0
|
@@ -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,
|
|
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;AAI/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;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAQ1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAYhF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAsBtG;AAyHD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,uBAAuB,CAetH;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,CAoHrI"}
|
package/dist/runtime/execute.js
CHANGED
|
@@ -2,9 +2,9 @@ import { parseCLIArgs, hasFlag, flagValue } from './argv.js';
|
|
|
2
2
|
import { loadRuntimeEnv } from './env.js';
|
|
3
3
|
import { CLIError } from './errors.js';
|
|
4
4
|
import { buildRequestHeaders, buildURL, normalizeExternalEndpoint } from './http.js';
|
|
5
|
-
import { listModules, listModuleCommands, findCommand } from './command_registry.js';
|
|
5
|
+
import { listModules, listModuleCommands, findCommand, findCommandSuggestions } from './command_registry.js';
|
|
6
6
|
import { loadBodyFromFlags, loadQueryFromFlags } from './body_loader.js';
|
|
7
|
-
import { getBodySchema, getTypeHints, getUnsupportedBodySchemaReason } from './zod_registry.js';
|
|
7
|
+
import { getBodySchema, getCommandDocHints, getDocHints, getTypeHints, getUnsupportedBodySchemaReason } from './zod_registry.js';
|
|
8
8
|
export function renderRootHelp(scope) {
|
|
9
9
|
const binary = scope === 'admin' ? 'arcubase-admin' : 'arcubase';
|
|
10
10
|
return [
|
|
@@ -17,7 +17,8 @@ export function renderRootHelp(scope) {
|
|
|
17
17
|
export function renderModuleHelp(scope, moduleName) {
|
|
18
18
|
const items = listModuleCommands(scope, moduleName);
|
|
19
19
|
if (items.length === 0) {
|
|
20
|
-
|
|
20
|
+
const suggestions = findCommandSuggestions(moduleName, '').map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
|
|
21
|
+
throw new CLIError('UNKNOWN_MODULE', `unknown module: ${moduleName}`, 2, suggestions.length > 0 ? { suggestions } : undefined);
|
|
21
22
|
}
|
|
22
23
|
return [
|
|
23
24
|
`${scope === 'admin' ? 'arcubase-admin' : 'arcubase'} ${moduleName} <command> [flags]`,
|
|
@@ -29,15 +30,24 @@ export function renderModuleHelp(scope, moduleName) {
|
|
|
29
30
|
export function renderCommandHelp(scope, moduleName, commandName) {
|
|
30
31
|
const command = findCommand(scope, moduleName, commandName);
|
|
31
32
|
if (!command) {
|
|
32
|
-
|
|
33
|
+
const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
|
|
34
|
+
throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName} ${commandName}`, 2, suggestions.length > 0 ? { suggestions } : undefined);
|
|
33
35
|
}
|
|
36
|
+
const docHints = [
|
|
37
|
+
...getCommandDocHints(`${scope}.${command.module}.${command.functionName}`),
|
|
38
|
+
...(command.requestType ? getDocHints(command.requestType) : []),
|
|
39
|
+
].filter((item, index, list) => list.findIndex((candidate) => candidate.file === item.file) === index);
|
|
34
40
|
return [
|
|
35
41
|
`${scope === 'admin' ? 'arcubase-admin' : 'arcubase'} ${moduleName} ${commandName}`,
|
|
36
42
|
`method: ${command.method}`,
|
|
37
43
|
`endpoint: ${normalizeExternalEndpoint(command.endpoint)}`,
|
|
38
44
|
command.requestType ? `body: ${command.requestType} via --body-file` : 'body: none',
|
|
45
|
+
'query flags: --query-file',
|
|
39
46
|
command.endpointParams.length ? `path flags: ${command.endpointParams.map((item) => `--${item.replace(/_/g, '-')}`).join(', ')}` : 'path flags: none',
|
|
40
47
|
command.scalarParams.length ? `scalar flags: ${command.scalarParams.map((item) => `--${item.name.replace(/([A-Z])/g, '-$1').toLowerCase()}`).join(', ')}` : 'scalar flags: none',
|
|
48
|
+
...(docHints.length > 0
|
|
49
|
+
? ['docs:', ...docHints.map((item) => ` - ${item.title}: ${item.file}`)]
|
|
50
|
+
: []),
|
|
41
51
|
].join('\n');
|
|
42
52
|
}
|
|
43
53
|
function coerceScalar(value, typeText) {
|
|
@@ -84,10 +94,55 @@ function buildScalarQuery(command, flags) {
|
|
|
84
94
|
}
|
|
85
95
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
86
96
|
}
|
|
97
|
+
function isRecord(value) {
|
|
98
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
99
|
+
}
|
|
100
|
+
function throwBodyValidationFailure(message, requestType, path, scope, command) {
|
|
101
|
+
throw new CLIError('BODY_VALIDATION_FAILED', message, 2, {
|
|
102
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
103
|
+
requestType,
|
|
104
|
+
issues: [
|
|
105
|
+
{
|
|
106
|
+
path,
|
|
107
|
+
message,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
tsHints: getTypeHints(requestType),
|
|
111
|
+
docHints: getDocHints(requestType),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function validateActionSpecificBody(scope, command, flags, body) {
|
|
115
|
+
if (!isRecord(body) || !command.requestType) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (command.module === 'workflow' && command.functionName === 'queryEntitySelection') {
|
|
119
|
+
const action = flagValue(flags, 'action');
|
|
120
|
+
const selection = body.selection;
|
|
121
|
+
if (!isRecord(selection) || typeof selection.type !== 'string') {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const type = selection.type;
|
|
125
|
+
const condition = isRecord(selection.condition) ? selection.condition : undefined;
|
|
126
|
+
const conditionKeys = condition ? Object.keys(condition).filter((key) => key !== 'selectAll') : [];
|
|
127
|
+
if (action === 'query') {
|
|
128
|
+
if (type === 'condition') {
|
|
129
|
+
throwBodyValidationFailure('selection.type=condition is not supported for action=query; use selection.type=ids or selection.type=all, or use workflow query-entity for search conditions', command.requestType, 'body.selection.type', scope, command);
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if ((action === 'archive' || action === 'delete' || action === 'batch_print') && type === 'all') {
|
|
134
|
+
throwBodyValidationFailure(`selection.type=all is not supported for action=${action}; use ids or condition`, command.requestType, 'body.selection.type', scope, command);
|
|
135
|
+
}
|
|
136
|
+
if ((action === 'archive' || action === 'delete') && type === 'condition' && conditionKeys.length === 0) {
|
|
137
|
+
throwBodyValidationFailure(`selection.condition for action=${action} requires at least one q, tab, or filter_* key in addition to selectAll`, command.requestType, 'body.selection.condition', scope, command);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
87
141
|
export function summarizeCommand(scope, moduleName, commandName) {
|
|
88
142
|
const command = findCommand(scope, moduleName, commandName);
|
|
89
143
|
if (!command) {
|
|
90
|
-
|
|
144
|
+
const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
|
|
145
|
+
throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName} ${commandName}`, 2, suggestions.length > 0 ? { suggestions } : undefined);
|
|
91
146
|
}
|
|
92
147
|
return {
|
|
93
148
|
scope,
|
|
@@ -99,7 +154,7 @@ export function summarizeCommand(scope, moduleName, commandName) {
|
|
|
99
154
|
scalarFlags: command.scalarParams.map((item) => item.name.replace(/([A-Z])/g, '-$1').toLowerCase()),
|
|
100
155
|
};
|
|
101
156
|
}
|
|
102
|
-
export async function executeCLI(scope, argv, env
|
|
157
|
+
export async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
103
158
|
const parsed = parseCLIArgs(argv);
|
|
104
159
|
if (parsed.commandTokens.length === 0) {
|
|
105
160
|
return { kind: 'help', text: renderRootHelp(scope) };
|
|
@@ -114,6 +169,7 @@ export async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetch
|
|
|
114
169
|
if (hasFlag(parsed.flags, 'help')) {
|
|
115
170
|
return { kind: 'help', text: renderCommandHelp(scope, moduleName, commandName) };
|
|
116
171
|
}
|
|
172
|
+
const runtimeEnv = env ?? loadRuntimeEnv(scope);
|
|
117
173
|
const command = findCommand(scope, moduleName, commandName);
|
|
118
174
|
if (!command) {
|
|
119
175
|
throw new CLIError('UNKNOWN_COMMAND', `unknown command: ${moduleName} ${commandName}`, 2);
|
|
@@ -123,6 +179,7 @@ export async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetch
|
|
|
123
179
|
const fileQuery = loadQueryFromFlags(parsed.flags);
|
|
124
180
|
const query = { ...(scalarQuery ?? {}), ...(fileQuery ?? {}) };
|
|
125
181
|
const body = loadBodyFromFlags(parsed.flags);
|
|
182
|
+
let validatedBody = body;
|
|
126
183
|
if (command.requestType) {
|
|
127
184
|
if (body === undefined) {
|
|
128
185
|
throw new CLIError('MISSING_BODY_FILE', `command requires --body-file for ${command.requestType}`, 2);
|
|
@@ -139,8 +196,11 @@ export async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetch
|
|
|
139
196
|
message: issue.message,
|
|
140
197
|
})),
|
|
141
198
|
tsHints: getTypeHints(command.requestType),
|
|
199
|
+
docHints: getDocHints(command.requestType),
|
|
142
200
|
});
|
|
143
201
|
}
|
|
202
|
+
validatedBody = parsedBody.data;
|
|
203
|
+
validateActionSpecificBody(scope, command, parsed.flags, validatedBody);
|
|
144
204
|
}
|
|
145
205
|
else {
|
|
146
206
|
const unsupportedReason = getUnsupportedBodySchemaReason(command.requestType);
|
|
@@ -150,18 +210,18 @@ export async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetch
|
|
|
150
210
|
requestType: command.requestType,
|
|
151
211
|
reason: unsupportedReason,
|
|
152
212
|
tsHints: getTypeHints(command.requestType),
|
|
213
|
+
docHints: getDocHints(command.requestType),
|
|
153
214
|
});
|
|
154
215
|
}
|
|
155
216
|
}
|
|
156
217
|
}
|
|
157
|
-
const
|
|
158
|
-
const response = await fetchImpl(buildURL(env.ARCUBASE_BASE_URL, endpoint, Object.keys(query).length > 0 ? query : undefined), {
|
|
218
|
+
const response = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, endpoint, Object.keys(query).length > 0 ? query : undefined), {
|
|
159
219
|
method: command.method,
|
|
160
220
|
headers: {
|
|
161
|
-
...
|
|
221
|
+
...buildRequestHeaders(runtimeEnv),
|
|
162
222
|
'Content-Type': 'application/json',
|
|
163
223
|
},
|
|
164
|
-
body:
|
|
224
|
+
body: validatedBody === undefined || command.method === 'GET' ? undefined : JSON.stringify(validatedBody),
|
|
165
225
|
});
|
|
166
226
|
const raw = await response.text();
|
|
167
227
|
let parsedResponse = raw;
|
|
@@ -174,6 +234,25 @@ export async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetch
|
|
|
174
234
|
if (!response.ok) {
|
|
175
235
|
throw new CLIError('UPSTREAM_REQUEST_FAILED', typeof parsedResponse === 'string' ? parsedResponse : JSON.stringify(parsedResponse), 1);
|
|
176
236
|
}
|
|
237
|
+
if (parsedResponse && typeof parsedResponse === 'object' && 'error' in parsedResponse && parsedResponse.error) {
|
|
238
|
+
const upstreamError = parsedResponse.error;
|
|
239
|
+
const upstreamMessage = typeof upstreamError === 'object' && upstreamError && 'message' in upstreamError && typeof upstreamError.message === 'string'
|
|
240
|
+
? upstreamError.message
|
|
241
|
+
: typeof upstreamError === 'string'
|
|
242
|
+
? upstreamError
|
|
243
|
+
: JSON.stringify(upstreamError);
|
|
244
|
+
const traceId = typeof parsedResponse.trace_id === 'string'
|
|
245
|
+
? parsedResponse.trace_id
|
|
246
|
+
: typeof parsedResponse.request_id === 'string'
|
|
247
|
+
? parsedResponse.request_id
|
|
248
|
+
: undefined;
|
|
249
|
+
throw new CLIError('UPSTREAM_BODY_ERROR', upstreamMessage, 1, {
|
|
250
|
+
endpoint,
|
|
251
|
+
method: command.method,
|
|
252
|
+
traceId,
|
|
253
|
+
upstreamError,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
177
256
|
return {
|
|
178
257
|
kind: 'result',
|
|
179
258
|
commandPath: command.commandPath,
|
package/dist/runtime/http.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RuntimeEnv } from './env.js';
|
|
2
|
-
export declare function buildRequestHeaders(env: Pick<RuntimeEnv, 'ARCUBASE_ACCESS_TOKEN' | 'ARCUBASE_TENANT_ID' | 'ARCUBASE_TRACE_ID'>): Record<string, string>;
|
|
2
|
+
export declare function buildRequestHeaders(env: Pick<RuntimeEnv, 'ARCUBASE_ACCESS_TOKEN' | 'ARCUBASE_TENANT_ID' | 'ARCUBASE_HOST' | 'ARCUBASE_TRACE_ID'>): Record<string, string>;
|
|
3
3
|
export declare function normalizeExternalEndpoint(endpoint: string): string;
|
|
4
4
|
export declare function buildURL(baseURL: string, endpoint: string, query?: Record<string, any>): string;
|
|
5
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,uBAAuB,GAAG,oBAAoB,GAAG,mBAAmB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,uBAAuB,GAAG,oBAAoB,GAAG,eAAe,GAAG,mBAAmB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYzK;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASlE;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAS/F"}
|
package/dist/runtime/http.js
CHANGED
|
@@ -3,6 +3,9 @@ export function buildRequestHeaders(env) {
|
|
|
3
3
|
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}`,
|
|
4
4
|
'X-Tenant-Id': env.ARCUBASE_TENANT_ID
|
|
5
5
|
};
|
|
6
|
+
if (env.ARCUBASE_HOST && env.ARCUBASE_HOST.trim() !== '') {
|
|
7
|
+
headers['X-Host'] = env.ARCUBASE_HOST;
|
|
8
|
+
}
|
|
6
9
|
if (env.ARCUBASE_TRACE_ID) {
|
|
7
10
|
headers['X-Trace-Id'] = env.ARCUBASE_TRACE_ID;
|
|
8
11
|
}
|
|
@@ -6,5 +6,11 @@ export type RuntimeTypeHint = {
|
|
|
6
6
|
symbol: string;
|
|
7
7
|
file: string;
|
|
8
8
|
};
|
|
9
|
+
export type RuntimeDocHint = {
|
|
10
|
+
title: string;
|
|
11
|
+
file: string;
|
|
12
|
+
};
|
|
9
13
|
export declare function getTypeHints(typeName: string): RuntimeTypeHint[];
|
|
14
|
+
export declare function getDocHints(typeName: string): RuntimeDocHint[];
|
|
15
|
+
export declare function getCommandDocHints(operation: string): RuntimeDocHint[];
|
|
10
16
|
//# sourceMappingURL=zod_registry.d.ts.map
|
|
@@ -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;
|
|
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;AA2DD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAqBhE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAI9D;AAsDD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,CAItE"}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { bodySchemas, unsupportedBodySchemas } from '../generated/zod_registry.generated.js';
|
|
2
2
|
import { typeIndex } from '../generated/type_index.generated.js';
|
|
3
|
+
import { AppCreateByTenantsReqVOSchemaOverride, EntityBulkUpdateReqVOSchemaOverride, EntityInvokeBatchOperatorReqVOSchemaOverride, EntityQueryReqVOSchemaOverride, EntitySaveReqVOSchemaOverride, EntitySelectionActionReqVOSchemaOverride, EntityTagsBatchReqVOSchemaOverride, EntityTagsSelectionReqVOSchemaOverride, EntityUpdateReqVOSchemaOverride, InsertReqVOSchemaOverride, } from './entity_save_schema.js';
|
|
4
|
+
const schemaOverrides = {
|
|
5
|
+
AppCreateByTenantsReqVO: AppCreateByTenantsReqVOSchemaOverride,
|
|
6
|
+
EntityBulkUpdateReqVO: EntityBulkUpdateReqVOSchemaOverride,
|
|
7
|
+
'EntityInvokeBatchOperatorReqVO & InvokeRequestVO': EntityInvokeBatchOperatorReqVOSchemaOverride,
|
|
8
|
+
EntityQueryReqVO: EntityQueryReqVOSchemaOverride,
|
|
9
|
+
EntitySaveReqVO: EntitySaveReqVOSchemaOverride,
|
|
10
|
+
EntitySelectionActionReqVO: EntitySelectionActionReqVOSchemaOverride,
|
|
11
|
+
'{ policy_id: string selection: any }': EntityTagsSelectionReqVOSchemaOverride,
|
|
12
|
+
'{ policy_id: string selection: any tag_names: string[] }': EntityTagsBatchReqVOSchemaOverride,
|
|
13
|
+
EntityUpdateReqVO: EntityUpdateReqVOSchemaOverride,
|
|
14
|
+
InsertReqVO: InsertReqVOSchemaOverride,
|
|
15
|
+
};
|
|
3
16
|
export function getBodySchema(typeName) {
|
|
4
17
|
const name = String(typeName || '').trim();
|
|
5
18
|
if (!name)
|
|
6
19
|
return null;
|
|
20
|
+
if (schemaOverrides[name]) {
|
|
21
|
+
return schemaOverrides[name];
|
|
22
|
+
}
|
|
7
23
|
return bodySchemas[name] ?? null;
|
|
8
24
|
}
|
|
9
25
|
export function getUnsupportedBodySchemaReason(typeName) {
|
|
@@ -22,6 +38,60 @@ export function requireBodySchema(typeName) {
|
|
|
22
38
|
}
|
|
23
39
|
throw new Error(`runtime validation schema not found for ${typeName}`);
|
|
24
40
|
}
|
|
41
|
+
const examplesIndexDocHint = {
|
|
42
|
+
title: 'Examples index',
|
|
43
|
+
file: '/opt/arcubase-sdk/docs/runtime-reference/examples/README.md',
|
|
44
|
+
};
|
|
45
|
+
const omsExampleDocHint = {
|
|
46
|
+
title: 'OMS example 01',
|
|
47
|
+
file: '/opt/arcubase-sdk/docs/runtime-reference/examples/oms-01/README.md',
|
|
48
|
+
};
|
|
49
|
+
const docHintIndex = {
|
|
50
|
+
AppCreateByTenantsReqVO: [
|
|
51
|
+
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
52
|
+
examplesIndexDocHint,
|
|
53
|
+
omsExampleDocHint,
|
|
54
|
+
],
|
|
55
|
+
AppCreateEntityReqVO: [
|
|
56
|
+
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
57
|
+
examplesIndexDocHint,
|
|
58
|
+
omsExampleDocHint,
|
|
59
|
+
],
|
|
60
|
+
EntitySaveReqVO: [
|
|
61
|
+
{ title: 'Entity schema', file: '/opt/arcubase-sdk/docs/runtime-reference/entity-schema.md' },
|
|
62
|
+
omsExampleDocHint,
|
|
63
|
+
],
|
|
64
|
+
EntityQueryReqVO: [
|
|
65
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
66
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
67
|
+
omsExampleDocHint,
|
|
68
|
+
],
|
|
69
|
+
EntityUpdateReqVO: [
|
|
70
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
71
|
+
omsExampleDocHint,
|
|
72
|
+
],
|
|
73
|
+
EntitySelectionActionReqVO: [
|
|
74
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
75
|
+
omsExampleDocHint,
|
|
76
|
+
],
|
|
77
|
+
InsertReqVO: [
|
|
78
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
79
|
+
omsExampleDocHint,
|
|
80
|
+
],
|
|
81
|
+
EntityBulkUpdateReqVO: [
|
|
82
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
83
|
+
omsExampleDocHint,
|
|
84
|
+
],
|
|
85
|
+
'EntityInvokeBatchOperatorReqVO & InvokeRequestVO': [
|
|
86
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
87
|
+
],
|
|
88
|
+
'{ policy_id: string selection: any }': [
|
|
89
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
90
|
+
],
|
|
91
|
+
'{ policy_id: string selection: any tag_names: string[] }': [
|
|
92
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
93
|
+
],
|
|
94
|
+
};
|
|
25
95
|
export function getTypeHints(typeName) {
|
|
26
96
|
const name = String(typeName || '').trim();
|
|
27
97
|
if (!name)
|
|
@@ -48,3 +118,66 @@ export function getTypeHints(typeName) {
|
|
|
48
118
|
}
|
|
49
119
|
return out;
|
|
50
120
|
}
|
|
121
|
+
export function getDocHints(typeName) {
|
|
122
|
+
const name = String(typeName || '').trim();
|
|
123
|
+
if (!name)
|
|
124
|
+
return [];
|
|
125
|
+
return docHintIndex[name] ?? [];
|
|
126
|
+
}
|
|
127
|
+
const commandDocHintIndex = {
|
|
128
|
+
'admin.app.createAppByTenants': [
|
|
129
|
+
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
130
|
+
examplesIndexDocHint,
|
|
131
|
+
omsExampleDocHint,
|
|
132
|
+
],
|
|
133
|
+
'admin.app.createEntity': [
|
|
134
|
+
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
135
|
+
omsExampleDocHint,
|
|
136
|
+
],
|
|
137
|
+
'admin.entity.adminGetEntityInfo': [
|
|
138
|
+
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
139
|
+
omsExampleDocHint,
|
|
140
|
+
],
|
|
141
|
+
'admin.entity.adminSaveEntity': [
|
|
142
|
+
{ title: 'Entity schema', file: '/opt/arcubase-sdk/docs/runtime-reference/entity-schema.md' },
|
|
143
|
+
omsExampleDocHint,
|
|
144
|
+
],
|
|
145
|
+
'user.workflow.insertEntity': [
|
|
146
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
147
|
+
omsExampleDocHint,
|
|
148
|
+
],
|
|
149
|
+
'user.workflow.queryEntity': [
|
|
150
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
151
|
+
omsExampleDocHint,
|
|
152
|
+
],
|
|
153
|
+
'user.workflow.getEntityRow': [
|
|
154
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
155
|
+
omsExampleDocHint,
|
|
156
|
+
],
|
|
157
|
+
'user.workflow.updateEntityRow': [
|
|
158
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
159
|
+
omsExampleDocHint,
|
|
160
|
+
],
|
|
161
|
+
'user.workflow.queryEntitySelection': [
|
|
162
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
163
|
+
omsExampleDocHint,
|
|
164
|
+
],
|
|
165
|
+
'user.workflow.deleteEntityRow': [
|
|
166
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
167
|
+
omsExampleDocHint,
|
|
168
|
+
],
|
|
169
|
+
'user.workflow.restoreEntityRow': [
|
|
170
|
+
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
171
|
+
omsExampleDocHint,
|
|
172
|
+
],
|
|
173
|
+
'user.entity.updateEntityBulk': [
|
|
174
|
+
{ title: 'Search and bulk actions', file: '/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md' },
|
|
175
|
+
omsExampleDocHint,
|
|
176
|
+
],
|
|
177
|
+
};
|
|
178
|
+
export function getCommandDocHints(operation) {
|
|
179
|
+
const key = String(operation || '').trim();
|
|
180
|
+
if (!key)
|
|
181
|
+
return [];
|
|
182
|
+
return commandDocHintIndex[key] ?? [];
|
|
183
|
+
}
|
|
@@ -15,6 +15,7 @@ test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
|
15
15
|
ARCUBASE_BASE_URL: 'http://example.com',
|
|
16
16
|
ARCUBASE_TENANT_ID: 'tenant-1',
|
|
17
17
|
ARCUBASE_ACCESS_TOKEN: 'token-1',
|
|
18
|
+
ARCUBASE_HOST: undefined,
|
|
18
19
|
ARCUBASE_TRACE_ID: 'trace-1',
|
|
19
20
|
ARCUBASE_SUBJECT_TYPE: undefined,
|
|
20
21
|
ARCUBASE_SUBJECT_ID: undefined,
|
|
@@ -26,6 +27,7 @@ test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
|
26
27
|
ARCUBASE_ADMIN_BASE_URL: ' https://admin.example.com ',
|
|
27
28
|
ARCUBASE_ADMIN_TENANT_ID: ' tenant-admin ',
|
|
28
29
|
ARCUBASE_ADMIN_ACCESS_TOKEN: ' token-admin ',
|
|
30
|
+
ARCUBASE_ADMIN_HOST: ' tenant-admin.arcubase.co ',
|
|
29
31
|
ARCUBASE_ADMIN_SUBJECT_TYPE: ' system_admin ',
|
|
30
32
|
ARCUBASE_ADMIN_SUBJECT_ID: ' user-admin ',
|
|
31
33
|
});
|
|
@@ -33,6 +35,7 @@ test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
|
33
35
|
ARCUBASE_BASE_URL: 'https://admin.example.com',
|
|
34
36
|
ARCUBASE_TENANT_ID: 'tenant-admin',
|
|
35
37
|
ARCUBASE_ACCESS_TOKEN: 'token-admin',
|
|
38
|
+
ARCUBASE_HOST: 'tenant-admin.arcubase.co',
|
|
36
39
|
ARCUBASE_TRACE_ID: undefined,
|
|
37
40
|
ARCUBASE_SUBJECT_TYPE: 'system_admin',
|
|
38
41
|
ARCUBASE_SUBJECT_ID: 'user-admin',
|
|
@@ -44,6 +47,7 @@ test('loadRuntimeEnv accepts user-prefixed runtime env', () => {
|
|
|
44
47
|
ARCUBASE_USER_BASE_URL: ' https://user.example.com ',
|
|
45
48
|
ARCUBASE_USER_TENANT_ID: ' tenant-user ',
|
|
46
49
|
ARCUBASE_USER_ACCESS_TOKEN: ' token-user ',
|
|
50
|
+
ARCUBASE_USER_HOST: ' tenant-user.arcubase.co ',
|
|
47
51
|
ARCUBASE_USER_SUBJECT_TYPE: ' service_account ',
|
|
48
52
|
ARCUBASE_USER_SUBJECT_ID: ' sa-user ',
|
|
49
53
|
});
|
|
@@ -51,6 +55,7 @@ test('loadRuntimeEnv accepts user-prefixed runtime env', () => {
|
|
|
51
55
|
ARCUBASE_BASE_URL: 'https://user.example.com',
|
|
52
56
|
ARCUBASE_TENANT_ID: 'tenant-user',
|
|
53
57
|
ARCUBASE_ACCESS_TOKEN: 'token-user',
|
|
58
|
+
ARCUBASE_HOST: 'tenant-user.arcubase.co',
|
|
54
59
|
ARCUBASE_TRACE_ID: undefined,
|
|
55
60
|
ARCUBASE_SUBJECT_TYPE: 'service_account',
|
|
56
61
|
ARCUBASE_SUBJECT_ID: 'sa-user',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { adminCommands, userCommands } from '../generated/command_registry.generated.js';
|
|
4
|
+
import { findCommandSuggestions } from '../runtime/command_registry.js';
|
|
4
5
|
test('admin app create-entity command exists', () => {
|
|
5
6
|
assert.ok(adminCommands.some((c) => c.commandPath.join(' ') === 'app create-entity'));
|
|
6
7
|
});
|
|
@@ -20,3 +21,7 @@ test('tag commands no longer emit truncated inline request type', () => {
|
|
|
20
21
|
assert.match(String(typed.requestType), /^\{\s*policy_id:\s*string.*selection:\s*any.*tag_names:\s*string\[\]\s*\}$/);
|
|
21
22
|
assert.equal(typed.scalarParams.length, 0);
|
|
22
23
|
});
|
|
24
|
+
test('suggestions can point wrong admin delete guess to user workflow delete command', () => {
|
|
25
|
+
const suggestions = findCommandSuggestions('entity', 'admin-delete-entity-row');
|
|
26
|
+
assert.ok(suggestions.some((item) => item.binary === 'arcubase' && item.moduleName === 'workflow' && item.commandName === 'delete-entity-row'));
|
|
27
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity_save_schema.test.d.ts","sourceRoot":"","sources":["../../src/tests/entity_save_schema.test.ts"],"names":[],"mappings":""}
|