@carthooks/arcubase-cli 0.1.6 → 0.1.7
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 +1 -7
- package/bundle/arcubase.mjs +1 -7
- package/dist/runtime/env.d.ts +0 -2
- package/dist/runtime/env.d.ts.map +1 -1
- package/dist/runtime/env.js +0 -2
- package/dist/runtime/http.d.ts +1 -1
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +0 -4
- package/dist/tests/bootstrap.test.js +1 -12
- package/dist/tests/execute_validation.test.js +4 -4
- package/dist/tests/help.test.js +0 -1
- package/dist/tests/upload.test.js +0 -1
- package/package.json +1 -1
- package/sdk-dist/docs/runtime-reference/README.md +0 -6
- package/sdk-dist/docs/runtime-reference/app-discovery.md +0 -16
- package/src/runtime/env.ts +0 -4
- package/src/runtime/http.ts +1 -5
- package/src/tests/bootstrap.test.ts +1 -12
- package/src/tests/execute_validation.test.ts +4 -4
- package/src/tests/help.test.ts +0 -1
- package/src/tests/upload.test.ts +0 -1
|
@@ -92,9 +92,7 @@ function optionalValue(env, scope, key) {
|
|
|
92
92
|
function loadRuntimeEnv(scope, env = process.env) {
|
|
93
93
|
return {
|
|
94
94
|
ARCUBASE_BASE_URL: requiredValue(env, scope, "ARCUBASE_BASE_URL"),
|
|
95
|
-
ARCUBASE_TENANT_ID: requiredValue(env, scope, "ARCUBASE_TENANT_ID"),
|
|
96
95
|
ARCUBASE_ACCESS_TOKEN: requiredValue(env, scope, "ARCUBASE_ACCESS_TOKEN"),
|
|
97
|
-
ARCUBASE_HOST: optionalValue(env, scope, "ARCUBASE_HOST"),
|
|
98
96
|
ARCUBASE_TRACE_ID: optionalValue(env, scope, "ARCUBASE_TRACE_ID"),
|
|
99
97
|
ARCUBASE_SUBJECT_TYPE: optionalValue(env, scope, "ARCUBASE_SUBJECT_TYPE"),
|
|
100
98
|
ARCUBASE_SUBJECT_ID: optionalValue(env, scope, "ARCUBASE_SUBJECT_ID"),
|
|
@@ -105,12 +103,8 @@ function loadRuntimeEnv(scope, env = process.env) {
|
|
|
105
103
|
// src/runtime/http.ts
|
|
106
104
|
function buildRequestHeaders(env) {
|
|
107
105
|
const headers = {
|
|
108
|
-
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}
|
|
109
|
-
"X-Tenant-Id": env.ARCUBASE_TENANT_ID
|
|
106
|
+
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}`
|
|
110
107
|
};
|
|
111
|
-
if (env.ARCUBASE_HOST && env.ARCUBASE_HOST.trim() !== "") {
|
|
112
|
-
headers["X-Host"] = env.ARCUBASE_HOST;
|
|
113
|
-
}
|
|
114
108
|
if (env.ARCUBASE_TRACE_ID) {
|
|
115
109
|
headers["X-Trace-Id"] = env.ARCUBASE_TRACE_ID;
|
|
116
110
|
}
|
package/bundle/arcubase.mjs
CHANGED
|
@@ -92,9 +92,7 @@ function optionalValue(env, scope, key) {
|
|
|
92
92
|
function loadRuntimeEnv(scope, env = process.env) {
|
|
93
93
|
return {
|
|
94
94
|
ARCUBASE_BASE_URL: requiredValue(env, scope, "ARCUBASE_BASE_URL"),
|
|
95
|
-
ARCUBASE_TENANT_ID: requiredValue(env, scope, "ARCUBASE_TENANT_ID"),
|
|
96
95
|
ARCUBASE_ACCESS_TOKEN: requiredValue(env, scope, "ARCUBASE_ACCESS_TOKEN"),
|
|
97
|
-
ARCUBASE_HOST: optionalValue(env, scope, "ARCUBASE_HOST"),
|
|
98
96
|
ARCUBASE_TRACE_ID: optionalValue(env, scope, "ARCUBASE_TRACE_ID"),
|
|
99
97
|
ARCUBASE_SUBJECT_TYPE: optionalValue(env, scope, "ARCUBASE_SUBJECT_TYPE"),
|
|
100
98
|
ARCUBASE_SUBJECT_ID: optionalValue(env, scope, "ARCUBASE_SUBJECT_ID"),
|
|
@@ -105,12 +103,8 @@ function loadRuntimeEnv(scope, env = process.env) {
|
|
|
105
103
|
// src/runtime/http.ts
|
|
106
104
|
function buildRequestHeaders(env) {
|
|
107
105
|
const headers = {
|
|
108
|
-
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}
|
|
109
|
-
"X-Tenant-Id": env.ARCUBASE_TENANT_ID
|
|
106
|
+
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}`
|
|
110
107
|
};
|
|
111
|
-
if (env.ARCUBASE_HOST && env.ARCUBASE_HOST.trim() !== "") {
|
|
112
|
-
headers["X-Host"] = env.ARCUBASE_HOST;
|
|
113
|
-
}
|
|
114
108
|
if (env.ARCUBASE_TRACE_ID) {
|
|
115
109
|
headers["X-Trace-Id"] = env.ARCUBASE_TRACE_ID;
|
|
116
110
|
}
|
package/dist/runtime/env.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/runtime/env.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/runtime/env.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAA;AAE9C,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAqClD,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,GAAE,QAAsB,GAAG,UAAU,CAS9F"}
|
package/dist/runtime/env.js
CHANGED
|
@@ -32,9 +32,7 @@ function optionalValue(env, scope, key) {
|
|
|
32
32
|
export function loadRuntimeEnv(scope, env = process.env) {
|
|
33
33
|
return {
|
|
34
34
|
ARCUBASE_BASE_URL: requiredValue(env, scope, 'ARCUBASE_BASE_URL'),
|
|
35
|
-
ARCUBASE_TENANT_ID: requiredValue(env, scope, 'ARCUBASE_TENANT_ID'),
|
|
36
35
|
ARCUBASE_ACCESS_TOKEN: requiredValue(env, scope, 'ARCUBASE_ACCESS_TOKEN'),
|
|
37
|
-
ARCUBASE_HOST: optionalValue(env, scope, 'ARCUBASE_HOST'),
|
|
38
36
|
ARCUBASE_TRACE_ID: optionalValue(env, scope, 'ARCUBASE_TRACE_ID'),
|
|
39
37
|
ARCUBASE_SUBJECT_TYPE: optionalValue(env, scope, 'ARCUBASE_SUBJECT_TYPE'),
|
|
40
38
|
ARCUBASE_SUBJECT_ID: optionalValue(env, scope, 'ARCUBASE_SUBJECT_ID'),
|
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' | '
|
|
2
|
+
export declare function buildRequestHeaders(env: Pick<RuntimeEnv, 'ARCUBASE_ACCESS_TOKEN' | '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,
|
|
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,mBAAmB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhI;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
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
export function buildRequestHeaders(env) {
|
|
2
2
|
const headers = {
|
|
3
3
|
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}`,
|
|
4
|
-
'X-Tenant-Id': env.ARCUBASE_TENANT_ID
|
|
5
4
|
};
|
|
6
|
-
if (env.ARCUBASE_HOST && env.ARCUBASE_HOST.trim() !== '') {
|
|
7
|
-
headers['X-Host'] = env.ARCUBASE_HOST;
|
|
8
|
-
}
|
|
9
5
|
if (env.ARCUBASE_TRACE_ID) {
|
|
10
6
|
headers['X-Trace-Id'] = env.ARCUBASE_TRACE_ID;
|
|
11
7
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { loadRuntimeEnv } from '../runtime/env.js';
|
|
4
|
-
test('loadRuntimeEnv requires base url
|
|
4
|
+
test('loadRuntimeEnv requires base url and access token', () => {
|
|
5
5
|
assert.throws(() => loadRuntimeEnv('admin', {}), /ARCUBASE_BASE_URL is required/);
|
|
6
6
|
});
|
|
7
7
|
test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
8
8
|
const env = loadRuntimeEnv('admin', {
|
|
9
9
|
ARCUBASE_BASE_URL: ' http://example.com ',
|
|
10
|
-
ARCUBASE_TENANT_ID: ' tenant-1 ',
|
|
11
10
|
ARCUBASE_ACCESS_TOKEN: ' token-1 ',
|
|
12
11
|
ARCUBASE_TRACE_ID: ' trace-1 '
|
|
13
12
|
});
|
|
14
13
|
assert.deepEqual(env, {
|
|
15
14
|
ARCUBASE_BASE_URL: 'http://example.com',
|
|
16
|
-
ARCUBASE_TENANT_ID: 'tenant-1',
|
|
17
15
|
ARCUBASE_ACCESS_TOKEN: 'token-1',
|
|
18
|
-
ARCUBASE_HOST: undefined,
|
|
19
16
|
ARCUBASE_TRACE_ID: 'trace-1',
|
|
20
17
|
ARCUBASE_SUBJECT_TYPE: undefined,
|
|
21
18
|
ARCUBASE_SUBJECT_ID: undefined,
|
|
@@ -25,17 +22,13 @@ test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
|
25
22
|
test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
26
23
|
const env = loadRuntimeEnv('admin', {
|
|
27
24
|
ARCUBASE_ADMIN_BASE_URL: ' https://admin.example.com ',
|
|
28
|
-
ARCUBASE_ADMIN_TENANT_ID: ' tenant-admin ',
|
|
29
25
|
ARCUBASE_ADMIN_ACCESS_TOKEN: ' token-admin ',
|
|
30
|
-
ARCUBASE_ADMIN_HOST: ' tenant-admin.arcubase.co ',
|
|
31
26
|
ARCUBASE_ADMIN_SUBJECT_TYPE: ' system_admin ',
|
|
32
27
|
ARCUBASE_ADMIN_SUBJECT_ID: ' user-admin ',
|
|
33
28
|
});
|
|
34
29
|
assert.deepEqual(env, {
|
|
35
30
|
ARCUBASE_BASE_URL: 'https://admin.example.com',
|
|
36
|
-
ARCUBASE_TENANT_ID: 'tenant-admin',
|
|
37
31
|
ARCUBASE_ACCESS_TOKEN: 'token-admin',
|
|
38
|
-
ARCUBASE_HOST: 'tenant-admin.arcubase.co',
|
|
39
32
|
ARCUBASE_TRACE_ID: undefined,
|
|
40
33
|
ARCUBASE_SUBJECT_TYPE: 'system_admin',
|
|
41
34
|
ARCUBASE_SUBJECT_ID: 'user-admin',
|
|
@@ -45,17 +38,13 @@ test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
|
45
38
|
test('loadRuntimeEnv accepts user-prefixed runtime env', () => {
|
|
46
39
|
const env = loadRuntimeEnv('user', {
|
|
47
40
|
ARCUBASE_USER_BASE_URL: ' https://user.example.com ',
|
|
48
|
-
ARCUBASE_USER_TENANT_ID: ' tenant-user ',
|
|
49
41
|
ARCUBASE_USER_ACCESS_TOKEN: ' token-user ',
|
|
50
|
-
ARCUBASE_USER_HOST: ' tenant-user.arcubase.co ',
|
|
51
42
|
ARCUBASE_USER_SUBJECT_TYPE: ' service_account ',
|
|
52
43
|
ARCUBASE_USER_SUBJECT_ID: ' sa-user ',
|
|
53
44
|
});
|
|
54
45
|
assert.deepEqual(env, {
|
|
55
46
|
ARCUBASE_BASE_URL: 'https://user.example.com',
|
|
56
|
-
ARCUBASE_TENANT_ID: 'tenant-user',
|
|
57
47
|
ARCUBASE_ACCESS_TOKEN: 'token-user',
|
|
58
|
-
ARCUBASE_HOST: 'tenant-user.arcubase.co',
|
|
59
48
|
ARCUBASE_TRACE_ID: undefined,
|
|
60
49
|
ARCUBASE_SUBJECT_TYPE: 'service_account',
|
|
61
50
|
ARCUBASE_SUBJECT_ID: 'sa-user',
|
|
@@ -7,9 +7,7 @@ import { executeCLI } from '../runtime/execute.js';
|
|
|
7
7
|
import { CLIError } from '../runtime/errors.js';
|
|
8
8
|
const env = {
|
|
9
9
|
ARCUBASE_BASE_URL: 'https://arcubase.example.com',
|
|
10
|
-
ARCUBASE_TENANT_ID: 'tenant_1',
|
|
11
10
|
ARCUBASE_ACCESS_TOKEN: 'tok',
|
|
12
|
-
ARCUBASE_HOST: 'tenant_1.arcubase.co',
|
|
13
11
|
ARCUBASE_TRACE_ID: '',
|
|
14
12
|
ARCUBASE_SUBJECT_TYPE: '',
|
|
15
13
|
ARCUBASE_SUBJECT_ID: '',
|
|
@@ -49,11 +47,13 @@ test('admin create app by tenants rejects name longer than 20 chars', async () =
|
|
|
49
47
|
});
|
|
50
48
|
test('admin create entity executes with valid body file', async () => {
|
|
51
49
|
const bodyFile = tempJSONFile({ name: '订单', parent: 0 });
|
|
52
|
-
const out = await executeCLI('admin', ['app', 'create-entity', '--id', 'app_1', '--body-file', bodyFile], env, async (url, init) => new Response(JSON.stringify({ ok: true, url, method: init?.method,
|
|
50
|
+
const out = await executeCLI('admin', ['app', 'create-entity', '--id', 'app_1', '--body-file', bodyFile], env, async (url, init) => new Response(JSON.stringify({ ok: true, url, method: init?.method, headers: init?.headers }), { status: 200 }));
|
|
53
51
|
assert.equal(out.kind, 'result');
|
|
54
52
|
assert.equal(out.status, 200);
|
|
55
53
|
assert.equal(out.data.url, 'https://arcubase.example.com/apps/app_1/entities');
|
|
56
|
-
assert.equal(out.data.
|
|
54
|
+
assert.equal(out.data.headers['Authorization'], 'Bearer tok');
|
|
55
|
+
assert.equal(out.data.headers['X-Host'], undefined);
|
|
56
|
+
assert.equal(out.data.headers['X-Tenant-Id'], undefined);
|
|
57
57
|
});
|
|
58
58
|
test('admin api-prefixed command executes against external root path', async () => {
|
|
59
59
|
const out = await executeCLI('admin', ['app-entity-share', 'get-app-entity-shares', '--app-id', 'app_1'], env, async (url, init) => new Response(JSON.stringify({ ok: true, url, method: init?.method }), { status: 200 }));
|
package/dist/tests/help.test.js
CHANGED
|
@@ -3,7 +3,6 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import { executeCLI } from '../runtime/execute.js';
|
|
4
4
|
const env = {
|
|
5
5
|
ARCUBASE_BASE_URL: 'https://arcubase.example.com',
|
|
6
|
-
ARCUBASE_TENANT_ID: 'tenant_1',
|
|
7
6
|
ARCUBASE_ACCESS_TOKEN: 'tok',
|
|
8
7
|
ARCUBASE_TRACE_ID: '',
|
|
9
8
|
ARCUBASE_SUBJECT_TYPE: '',
|
|
@@ -6,7 +6,6 @@ import path from 'path';
|
|
|
6
6
|
import { executeCLI } from '../runtime/execute.js';
|
|
7
7
|
const env = {
|
|
8
8
|
ARCUBASE_BASE_URL: 'https://arcubase.example.com',
|
|
9
|
-
ARCUBASE_TENANT_ID: 'tenant_1',
|
|
10
9
|
ARCUBASE_ACCESS_TOKEN: 'tok',
|
|
11
10
|
ARCUBASE_TRACE_ID: '',
|
|
12
11
|
ARCUBASE_SUBJECT_TYPE: '',
|
package/package.json
CHANGED
|
@@ -101,22 +101,16 @@ arcubase rows query-entity \
|
|
|
101
101
|
The CLIs accept either generic env keys:
|
|
102
102
|
|
|
103
103
|
- `ARCUBASE_BASE_URL`
|
|
104
|
-
- `ARCUBASE_TENANT_ID`
|
|
105
104
|
- `ARCUBASE_ACCESS_TOKEN`
|
|
106
|
-
- `ARCUBASE_HOST`
|
|
107
105
|
|
|
108
106
|
or scoped env keys:
|
|
109
107
|
|
|
110
108
|
- admin:
|
|
111
109
|
- `ARCUBASE_ADMIN_BASE_URL`
|
|
112
|
-
- `ARCUBASE_ADMIN_TENANT_ID`
|
|
113
110
|
- `ARCUBASE_ADMIN_ACCESS_TOKEN`
|
|
114
|
-
- `ARCUBASE_ADMIN_HOST`
|
|
115
111
|
- user:
|
|
116
112
|
- `ARCUBASE_USER_BASE_URL`
|
|
117
|
-
- `ARCUBASE_USER_TENANT_ID`
|
|
118
113
|
- `ARCUBASE_USER_ACCESS_TOKEN`
|
|
119
|
-
- `ARCUBASE_USER_HOST`
|
|
120
114
|
|
|
121
115
|
Help should work without runtime env:
|
|
122
116
|
|
|
@@ -58,22 +58,6 @@ If the app already exists:
|
|
|
58
58
|
3. inspect the existing entity list
|
|
59
59
|
4. decide whether to create a new entity or write rows into an existing entity
|
|
60
60
|
|
|
61
|
-
## Per-employee permission scenarios
|
|
62
|
-
|
|
63
|
-
If the business requirement says different digiEmployees should have different Arcubase abilities:
|
|
64
|
-
|
|
65
|
-
- first resolve the app with `arcubase-admin app inventory`
|
|
66
|
-
- then resolve digiEmployee mappings with `arcubase.get_digiemployee_users`
|
|
67
|
-
- then continue with ingress-oriented admin configuration
|
|
68
|
-
|
|
69
|
-
Do not treat this as a reason to ask the user for:
|
|
70
|
-
|
|
71
|
-
- `app_id`
|
|
72
|
-
- `entity_id`
|
|
73
|
-
- `tenantUserId`
|
|
74
|
-
|
|
75
|
-
Do not treat this as a primary app-sharing or permission-template discovery task.
|
|
76
|
-
|
|
77
61
|
## New app flow
|
|
78
62
|
|
|
79
63
|
If the user clearly wants a brand-new app:
|
package/src/runtime/env.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export type RuntimeEnv = {
|
|
2
2
|
ARCUBASE_BASE_URL: string
|
|
3
|
-
ARCUBASE_TENANT_ID: string
|
|
4
3
|
ARCUBASE_ACCESS_TOKEN: string
|
|
5
|
-
ARCUBASE_HOST?: string
|
|
6
4
|
ARCUBASE_TRACE_ID?: string
|
|
7
5
|
ARCUBASE_SUBJECT_TYPE?: string
|
|
8
6
|
ARCUBASE_SUBJECT_ID?: string
|
|
@@ -51,9 +49,7 @@ function optionalValue(env: EnvInput, scope: RuntimeEnvScope, key: keyof Runtime
|
|
|
51
49
|
export function loadRuntimeEnv(scope: RuntimeEnvScope, env: EnvInput = process.env): RuntimeEnv {
|
|
52
50
|
return {
|
|
53
51
|
ARCUBASE_BASE_URL: requiredValue(env, scope, 'ARCUBASE_BASE_URL'),
|
|
54
|
-
ARCUBASE_TENANT_ID: requiredValue(env, scope, 'ARCUBASE_TENANT_ID'),
|
|
55
52
|
ARCUBASE_ACCESS_TOKEN: requiredValue(env, scope, 'ARCUBASE_ACCESS_TOKEN'),
|
|
56
|
-
ARCUBASE_HOST: optionalValue(env, scope, 'ARCUBASE_HOST'),
|
|
57
53
|
ARCUBASE_TRACE_ID: optionalValue(env, scope, 'ARCUBASE_TRACE_ID'),
|
|
58
54
|
ARCUBASE_SUBJECT_TYPE: optionalValue(env, scope, 'ARCUBASE_SUBJECT_TYPE'),
|
|
59
55
|
ARCUBASE_SUBJECT_ID: optionalValue(env, scope, 'ARCUBASE_SUBJECT_ID'),
|
package/src/runtime/http.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { RuntimeEnv } from './env.js'
|
|
2
2
|
|
|
3
|
-
export function buildRequestHeaders(env: Pick<RuntimeEnv, 'ARCUBASE_ACCESS_TOKEN' | '
|
|
3
|
+
export function buildRequestHeaders(env: Pick<RuntimeEnv, 'ARCUBASE_ACCESS_TOKEN' | 'ARCUBASE_TRACE_ID'>): Record<string, string> {
|
|
4
4
|
const headers: Record<string, string> = {
|
|
5
5
|
Authorization: `Bearer ${env.ARCUBASE_ACCESS_TOKEN}`,
|
|
6
|
-
'X-Tenant-Id': env.ARCUBASE_TENANT_ID
|
|
7
|
-
}
|
|
8
|
-
if (env.ARCUBASE_HOST && env.ARCUBASE_HOST.trim() !== '') {
|
|
9
|
-
headers['X-Host'] = env.ARCUBASE_HOST
|
|
10
6
|
}
|
|
11
7
|
if (env.ARCUBASE_TRACE_ID) {
|
|
12
8
|
headers['X-Trace-Id'] = env.ARCUBASE_TRACE_ID
|
|
@@ -3,23 +3,20 @@ import assert from 'node:assert/strict'
|
|
|
3
3
|
|
|
4
4
|
import { loadRuntimeEnv } from '../runtime/env.js'
|
|
5
5
|
|
|
6
|
-
test('loadRuntimeEnv requires base url
|
|
6
|
+
test('loadRuntimeEnv requires base url and access token', () => {
|
|
7
7
|
assert.throws(() => loadRuntimeEnv('admin', {}), /ARCUBASE_BASE_URL is required/)
|
|
8
8
|
})
|
|
9
9
|
|
|
10
10
|
test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
11
11
|
const env = loadRuntimeEnv('admin', {
|
|
12
12
|
ARCUBASE_BASE_URL: ' http://example.com ',
|
|
13
|
-
ARCUBASE_TENANT_ID: ' tenant-1 ',
|
|
14
13
|
ARCUBASE_ACCESS_TOKEN: ' token-1 ',
|
|
15
14
|
ARCUBASE_TRACE_ID: ' trace-1 '
|
|
16
15
|
})
|
|
17
16
|
|
|
18
17
|
assert.deepEqual(env, {
|
|
19
18
|
ARCUBASE_BASE_URL: 'http://example.com',
|
|
20
|
-
ARCUBASE_TENANT_ID: 'tenant-1',
|
|
21
19
|
ARCUBASE_ACCESS_TOKEN: 'token-1',
|
|
22
|
-
ARCUBASE_HOST: undefined,
|
|
23
20
|
ARCUBASE_TRACE_ID: 'trace-1',
|
|
24
21
|
ARCUBASE_SUBJECT_TYPE: undefined,
|
|
25
22
|
ARCUBASE_SUBJECT_ID: undefined,
|
|
@@ -30,18 +27,14 @@ test('loadRuntimeEnv returns normalized runtime env', () => {
|
|
|
30
27
|
test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
31
28
|
const env = loadRuntimeEnv('admin', {
|
|
32
29
|
ARCUBASE_ADMIN_BASE_URL: ' https://admin.example.com ',
|
|
33
|
-
ARCUBASE_ADMIN_TENANT_ID: ' tenant-admin ',
|
|
34
30
|
ARCUBASE_ADMIN_ACCESS_TOKEN: ' token-admin ',
|
|
35
|
-
ARCUBASE_ADMIN_HOST: ' tenant-admin.arcubase.co ',
|
|
36
31
|
ARCUBASE_ADMIN_SUBJECT_TYPE: ' system_admin ',
|
|
37
32
|
ARCUBASE_ADMIN_SUBJECT_ID: ' user-admin ',
|
|
38
33
|
})
|
|
39
34
|
|
|
40
35
|
assert.deepEqual(env, {
|
|
41
36
|
ARCUBASE_BASE_URL: 'https://admin.example.com',
|
|
42
|
-
ARCUBASE_TENANT_ID: 'tenant-admin',
|
|
43
37
|
ARCUBASE_ACCESS_TOKEN: 'token-admin',
|
|
44
|
-
ARCUBASE_HOST: 'tenant-admin.arcubase.co',
|
|
45
38
|
ARCUBASE_TRACE_ID: undefined,
|
|
46
39
|
ARCUBASE_SUBJECT_TYPE: 'system_admin',
|
|
47
40
|
ARCUBASE_SUBJECT_ID: 'user-admin',
|
|
@@ -52,18 +45,14 @@ test('loadRuntimeEnv accepts admin-prefixed runtime env', () => {
|
|
|
52
45
|
test('loadRuntimeEnv accepts user-prefixed runtime env', () => {
|
|
53
46
|
const env = loadRuntimeEnv('user', {
|
|
54
47
|
ARCUBASE_USER_BASE_URL: ' https://user.example.com ',
|
|
55
|
-
ARCUBASE_USER_TENANT_ID: ' tenant-user ',
|
|
56
48
|
ARCUBASE_USER_ACCESS_TOKEN: ' token-user ',
|
|
57
|
-
ARCUBASE_USER_HOST: ' tenant-user.arcubase.co ',
|
|
58
49
|
ARCUBASE_USER_SUBJECT_TYPE: ' service_account ',
|
|
59
50
|
ARCUBASE_USER_SUBJECT_ID: ' sa-user ',
|
|
60
51
|
})
|
|
61
52
|
|
|
62
53
|
assert.deepEqual(env, {
|
|
63
54
|
ARCUBASE_BASE_URL: 'https://user.example.com',
|
|
64
|
-
ARCUBASE_TENANT_ID: 'tenant-user',
|
|
65
55
|
ARCUBASE_ACCESS_TOKEN: 'token-user',
|
|
66
|
-
ARCUBASE_HOST: 'tenant-user.arcubase.co',
|
|
67
56
|
ARCUBASE_TRACE_ID: undefined,
|
|
68
57
|
ARCUBASE_SUBJECT_TYPE: 'service_account',
|
|
69
58
|
ARCUBASE_SUBJECT_ID: 'sa-user',
|
|
@@ -8,9 +8,7 @@ import { CLIError } from '../runtime/errors.js'
|
|
|
8
8
|
|
|
9
9
|
const env = {
|
|
10
10
|
ARCUBASE_BASE_URL: 'https://arcubase.example.com',
|
|
11
|
-
ARCUBASE_TENANT_ID: 'tenant_1',
|
|
12
11
|
ARCUBASE_ACCESS_TOKEN: 'tok',
|
|
13
|
-
ARCUBASE_HOST: 'tenant_1.arcubase.co',
|
|
14
12
|
ARCUBASE_TRACE_ID: '',
|
|
15
13
|
ARCUBASE_SUBJECT_TYPE: '',
|
|
16
14
|
ARCUBASE_SUBJECT_ID: '',
|
|
@@ -63,12 +61,14 @@ test('admin create entity executes with valid body file', async () => {
|
|
|
63
61
|
'admin',
|
|
64
62
|
['app', 'create-entity', '--id', 'app_1', '--body-file', bodyFile],
|
|
65
63
|
env as any,
|
|
66
|
-
async (url, init) => new Response(JSON.stringify({ ok: true, url, method: init?.method,
|
|
64
|
+
async (url, init) => new Response(JSON.stringify({ ok: true, url, method: init?.method, headers: init?.headers }), { status: 200 })
|
|
67
65
|
)
|
|
68
66
|
assert.equal(out.kind, 'result')
|
|
69
67
|
assert.equal(out.status, 200)
|
|
70
68
|
assert.equal(out.data.url, 'https://arcubase.example.com/apps/app_1/entities')
|
|
71
|
-
assert.equal(out.data.
|
|
69
|
+
assert.equal(out.data.headers['Authorization'], 'Bearer tok')
|
|
70
|
+
assert.equal(out.data.headers['X-Host'], undefined)
|
|
71
|
+
assert.equal(out.data.headers['X-Tenant-Id'], undefined)
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
test('admin api-prefixed command executes against external root path', async () => {
|
package/src/tests/help.test.ts
CHANGED
package/src/tests/upload.test.ts
CHANGED