@carthooks/arcubase-cli 0.1.10 → 0.1.12
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 +1274 -375
- package/bundle/arcubase.mjs +1274 -375
- package/dist/generated/command_registry.generated.d.ts +36 -35
- package/dist/generated/command_registry.generated.d.ts.map +1 -1
- package/dist/generated/command_registry.generated.js +37 -36
- package/dist/generated/type_index.generated.d.ts +23 -23
- package/dist/generated/type_index.generated.js +23 -23
- package/dist/runtime/entity_save_schema.d.ts.map +1 -1
- package/dist/runtime/entity_save_schema.js +30 -0
- package/dist/runtime/env.d.ts +2 -1
- package/dist/runtime/env.d.ts.map +1 -1
- package/dist/runtime/env.js +10 -1
- package/dist/runtime/errors.d.ts +2 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/execute.d.ts +4 -2
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +944 -134
- package/dist/runtime/paths.d.ts +1 -1
- package/dist/runtime/paths.d.ts.map +1 -1
- package/dist/runtime/paths.js +9 -2
- package/dist/runtime/upload.d.ts +1 -11
- package/dist/runtime/upload.d.ts.map +1 -1
- package/dist/runtime/upload.js +19 -133
- package/dist/runtime/zod_registry.d.ts +5 -3
- package/dist/runtime/zod_registry.d.ts.map +1 -1
- package/dist/runtime/zod_registry.js +108 -48
- package/dist/tests/bootstrap.test.js +12 -0
- package/dist/tests/command_registry.test.js +8 -0
- package/dist/tests/docs_readability.test.d.ts +2 -0
- package/dist/tests/docs_readability.test.d.ts.map +1 -0
- package/dist/tests/docs_readability.test.js +87 -0
- package/dist/tests/entity_save_schema.test.js +22 -0
- package/dist/tests/execute_validation.test.js +381 -44
- package/dist/tests/help.test.js +45 -8
- package/dist/tests/upload.test.js +30 -77
- package/package.json +1 -1
- package/sdk-dist/docs/runtime-reference/README.md +43 -29
- package/sdk-dist/docs/runtime-reference/access-rule.md +109 -0
- package/sdk-dist/docs/runtime-reference/condition.md +182 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/README.md +6 -5
- package/sdk-dist/docs/runtime-reference/entity-schema/checkbox.md +1 -1
- package/sdk-dist/docs/runtime-reference/entity-schema/file.md +2 -2
- package/sdk-dist/docs/runtime-reference/entity-schema/image.md +2 -2
- package/sdk-dist/docs/runtime-reference/entity-schema/linkto.md +3 -3
- package/sdk-dist/docs/runtime-reference/entity-schema/number.md +1 -1
- package/sdk-dist/docs/runtime-reference/entity-schema/query.md +3 -3
- package/sdk-dist/docs/runtime-reference/entity-schema/relation.md +3 -3
- package/sdk-dist/docs/runtime-reference/entity-schema/relationfield.md +3 -3
- package/sdk-dist/docs/runtime-reference/entity-schema/status.md +1 -1
- package/sdk-dist/docs/runtime-reference/entity-schema/text.md +1 -1
- package/sdk-dist/docs/runtime-reference/entity-schema.md +28 -21
- package/sdk-dist/docs/runtime-reference/examples/README.md +1 -1
- package/sdk-dist/docs/runtime-reference/examples/crm-01/README.md +30 -11
- package/sdk-dist/docs/runtime-reference/examples/crm-01/contact.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/contact.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/create-app.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/customer.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/customer.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/follow-up.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/follow-up.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.bulk-update.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.query.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.row.insert.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/lead.selection.condition.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +26 -26
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.row.insert.json +1 -1
- package/sdk-dist/docs/runtime-reference/examples/wms-01/README.md +26 -10
- package/sdk-dist/docs/runtime-reference/examples/wms-01/create-app.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/goods-receipt.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/goods-receipt.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/inventory-snapshot.bulk-update.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/inventory-snapshot.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/inventory-snapshot.query.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/inventory-snapshot.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/inventory-snapshot.selection.condition.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/item-master.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/item-master.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/stock-issue.create-entity.json +1 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/stock-issue.schema.json +1 -0
- package/sdk-dist/docs/runtime-reference/row-crud.md +35 -8
- package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +31 -95
- package/sdk-dist/docs/runtime-reference/selection.md +128 -0
- package/sdk-dist/docs/runtime-reference/table-lifecycle.md +113 -30
- package/sdk-dist/docs/runtime-reference/uploads.md +30 -59
- package/sdk-dist/docs/runtime-reference/workflow/README.md +129 -13
- package/sdk-dist/generated/command_registry.generated.ts +37 -36
- package/sdk-dist/generated/type_index.generated.ts +23 -23
- package/src/generated/command_registry.generated.ts +37 -36
- package/src/generated/type_index.generated.ts +23 -23
- package/src/runtime/entity_save_schema.ts +30 -0
- package/src/runtime/env.ts +14 -2
- package/src/runtime/errors.ts +2 -0
- package/src/runtime/execute.ts +1166 -134
- package/src/runtime/paths.ts +11 -2
- package/src/runtime/upload.ts +19 -178
- package/src/runtime/zod_registry.ts +113 -48
- package/src/tests/bootstrap.test.ts +16 -0
- package/src/tests/command_registry.test.ts +9 -0
- package/src/tests/docs_readability.test.ts +96 -0
- package/src/tests/entity_save_schema.test.ts +22 -0
- package/src/tests/execute_validation.test.ts +508 -47
- package/src/tests/help.test.ts +49 -8
- package/src/tests/upload.test.ts +34 -91
package/dist/runtime/paths.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const DEFAULT_ARCUBASE_CLI_ROOT = "/opt/arcubase-cli";
|
|
2
|
-
export declare const DEFAULT_ARCUBASE_SDK_ROOT = "/opt/arcubase-sdk";
|
|
3
2
|
export declare function resolveArcubaseSDKRoot(env?: Record<string, string | undefined>): string;
|
|
3
|
+
export declare function resolveArcubaseSDKPath(filePath: string, env?: Record<string, string | undefined>): string;
|
|
4
4
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/runtime/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/runtime/paths.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAE5D,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAIpG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAMtH"}
|
package/dist/runtime/paths.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { CLIError } from './errors.js';
|
|
1
2
|
export const DEFAULT_ARCUBASE_CLI_ROOT = '/opt/arcubase-cli';
|
|
2
|
-
export const DEFAULT_ARCUBASE_SDK_ROOT = '/opt/arcubase-sdk';
|
|
3
3
|
export function resolveArcubaseSDKRoot(env = process.env) {
|
|
4
4
|
const value = env.ARCUBASE_SDK_ROOT?.trim();
|
|
5
5
|
if (value)
|
|
6
6
|
return value;
|
|
7
|
-
|
|
7
|
+
throw new CLIError('RUNTIME_ENV_REQUIRED', 'ARCUBASE_SDK_ROOT is required', 2);
|
|
8
|
+
}
|
|
9
|
+
export function resolveArcubaseSDKPath(filePath, env = process.env) {
|
|
10
|
+
const cleanPath = String(filePath || '').trim().replace(/^\/+/, '');
|
|
11
|
+
if (!cleanPath) {
|
|
12
|
+
throw new CLIError('RUNTIME_ENV_REQUIRED', 'ARCUBASE_SDK_ROOT path is required', 2);
|
|
13
|
+
}
|
|
14
|
+
return `${resolveArcubaseSDKRoot(env).replace(/\/+$/, '')}/${cleanPath}`;
|
|
8
15
|
}
|
package/dist/runtime/upload.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import type { RuntimeEnv } from './env.js';
|
|
2
|
-
export type ArcubaseUploadResult = {
|
|
3
|
-
upload_id: number | string;
|
|
4
|
-
file: string;
|
|
5
|
-
file_name: string;
|
|
6
|
-
meta: Record<string, never>;
|
|
7
|
-
};
|
|
8
1
|
export declare function renderUploadHelp(): string;
|
|
9
|
-
export declare function uploadLocalFile(
|
|
10
|
-
filename?: string;
|
|
11
|
-
global?: boolean;
|
|
12
|
-
}, fetchImpl?: typeof fetch): Promise<ArcubaseUploadResult[]>;
|
|
2
|
+
export declare function uploadLocalFile(): Promise<never>;
|
|
13
3
|
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/runtime/upload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/runtime/upload.ts"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,IAAI,MAAM,CAuBzC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC,CAItD"}
|
package/dist/runtime/upload.js
CHANGED
|
@@ -1,148 +1,34 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
1
|
import { CLIError } from './errors.js';
|
|
4
|
-
import {
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
if (!fs.existsSync(absolutePath)) {
|
|
8
|
-
throw new CLIError('UPLOAD_SOURCE_NOT_FOUND', `upload source file does not exist: ${sourcePath}`, 2);
|
|
9
|
-
}
|
|
10
|
-
const stat = fs.statSync(absolutePath);
|
|
11
|
-
if (!stat.isFile()) {
|
|
12
|
-
throw new CLIError('UPLOAD_SOURCE_INVALID', `upload source path must be a file: ${sourcePath}`, 2);
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
absolutePath,
|
|
16
|
-
bytes: fs.readFileSync(absolutePath),
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
function parseJSONResponse(raw) {
|
|
20
|
-
try {
|
|
21
|
-
return raw ? JSON.parse(raw) : null;
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return raw;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function requireTokenPayload(payload) {
|
|
28
|
-
if (payload && typeof payload === 'object' && payload.error) {
|
|
29
|
-
const upstreamError = payload.error;
|
|
30
|
-
const message = typeof upstreamError === 'object' && upstreamError && 'message' in upstreamError && typeof upstreamError.message === 'string'
|
|
31
|
-
? upstreamError.message
|
|
32
|
-
: typeof upstreamError === 'string'
|
|
33
|
-
? upstreamError
|
|
34
|
-
: JSON.stringify(upstreamError);
|
|
35
|
-
throw new CLIError('UPSTREAM_BODY_ERROR', message, 1, {
|
|
36
|
-
endpoint: '/api/upload/token',
|
|
37
|
-
method: 'POST',
|
|
38
|
-
traceId: typeof payload.trace_id === 'string' ? payload.trace_id : undefined,
|
|
39
|
-
upstreamError,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
if (!payload?.data || typeof payload.data !== 'object') {
|
|
43
|
-
throw new CLIError('UPLOAD_TOKEN_INVALID', 'upload token response did not include data', 1);
|
|
44
|
-
}
|
|
45
|
-
return payload.data;
|
|
2
|
+
import { resolveArcubaseSDKPath } from './paths.js';
|
|
3
|
+
function sdkPath(file) {
|
|
4
|
+
return resolveArcubaseSDKPath(file);
|
|
46
5
|
}
|
|
47
6
|
export function renderUploadHelp() {
|
|
48
7
|
return [
|
|
49
|
-
'arcubase upload <
|
|
8
|
+
'arcubase upload <command> [flags]',
|
|
50
9
|
'',
|
|
51
10
|
'purpose:',
|
|
52
|
-
' -
|
|
53
|
-
' -
|
|
54
|
-
'',
|
|
55
|
-
'flags:',
|
|
56
|
-
' --filename <name> override the uploaded filename stored in Arcubase',
|
|
57
|
-
' --global request a global upload token instead of a tenant-scoped token',
|
|
11
|
+
' - call explicit Arcubase upload APIs',
|
|
12
|
+
' - keep file transfer outside this CLI surface',
|
|
58
13
|
'',
|
|
59
|
-
'
|
|
60
|
-
' -
|
|
61
|
-
' -
|
|
14
|
+
'commands:',
|
|
15
|
+
' - token',
|
|
16
|
+
' - preview',
|
|
17
|
+
' - mobile',
|
|
18
|
+
' - check-mobile',
|
|
62
19
|
'',
|
|
63
20
|
'example:',
|
|
64
|
-
' arcubase upload
|
|
65
|
-
' arcubase upload ./photo.jpg --filename lead-photo.jpg',
|
|
21
|
+
' arcubase upload token --body-json \'{"global":false}\'',
|
|
66
22
|
'',
|
|
67
23
|
'docs:',
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
24
|
+
` - Uploads: ${sdkPath('docs/runtime-reference/uploads.md')}`,
|
|
25
|
+
` - Row CRUD: ${sdkPath('docs/runtime-reference/row-crud.md')}`,
|
|
26
|
+
` - File field: ${sdkPath('docs/runtime-reference/entity-schema/file.md')}`,
|
|
27
|
+
` - Image field: ${sdkPath('docs/runtime-reference/entity-schema/image.md')}`,
|
|
72
28
|
].join('\n');
|
|
73
29
|
}
|
|
74
|
-
export async function uploadLocalFile(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const tokenResponse = await fetchImpl(buildURL(env.ARCUBASE_BASE_URL, '/api/upload/token'), {
|
|
78
|
-
method: 'POST',
|
|
79
|
-
headers: {
|
|
80
|
-
...buildRequestHeaders(env),
|
|
81
|
-
'Content-Type': 'application/json',
|
|
82
|
-
},
|
|
83
|
-
body: JSON.stringify({
|
|
84
|
-
global: Boolean(options.global),
|
|
85
|
-
}),
|
|
30
|
+
export async function uploadLocalFile() {
|
|
31
|
+
throw new CLIError('UNSUPPORTED_COMMAND', 'local file upload is not part of the reset CLI surface; use upload token APIs instead', 2, {
|
|
32
|
+
docHints: [{ title: 'Uploads', file: sdkPath('docs/runtime-reference/uploads.md') }],
|
|
86
33
|
});
|
|
87
|
-
const tokenRaw = await tokenResponse.text();
|
|
88
|
-
const tokenParsed = parseJSONResponse(tokenRaw);
|
|
89
|
-
if (!tokenResponse.ok) {
|
|
90
|
-
throw new CLIError('UPLOAD_TOKEN_REQUEST_FAILED', typeof tokenParsed === 'string' ? tokenParsed : JSON.stringify(tokenParsed), 1, {
|
|
91
|
-
endpoint: '/api/upload/token',
|
|
92
|
-
method: 'POST',
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
const tokenData = requireTokenPayload(tokenParsed);
|
|
96
|
-
if (tokenData.mode !== 'aliyun-oss' && tokenData.mode !== 's3-post-policy') {
|
|
97
|
-
throw new CLIError('UPLOAD_MODE_UNSUPPORTED', `unsupported upload mode: ${String(tokenData.mode || '')}`, 1);
|
|
98
|
-
}
|
|
99
|
-
if (!tokenData.token_data?.dir || !tokenData.token_data.policy || !tokenData.token_data.host) {
|
|
100
|
-
throw new CLIError('UPLOAD_TOKEN_INVALID', 'upload token response is missing required token_data fields', 1);
|
|
101
|
-
}
|
|
102
|
-
if (tokenData.id === undefined || tokenData.id === null || tokenData.id === '') {
|
|
103
|
-
throw new CLIError('UPLOAD_TOKEN_INVALID', 'upload token response is missing id', 1);
|
|
104
|
-
}
|
|
105
|
-
const form = new FormData();
|
|
106
|
-
form.append('key', `${tokenData.token_data.dir}${filename}`);
|
|
107
|
-
form.append('policy', tokenData.token_data.policy);
|
|
108
|
-
if (tokenData.mode === 'aliyun-oss') {
|
|
109
|
-
if (!tokenData.token_data.accessid || !tokenData.token_data.signature) {
|
|
110
|
-
throw new CLIError('UPLOAD_TOKEN_INVALID', 'upload token response is missing required token_data fields', 1);
|
|
111
|
-
}
|
|
112
|
-
form.append('OSSAccessKeyId', tokenData.token_data.accessid);
|
|
113
|
-
form.append('success_action_status', '200');
|
|
114
|
-
form.append('signature', tokenData.token_data.signature);
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
if (!tokenData.token_data.x_amz_algorithm ||
|
|
118
|
-
!tokenData.token_data.x_amz_credential ||
|
|
119
|
-
!tokenData.token_data.x_amz_date ||
|
|
120
|
-
!tokenData.token_data.x_amz_signature) {
|
|
121
|
-
throw new CLIError('UPLOAD_TOKEN_INVALID', 'upload token response is missing required s3 token_data fields', 1);
|
|
122
|
-
}
|
|
123
|
-
form.append('x-amz-algorithm', tokenData.token_data.x_amz_algorithm);
|
|
124
|
-
form.append('x-amz-credential', tokenData.token_data.x_amz_credential);
|
|
125
|
-
form.append('x-amz-date', tokenData.token_data.x_amz_date);
|
|
126
|
-
form.append('x-amz-signature', tokenData.token_data.x_amz_signature);
|
|
127
|
-
}
|
|
128
|
-
form.append('file', new Blob([new Uint8Array(bytes)]), filename);
|
|
129
|
-
const uploadResponse = await fetchImpl(tokenData.token_data.host, {
|
|
130
|
-
method: 'POST',
|
|
131
|
-
body: form,
|
|
132
|
-
});
|
|
133
|
-
const uploadRaw = await uploadResponse.text();
|
|
134
|
-
if (!uploadResponse.ok) {
|
|
135
|
-
throw new CLIError('UPLOAD_TRANSFER_FAILED', uploadRaw || `upload failed with status ${uploadResponse.status}`, 1, {
|
|
136
|
-
endpoint: tokenData.token_data.host,
|
|
137
|
-
method: 'POST',
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
return [
|
|
141
|
-
{
|
|
142
|
-
upload_id: tokenData.id,
|
|
143
|
-
file: filename,
|
|
144
|
-
file_name: filename,
|
|
145
|
-
meta: {},
|
|
146
|
-
},
|
|
147
|
-
];
|
|
148
34
|
}
|
|
@@ -10,7 +10,9 @@ export type RuntimeDocHint = {
|
|
|
10
10
|
title: string;
|
|
11
11
|
file: string;
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
export declare function
|
|
15
|
-
export declare function
|
|
13
|
+
type EnvInput = Record<string, string | undefined>;
|
|
14
|
+
export declare function getTypeHints(typeName: string, env?: EnvInput): RuntimeTypeHint[];
|
|
15
|
+
export declare function getDocHints(typeName: string, env?: EnvInput): RuntimeDocHint[];
|
|
16
|
+
export declare function getCommandDocHints(operation: string, env?: EnvInput): RuntimeDocHint[];
|
|
17
|
+
export {};
|
|
16
18
|
//# 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;AA8BrC,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;AAED,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAyGlD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,QAAsB,GAAG,eAAe,EAAE,CAqB7F;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,QAAsB,GAAG,cAAc,EAAE,CAI3F;AAwED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAE,QAAsB,GAAG,cAAc,EAAE,CAInG"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { bodySchemas, unsupportedBodySchemas } from '../generated/zod_registry.generated.js';
|
|
2
2
|
import { typeIndex } from '../generated/type_index.generated.js';
|
|
3
|
+
import { resolveArcubaseSDKPath } from './paths.js';
|
|
3
4
|
import { AppCreateByTenantsReqVOSchemaOverride, EntityBulkUpdateReqVOSchemaOverride, EntityInvokeBatchOperatorReqVOSchemaOverride, EntityQueryReqVOSchemaOverride, EntitySaveReqVOSchemaOverride, EntitySelectionActionReqVOSchemaOverride, EntityTagsBatchReqVOSchemaOverride, EntityTagsSelectionReqVOSchemaOverride, EntityUpdateReqVOSchemaOverride, InsertReqVOSchemaOverride, } from './entity_save_schema.js';
|
|
4
5
|
const schemaOverrides = {
|
|
5
6
|
AppCreateByTenantsReqVO: AppCreateByTenantsReqVOSchemaOverride,
|
|
@@ -38,60 +39,105 @@ export function requireBodySchema(typeName) {
|
|
|
38
39
|
}
|
|
39
40
|
throw new Error(`runtime validation schema not found for ${typeName}`);
|
|
40
41
|
}
|
|
42
|
+
function sdkPath(file, env = process.env) {
|
|
43
|
+
return resolveArcubaseSDKPath(file.replace(/^\/?opt\/arcubase-sdk\/?/, ''), env);
|
|
44
|
+
}
|
|
45
|
+
function resolveTypeHintFiles(hints, env = process.env) {
|
|
46
|
+
return hints.map((item) => ({ ...item, file: sdkPath(item.file, env) }));
|
|
47
|
+
}
|
|
48
|
+
function resolveDocHintFiles(hints, env = process.env) {
|
|
49
|
+
return hints.map((item) => ({ ...item, file: sdkPath(item.file, env) }));
|
|
50
|
+
}
|
|
41
51
|
const examplesIndexDocHint = {
|
|
42
52
|
title: 'Examples index',
|
|
43
|
-
file: '
|
|
53
|
+
file: 'docs/runtime-reference/examples/README.md',
|
|
54
|
+
};
|
|
55
|
+
const selectionDocHint = {
|
|
56
|
+
title: 'Selection',
|
|
57
|
+
file: 'docs/runtime-reference/selection.md',
|
|
58
|
+
};
|
|
59
|
+
const conditionDocHint = {
|
|
60
|
+
title: 'Condition',
|
|
61
|
+
file: 'docs/runtime-reference/condition.md',
|
|
44
62
|
};
|
|
45
63
|
const docHintIndex = {
|
|
46
64
|
AppCreateByTenantsReqVO: [
|
|
47
|
-
{ title: 'Table lifecycle', file: '
|
|
65
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
48
66
|
examplesIndexDocHint,
|
|
49
67
|
],
|
|
50
68
|
AppCreateEntityReqVO: [
|
|
51
|
-
{ title: 'Table lifecycle', file: '
|
|
69
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
70
|
+
{ title: 'Table schema cheatsheet', file: 'docs/runtime-reference/entity-schema.md' },
|
|
71
|
+
{ title: 'Field type index', file: 'docs/runtime-reference/entity-schema/README.md' },
|
|
72
|
+
examplesIndexDocHint,
|
|
73
|
+
],
|
|
74
|
+
AppIngressCreateReqVO: [
|
|
75
|
+
{ title: 'Access rule', file: 'docs/runtime-reference/access-rule.md' },
|
|
76
|
+
examplesIndexDocHint,
|
|
77
|
+
],
|
|
78
|
+
AppIngressUpdateReqVO: [
|
|
79
|
+
{ title: 'Access rule', file: 'docs/runtime-reference/access-rule.md' },
|
|
52
80
|
examplesIndexDocHint,
|
|
53
81
|
],
|
|
54
82
|
EntitySaveReqVO: [
|
|
55
|
-
{ title: '
|
|
83
|
+
{ title: 'Table schema cheatsheet', file: 'docs/runtime-reference/entity-schema.md' },
|
|
84
|
+
{ title: 'Field type index', file: 'docs/runtime-reference/entity-schema/README.md' },
|
|
85
|
+
{ title: 'Text field', file: 'docs/runtime-reference/entity-schema/text.md' },
|
|
86
|
+
{ title: 'Textarea field', file: 'docs/runtime-reference/entity-schema/textarea.md' },
|
|
87
|
+
{ title: 'Number field', file: 'docs/runtime-reference/entity-schema/number.md' },
|
|
88
|
+
{ title: 'Datetime field', file: 'docs/runtime-reference/entity-schema/datetime.md' },
|
|
89
|
+
{ title: 'Boolean field', file: 'docs/runtime-reference/entity-schema/boolean.md' },
|
|
90
|
+
{ title: 'Select field', file: 'docs/runtime-reference/entity-schema/select.md' },
|
|
56
91
|
examplesIndexDocHint,
|
|
57
92
|
],
|
|
58
93
|
EntityQueryReqVO: [
|
|
59
|
-
{ title: 'Row CRUD', file: '
|
|
60
|
-
{ title: 'Search and bulk actions', file: '
|
|
94
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
95
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
96
|
+
conditionDocHint,
|
|
61
97
|
examplesIndexDocHint,
|
|
62
98
|
],
|
|
63
99
|
EntityUpdateReqVO: [
|
|
64
|
-
{ title: 'Row CRUD', file: '
|
|
65
|
-
{ title: 'Uploads', file: '
|
|
100
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
101
|
+
{ title: 'Uploads', file: 'docs/runtime-reference/uploads.md' },
|
|
66
102
|
examplesIndexDocHint,
|
|
67
103
|
],
|
|
68
104
|
EntitySelectionActionReqVO: [
|
|
69
|
-
|
|
105
|
+
selectionDocHint,
|
|
106
|
+
conditionDocHint,
|
|
107
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
70
108
|
examplesIndexDocHint,
|
|
71
109
|
],
|
|
72
110
|
InsertReqVO: [
|
|
73
|
-
{ title: 'Row CRUD', file: '
|
|
74
|
-
{ title: 'Uploads', file: '
|
|
111
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
112
|
+
{ title: 'Uploads', file: 'docs/runtime-reference/uploads.md' },
|
|
75
113
|
examplesIndexDocHint,
|
|
76
114
|
],
|
|
77
115
|
EntityBulkUpdateReqVO: [
|
|
78
|
-
|
|
116
|
+
selectionDocHint,
|
|
117
|
+
conditionDocHint,
|
|
118
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
79
119
|
examplesIndexDocHint,
|
|
80
120
|
],
|
|
81
121
|
'EntityInvokeBatchOperatorReqVO & InvokeRequestVO': [
|
|
82
|
-
|
|
122
|
+
selectionDocHint,
|
|
123
|
+
conditionDocHint,
|
|
124
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
83
125
|
examplesIndexDocHint,
|
|
84
126
|
],
|
|
85
127
|
'{ policy_id: string selection: any }': [
|
|
86
|
-
|
|
128
|
+
selectionDocHint,
|
|
129
|
+
conditionDocHint,
|
|
130
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
87
131
|
examplesIndexDocHint,
|
|
88
132
|
],
|
|
89
133
|
'{ policy_id: string selection: any tag_names: string[] }': [
|
|
90
|
-
|
|
134
|
+
selectionDocHint,
|
|
135
|
+
conditionDocHint,
|
|
136
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
91
137
|
examplesIndexDocHint,
|
|
92
138
|
],
|
|
93
139
|
};
|
|
94
|
-
export function getTypeHints(typeName) {
|
|
140
|
+
export function getTypeHints(typeName, env = process.env) {
|
|
95
141
|
const name = String(typeName || '').trim();
|
|
96
142
|
if (!name)
|
|
97
143
|
return [];
|
|
@@ -115,72 +161,86 @@ export function getTypeHints(typeName) {
|
|
|
115
161
|
for (const dep of entry.dependencies ?? []) {
|
|
116
162
|
append(dep.symbol, dep.file);
|
|
117
163
|
}
|
|
118
|
-
return out;
|
|
164
|
+
return resolveTypeHintFiles(out, env);
|
|
119
165
|
}
|
|
120
|
-
export function getDocHints(typeName) {
|
|
166
|
+
export function getDocHints(typeName, env = process.env) {
|
|
121
167
|
const name = String(typeName || '').trim();
|
|
122
168
|
if (!name)
|
|
123
169
|
return [];
|
|
124
|
-
return docHintIndex[name] ?? [];
|
|
170
|
+
return resolveDocHintFiles(docHintIndex[name] ?? [], env);
|
|
125
171
|
}
|
|
126
172
|
const commandDocHintIndex = {
|
|
127
173
|
'admin.app.createAppByTenants': [
|
|
128
|
-
{ title: 'Table lifecycle', file: '
|
|
174
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
129
175
|
examplesIndexDocHint,
|
|
130
176
|
],
|
|
131
177
|
'admin.app.createEntity': [
|
|
132
|
-
{ title: 'Table lifecycle', file: '
|
|
178
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
179
|
+
examplesIndexDocHint,
|
|
180
|
+
],
|
|
181
|
+
'admin.table.adminGetEntityInfo': [
|
|
182
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
183
|
+
examplesIndexDocHint,
|
|
184
|
+
],
|
|
185
|
+
'admin.table.adminSaveEntity': [
|
|
186
|
+
{ title: 'Table schema cheatsheet', file: 'docs/runtime-reference/entity-schema.md' },
|
|
187
|
+
{ title: 'Field type index', file: 'docs/runtime-reference/entity-schema/README.md' },
|
|
188
|
+
{ title: 'Table lifecycle', file: 'docs/runtime-reference/table-lifecycle.md' },
|
|
189
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
133
190
|
examplesIndexDocHint,
|
|
134
191
|
],
|
|
135
|
-
'admin.
|
|
136
|
-
{ title: '
|
|
192
|
+
'admin.access-rule.createEntityIngress': [
|
|
193
|
+
{ title: 'Access rule', file: 'docs/runtime-reference/access-rule.md' },
|
|
137
194
|
examplesIndexDocHint,
|
|
138
195
|
],
|
|
139
|
-
'admin.
|
|
140
|
-
{ title: '
|
|
141
|
-
{ title: 'Table lifecycle', file: '/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md' },
|
|
142
|
-
{ title: 'Row CRUD', file: '/opt/arcubase-sdk/docs/runtime-reference/row-crud.md' },
|
|
196
|
+
'admin.access-rule.updateEntityIngress': [
|
|
197
|
+
{ title: 'Access rule', file: 'docs/runtime-reference/access-rule.md' },
|
|
143
198
|
examplesIndexDocHint,
|
|
144
199
|
],
|
|
145
|
-
'user.
|
|
146
|
-
{ title: 'Row CRUD', file: '
|
|
147
|
-
{ title: 'Uploads', file: '
|
|
200
|
+
'user.row.insertEntity': [
|
|
201
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
202
|
+
{ title: 'Uploads', file: 'docs/runtime-reference/uploads.md' },
|
|
148
203
|
examplesIndexDocHint,
|
|
149
204
|
],
|
|
150
|
-
'user.
|
|
151
|
-
{ title: 'Search and bulk actions', file: '
|
|
152
|
-
|
|
205
|
+
'user.row.queryEntity': [
|
|
206
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
207
|
+
conditionDocHint,
|
|
208
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
153
209
|
examplesIndexDocHint,
|
|
154
210
|
],
|
|
155
|
-
'user.
|
|
156
|
-
{ title: 'Row CRUD', file: '
|
|
211
|
+
'user.row.getEntityRow': [
|
|
212
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
157
213
|
examplesIndexDocHint,
|
|
158
214
|
],
|
|
159
|
-
'user.
|
|
160
|
-
{ title: 'Row CRUD', file: '
|
|
161
|
-
{ title: 'Uploads', file: '
|
|
215
|
+
'user.row.updateEntityRow': [
|
|
216
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
217
|
+
{ title: 'Uploads', file: 'docs/runtime-reference/uploads.md' },
|
|
162
218
|
examplesIndexDocHint,
|
|
163
219
|
],
|
|
164
|
-
'user.
|
|
165
|
-
|
|
220
|
+
'user.row.queryEntitySelection': [
|
|
221
|
+
selectionDocHint,
|
|
222
|
+
conditionDocHint,
|
|
223
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
166
224
|
examplesIndexDocHint,
|
|
167
225
|
],
|
|
168
|
-
'user.
|
|
169
|
-
{ title: 'Row CRUD', file: '
|
|
226
|
+
'user.row.deleteEntityRow': [
|
|
227
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
170
228
|
examplesIndexDocHint,
|
|
171
229
|
],
|
|
172
|
-
'user.
|
|
173
|
-
{ title: 'Row CRUD', file: '
|
|
230
|
+
'user.row.restoreEntityRow': [
|
|
231
|
+
{ title: 'Row CRUD', file: 'docs/runtime-reference/row-crud.md' },
|
|
174
232
|
examplesIndexDocHint,
|
|
175
233
|
],
|
|
176
|
-
'user.
|
|
177
|
-
|
|
234
|
+
'user.row.updateEntityBulk': [
|
|
235
|
+
selectionDocHint,
|
|
236
|
+
conditionDocHint,
|
|
237
|
+
{ title: 'Search and bulk actions', file: 'docs/runtime-reference/search-and-bulk-actions.md' },
|
|
178
238
|
examplesIndexDocHint,
|
|
179
239
|
],
|
|
180
240
|
};
|
|
181
|
-
export function getCommandDocHints(operation) {
|
|
241
|
+
export function getCommandDocHints(operation, env = process.env) {
|
|
182
242
|
const key = String(operation || '').trim();
|
|
183
243
|
if (!key)
|
|
184
244
|
return [];
|
|
185
|
-
return commandDocHintIndex[key] ?? [];
|
|
245
|
+
return resolveDocHintFiles(commandDocHintIndex[key] ?? [], env);
|
|
186
246
|
}
|
|
@@ -4,15 +4,23 @@ import { loadRuntimeEnv } from '../runtime/env.js';
|
|
|
4
4
|
test('loadRuntimeEnv requires base url and access token', () => {
|
|
5
5
|
assert.throws(() => loadRuntimeEnv('admin', {}), /ARCUBASE_BASE_URL is required/);
|
|
6
6
|
});
|
|
7
|
+
test('loadRuntimeEnv requires injected SDK root without fallback', () => {
|
|
8
|
+
assert.throws(() => loadRuntimeEnv('admin', {
|
|
9
|
+
ARCUBASE_BASE_URL: 'http://example.com',
|
|
10
|
+
ARCUBASE_ACCESS_TOKEN: 'token-1',
|
|
11
|
+
}), /ARCUBASE_SDK_ROOT is required/);
|
|
12
|
+
});
|
|
7
13
|
test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
8
14
|
const env = loadRuntimeEnv('admin', {
|
|
9
15
|
ARCUBASE_BASE_URL: ' http://example.com ',
|
|
10
16
|
ARCUBASE_ACCESS_TOKEN: ' token-1 ',
|
|
17
|
+
ARCUBASE_SDK_ROOT: ' /runtime/arcubase-sdk ',
|
|
11
18
|
ARCUBASE_TRACE_ID: ' trace-1 '
|
|
12
19
|
});
|
|
13
20
|
assert.deepEqual(env, {
|
|
14
21
|
ARCUBASE_BASE_URL: 'http://example.com',
|
|
15
22
|
ARCUBASE_ACCESS_TOKEN: 'token-1',
|
|
23
|
+
ARCUBASE_SDK_ROOT: '/runtime/arcubase-sdk',
|
|
16
24
|
ARCUBASE_TRACE_ID: 'trace-1',
|
|
17
25
|
ARCUBASE_SUBJECT_TYPE: undefined,
|
|
18
26
|
ARCUBASE_SUBJECT_ID: undefined,
|
|
@@ -23,12 +31,14 @@ test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
|
23
31
|
const env = loadRuntimeEnv('admin', {
|
|
24
32
|
ARCUBASE_ADMIN_BASE_URL: ' https://admin.example.com ',
|
|
25
33
|
ARCUBASE_ADMIN_ACCESS_TOKEN: ' token-admin ',
|
|
34
|
+
ARCUBASE_SDK_ROOT: '/runtime/arcubase-sdk',
|
|
26
35
|
ARCUBASE_ADMIN_SUBJECT_TYPE: ' system_admin ',
|
|
27
36
|
ARCUBASE_ADMIN_SUBJECT_ID: ' user-admin ',
|
|
28
37
|
});
|
|
29
38
|
assert.deepEqual(env, {
|
|
30
39
|
ARCUBASE_BASE_URL: 'https://admin.example.com',
|
|
31
40
|
ARCUBASE_ACCESS_TOKEN: 'token-admin',
|
|
41
|
+
ARCUBASE_SDK_ROOT: '/runtime/arcubase-sdk',
|
|
32
42
|
ARCUBASE_TRACE_ID: undefined,
|
|
33
43
|
ARCUBASE_SUBJECT_TYPE: 'system_admin',
|
|
34
44
|
ARCUBASE_SUBJECT_ID: 'user-admin',
|
|
@@ -39,12 +49,14 @@ test('loadRuntimeEnv accepts user-prefixed runtime env', () => {
|
|
|
39
49
|
const env = loadRuntimeEnv('user', {
|
|
40
50
|
ARCUBASE_USER_BASE_URL: ' https://user.example.com ',
|
|
41
51
|
ARCUBASE_USER_ACCESS_TOKEN: ' token-user ',
|
|
52
|
+
ARCUBASE_SDK_ROOT: '/runtime/arcubase-sdk',
|
|
42
53
|
ARCUBASE_USER_SUBJECT_TYPE: ' service_account ',
|
|
43
54
|
ARCUBASE_USER_SUBJECT_ID: ' sa-user ',
|
|
44
55
|
});
|
|
45
56
|
assert.deepEqual(env, {
|
|
46
57
|
ARCUBASE_BASE_URL: 'https://user.example.com',
|
|
47
58
|
ARCUBASE_ACCESS_TOKEN: 'token-user',
|
|
59
|
+
ARCUBASE_SDK_ROOT: '/runtime/arcubase-sdk',
|
|
48
60
|
ARCUBASE_TRACE_ID: undefined,
|
|
49
61
|
ARCUBASE_SUBJECT_TYPE: 'service_account',
|
|
50
62
|
ARCUBASE_SUBJECT_ID: 'sa-user',
|
|
@@ -63,6 +63,12 @@ test('user surface is restricted to reset white list', () => {
|
|
|
63
63
|
].sort();
|
|
64
64
|
assert.deepEqual(actual, expected);
|
|
65
65
|
});
|
|
66
|
+
test('generated modules use CLI namespaces only', () => {
|
|
67
|
+
const adminModules = [...new Set(adminCommands.map((item) => item.module))].sort();
|
|
68
|
+
const userModules = [...new Set(userCommands.map((item) => item.module))].sort();
|
|
69
|
+
assert.deepEqual(adminModules, ['access-rule', 'app', 'table', 'workflow']);
|
|
70
|
+
assert.deepEqual(userModules, ['entry', 'profile', 'row', 'table', 'upload', 'workflow']);
|
|
71
|
+
});
|
|
66
72
|
test('black list commands are removed from registry', () => {
|
|
67
73
|
const all = new Set([...commandPaths(adminCommands), ...commandPaths(userCommands)]);
|
|
68
74
|
const forbidden = [
|
|
@@ -74,6 +80,8 @@ test('black list commands are removed from registry', () => {
|
|
|
74
80
|
'ingress create-entity-ingress',
|
|
75
81
|
'workflow query-entity',
|
|
76
82
|
'workflow insert-entity',
|
|
83
|
+
'workflow prepare-entity-insert',
|
|
84
|
+
'workflow get-entity-row',
|
|
77
85
|
'workflow update-entity-row',
|
|
78
86
|
'workflow delete-entity-row',
|
|
79
87
|
'workflow restore-entity-row',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs_readability.test.d.ts","sourceRoot":"","sources":["../../src/tests/docs_readability.test.ts"],"names":[],"mappings":""}
|