tirtc-devtools-cli 0.0.12 → 0.0.14
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/README.md +42 -46
- package/USAGE.md +90 -311
- package/dist/cli/src/embedded_paths.d.ts +0 -2
- package/dist/cli/src/embedded_paths.js +3 -25
- package/dist/cli/src/index.js +82 -584
- package/dist/cli/src/role_driver.d.ts +33 -0
- package/dist/cli/src/role_driver.js +500 -0
- package/dist/cli/src/token_command.js +29 -14
- package/dist/cli/src/token_issue.d.ts +9 -0
- package/dist/cli/src/token_issue.js +138 -0
- package/dist/cli/src/token_tool.d.ts +4 -4
- package/dist/cli/src/token_tool.js +66 -182
- package/package.json +1 -1
- package/vendor/devtools/driver/macos-arm64/devtools_driver_probe +0 -0
- package/vendor/devtools/driver/macos-arm64/runtime_validation_client_bin +0 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio.h +83 -2
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io.h +9 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/av.h +74 -0
- package/vendor/runtime/macos-arm64/include/tirtc/error.h +63 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_downlink.h +58 -5
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_uplink.h +4 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/transport.h +52 -15
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/trp.h +17 -5
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_codec.h +41 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io.h +7 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_android.h +2 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_audio.a +0 -0
- package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_http.a +0 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_logging.a +0 -0
- package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
- package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
- package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/manifest.txt +20 -25
- package/vendor/runtime/script/prepare_runtime_media_dataset.sh +308 -12
- package/dist/app-server/protocol-client/index.d.ts +0 -25
- package/dist/app-server/protocol-client/index.js +0 -114
- package/dist/cli/src/bootstrap_flows.d.ts +0 -46
- package/dist/cli/src/bootstrap_flows.js +0 -249
- package/dist/cli/src/config.d.ts +0 -26
- package/dist/cli/src/config.js +0 -62
- package/dist/cli/src/facade.d.ts +0 -430
- package/dist/cli/src/facade.js +0 -170
- package/dist/cli/src/guide.d.ts +0 -1
- package/dist/cli/src/guide.js +0 -47
- package/dist/cli/src/session_manager.d.ts +0 -25
- package/dist/cli/src/session_manager.js +0 -391
- package/dist/cli/src/transport.d.ts +0 -30
- package/dist/cli/src/transport.js +0 -84
- package/vendor/app-server/bin/native/linux-x64/credential_napi.node +0 -0
- package/vendor/app-server/bin/native/macos-arm64/credential_napi.node +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/credential.h +0 -34
- package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/error.h +0 -33
- package/vendor/app-server/bin/runtime/linux-x64/lib/libcrypto.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_credential.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_http.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_logging.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libssl.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/lib/libxlog.a +0 -0
- package/vendor/app-server/bin/runtime/linux-x64/manifest.txt +0 -4
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/credential.h +0 -34
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/error.h +0 -33
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/foundation/build_info.h +0 -27
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/http.h +0 -57
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/logging.h +0 -55
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_av_sync.h +0 -61
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_source.h +0 -77
- package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_live_source.h +0 -71
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_credential.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
- package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
- package/vendor/app-server/bin/tirtc-devtool-host.js +0 -2
- package/vendor/app-server/dist/host/ArtifactManager.d.ts +0 -18
- package/vendor/app-server/dist/host/ArtifactManager.js +0 -98
- package/vendor/app-server/dist/host/HostCommandCoordinator.d.ts +0 -19
- package/vendor/app-server/dist/host/HostCommandCoordinator.js +0 -196
- package/vendor/app-server/dist/host/HostProtocol.d.ts +0 -103
- package/vendor/app-server/dist/host/HostProtocol.js +0 -239
- package/vendor/app-server/dist/host/HostServer.d.ts +0 -52
- package/vendor/app-server/dist/host/HostServer.js +0 -727
- package/vendor/app-server/dist/host/HostState.d.ts +0 -69
- package/vendor/app-server/dist/host/HostState.js +0 -19
- package/vendor/app-server/dist/host/RuntimeAdapter.d.ts +0 -95
- package/vendor/app-server/dist/host/RuntimeAdapter.js +0 -636
- package/vendor/app-server/dist/host/RuntimeReceiveWorker.d.ts +0 -37
- package/vendor/app-server/dist/host/RuntimeReceiveWorker.js +0 -186
- package/vendor/app-server/dist/host/RuntimeSendWorker.d.ts +0 -58
- package/vendor/app-server/dist/host/RuntimeSendWorker.js +0 -438
- package/vendor/app-server/dist/host/TokenTool.d.ts +0 -15
- package/vendor/app-server/dist/host/TokenTool.js +0 -84
- package/vendor/app-server/dist/host/WebPreviewGateway.d.ts +0 -28
- package/vendor/app-server/dist/host/WebPreviewGateway.js +0 -815
- package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.d.ts +0 -26
- package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +0 -118
- package/vendor/app-server/dist/host/native/RuntimeHostBridge.d.ts +0 -32
- package/vendor/app-server/dist/host/native/RuntimeHostBridge.js +0 -157
- package/vendor/app-server/dist/host/runtime_backed_preflight.d.ts +0 -10
- package/vendor/app-server/dist/host/runtime_backed_preflight.js +0 -78
- package/vendor/app-server/dist/host/tests/helpers/host_socket_client.d.ts +0 -28
- package/vendor/app-server/dist/host/tests/helpers/host_socket_client.js +0 -85
- package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.d.ts +0 -10
- package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.js +0 -41
- package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.d.ts +0 -11
- package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.js +0 -32
- package/vendor/app-server/dist/protocol/contract.d.ts +0 -1128
- package/vendor/app-server/dist/protocol/contract.js +0 -217
- package/vendor/app-server/dist/protocol-client/index.d.ts +0 -25
- package/vendor/app-server/dist/protocol-client/index.js +0 -114
- package/vendor/app-server/dist/src/index.d.ts +0 -1
- package/vendor/app-server/dist/src/index.js +0 -294
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_codec.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_frame.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_android.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_apple.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_harmony.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_windows.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_processing.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_sample_rate.h +0 -0
- /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/foundation/build_info.h +0 -0
- /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/http.h +0 -0
- /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/logging.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_codec.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_frame.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_apple.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_harmony.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_windows.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_processing.h +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTGTRP.a +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTiRTC.a +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.a +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.dylib +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.a +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.dylib +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libtgrtc.dylib +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libwebrtc_apm.a +0 -0
- /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libxlog.a +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type CliOptions = {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
};
|
|
4
|
+
type SendCommandOptions = {
|
|
5
|
+
executionId?: string;
|
|
6
|
+
caseId?: string;
|
|
7
|
+
appId?: string;
|
|
8
|
+
artifactRoot?: string;
|
|
9
|
+
remoteId?: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
videoCodec?: string;
|
|
12
|
+
durationMs?: string;
|
|
13
|
+
connectTimeoutMs?: string;
|
|
14
|
+
firstPacketTimeoutMs?: string;
|
|
15
|
+
bootstrapTokenJson?: string;
|
|
16
|
+
};
|
|
17
|
+
type ReceiveCommandOptions = {
|
|
18
|
+
artifactRoot?: string;
|
|
19
|
+
bootstrap?: string;
|
|
20
|
+
remoteId?: string;
|
|
21
|
+
token?: string;
|
|
22
|
+
audioStreamId?: string;
|
|
23
|
+
videoStreamId?: string;
|
|
24
|
+
consumer?: string;
|
|
25
|
+
frameLimit?: string;
|
|
26
|
+
durationMs?: string;
|
|
27
|
+
connectTimeoutMs?: string;
|
|
28
|
+
firstPacketTimeoutMs?: string;
|
|
29
|
+
firstOutputTimeoutMs?: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function runSendStart(commandOptions: SendCommandOptions, options: CliOptions): Promise<number>;
|
|
32
|
+
export declare function runReceiveStart(commandOptions: ReceiveCommandOptions, options: CliOptions): Promise<number>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runSendStart = runSendStart;
|
|
7
|
+
exports.runReceiveStart = runReceiveStart;
|
|
8
|
+
const child_process_1 = __importDefault(require("child_process"));
|
|
9
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const embedded_paths_1 = require("./embedded_paths");
|
|
14
|
+
const token_tool_1 = require("./token_tool");
|
|
15
|
+
const defaultAudioStreamId = 10;
|
|
16
|
+
const defaultVideoStreamId = 11;
|
|
17
|
+
const defaultDurationMs = 10000;
|
|
18
|
+
const defaultConnectTimeoutMs = 10000;
|
|
19
|
+
const defaultFirstPacketTimeoutMs = 10000;
|
|
20
|
+
const defaultFirstOutputTimeoutMs = 12000;
|
|
21
|
+
const defaultFrameLimit = 1;
|
|
22
|
+
const roleFailedExitCode = 1;
|
|
23
|
+
const usageExitCode = 2;
|
|
24
|
+
const preflightExitCode = 3;
|
|
25
|
+
class RoleCommandError extends Error {
|
|
26
|
+
reasonCode;
|
|
27
|
+
failedStage;
|
|
28
|
+
exitCode;
|
|
29
|
+
constructor(reasonCode, failedStage, exitCode, message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'RoleCommandError';
|
|
32
|
+
this.reasonCode = reasonCode;
|
|
33
|
+
this.failedStage = failedStage;
|
|
34
|
+
this.exitCode = exitCode;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function rolePreflightError(reasonCode, detail) {
|
|
38
|
+
return new RoleCommandError(reasonCode, 'preflight', preflightExitCode, reasonCode + ': ' + detail);
|
|
39
|
+
}
|
|
40
|
+
function roleUsageError(message) {
|
|
41
|
+
return new RoleCommandError('invalid_request', 'config', usageExitCode, message);
|
|
42
|
+
}
|
|
43
|
+
function pathExists(filePath) {
|
|
44
|
+
return fs_1.default.existsSync(filePath);
|
|
45
|
+
}
|
|
46
|
+
function pathIsExecutable(filePath) {
|
|
47
|
+
try {
|
|
48
|
+
fs_1.default.accessSync(filePath, fs_1.default.constants.X_OK);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function resolveRuntimePlatform() {
|
|
56
|
+
const explicit = process.env.TIRTC_RUNTIME_PLATFORM?.trim();
|
|
57
|
+
if (explicit) {
|
|
58
|
+
return explicit;
|
|
59
|
+
}
|
|
60
|
+
if (process.platform === 'darwin' && process.arch === 'arm64') {
|
|
61
|
+
return 'macos-arm64';
|
|
62
|
+
}
|
|
63
|
+
return 'linux-x64';
|
|
64
|
+
}
|
|
65
|
+
function resolveRoleDriverRoots(fromDir = __dirname) {
|
|
66
|
+
return {
|
|
67
|
+
packageRoot: (0, embedded_paths_1.resolveCliPackageRoot)(fromDir),
|
|
68
|
+
repoRoot: (0, embedded_paths_1.resolveWorkspaceRepoRoot)(fromDir),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function appendIfDefined(candidates, candidate) {
|
|
72
|
+
if (candidate && candidate.length > 0) {
|
|
73
|
+
candidates.push(candidate);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function resolveDriverPath(roots, platform) {
|
|
77
|
+
const explicit = process.env.TIRTC_DEVTOOLS_DRIVER_PATH?.trim();
|
|
78
|
+
if (explicit) {
|
|
79
|
+
return explicit;
|
|
80
|
+
}
|
|
81
|
+
const candidates = [];
|
|
82
|
+
appendIfDefined(candidates, roots.repoRoot
|
|
83
|
+
? path_1.default.join(roots.repoRoot, '.build/devtools-driver/bin', platform, 'devtools_driver_probe')
|
|
84
|
+
: undefined);
|
|
85
|
+
appendIfDefined(candidates, roots.repoRoot
|
|
86
|
+
? path_1.default.join(roots.repoRoot, 'products/devtools/driver/bin', platform, 'devtools_driver_probe')
|
|
87
|
+
: undefined);
|
|
88
|
+
appendIfDefined(candidates, roots.repoRoot
|
|
89
|
+
? path_1.default.join(roots.repoRoot, 'products/cli/vendor/devtools/driver', platform, 'devtools_driver_probe')
|
|
90
|
+
: undefined);
|
|
91
|
+
candidates.push(path_1.default.join(roots.packageRoot, 'vendor/devtools/driver', platform, 'devtools_driver_probe'));
|
|
92
|
+
for (const candidate of candidates) {
|
|
93
|
+
if (pathExists(candidate)) {
|
|
94
|
+
return candidate;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return candidates[0] ?? '';
|
|
98
|
+
}
|
|
99
|
+
function hasRuntimeBundle(runtimeRoot) {
|
|
100
|
+
return pathExists(path_1.default.join(runtimeRoot, 'include/tirtc/av.h')) &&
|
|
101
|
+
pathExists(path_1.default.join(runtimeRoot, 'lib/libmatrix_runtime_facade.a'));
|
|
102
|
+
}
|
|
103
|
+
function resolveRuntimeRoot(roots, platform) {
|
|
104
|
+
const explicit = process.env.TIRTC_RUNTIME_BUNDLE_ROOT?.trim();
|
|
105
|
+
if (explicit) {
|
|
106
|
+
return explicit;
|
|
107
|
+
}
|
|
108
|
+
const candidates = [];
|
|
109
|
+
appendIfDefined(candidates, roots.repoRoot ? path_1.default.join(roots.repoRoot, '.build/products/runtime', platform) : undefined);
|
|
110
|
+
appendIfDefined(candidates, roots.repoRoot ? path_1.default.join(roots.repoRoot, 'products/cli/bin/runtime', platform) : undefined);
|
|
111
|
+
appendIfDefined(candidates, roots.repoRoot ? path_1.default.join(roots.repoRoot, 'products/cli/vendor/runtime', platform) : undefined);
|
|
112
|
+
candidates.push(path_1.default.join(roots.packageRoot, 'vendor/runtime', platform));
|
|
113
|
+
for (const candidate of candidates) {
|
|
114
|
+
if (hasRuntimeBundle(candidate)) {
|
|
115
|
+
return candidate;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return candidates[0] ?? '';
|
|
119
|
+
}
|
|
120
|
+
function resolveAssetRoot(roots) {
|
|
121
|
+
const explicit = process.env.MATRIX_ASSET_WORKSPACE_ROOT?.trim();
|
|
122
|
+
if (explicit) {
|
|
123
|
+
return explicit;
|
|
124
|
+
}
|
|
125
|
+
if (roots.repoRoot) {
|
|
126
|
+
return path_1.default.join(roots.repoRoot, 'runtime/assets/.workspace/runtime-assets-current');
|
|
127
|
+
}
|
|
128
|
+
return path_1.default.join(roots.packageRoot, 'runtime/assets/.workspace/runtime-assets-current');
|
|
129
|
+
}
|
|
130
|
+
function parsePositiveInt(raw, fallback, name) {
|
|
131
|
+
if (raw === undefined) {
|
|
132
|
+
return fallback;
|
|
133
|
+
}
|
|
134
|
+
const parsed = Number.parseInt(raw, 10);
|
|
135
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
136
|
+
throw roleUsageError(name + ' must be a positive integer');
|
|
137
|
+
}
|
|
138
|
+
return parsed;
|
|
139
|
+
}
|
|
140
|
+
function requireEnv(name) {
|
|
141
|
+
const value = process.env[name]?.trim();
|
|
142
|
+
if (!value) {
|
|
143
|
+
throw rolePreflightError('missing_env', 'missing environment: ' + name);
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
function executionSuffix() {
|
|
148
|
+
return new Date().toISOString().replace(/[-:.TZ]/g, '').slice(0, 14);
|
|
149
|
+
}
|
|
150
|
+
function ensureDir(dirPath) {
|
|
151
|
+
fs_1.default.mkdirSync(dirPath, { recursive: true });
|
|
152
|
+
}
|
|
153
|
+
function writeJson(filePath, value) {
|
|
154
|
+
ensureDir(path_1.default.dirname(filePath));
|
|
155
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n');
|
|
156
|
+
}
|
|
157
|
+
function redactRequestValue(value) {
|
|
158
|
+
if (Array.isArray(value)) {
|
|
159
|
+
return value.map((item) => redactRequestValue(item));
|
|
160
|
+
}
|
|
161
|
+
if (typeof value !== 'object' || value === null) {
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
const result = {};
|
|
165
|
+
for (const [key, child] of Object.entries(value)) {
|
|
166
|
+
if (key === 'license' || key === 'token' || key === 'client_token' || key === 'secret_key') {
|
|
167
|
+
result[key] = '[REDACTED]';
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
result[key] = redactRequestValue(child);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
function readJson(filePath) {
|
|
176
|
+
return JSON.parse(fs_1.default.readFileSync(filePath, 'utf8'));
|
|
177
|
+
}
|
|
178
|
+
function trimOptional(value) {
|
|
179
|
+
const trimmed = value?.trim();
|
|
180
|
+
return trimmed ? trimmed : undefined;
|
|
181
|
+
}
|
|
182
|
+
function tokenFingerprint(token) {
|
|
183
|
+
return 'sha256:' + crypto_1.default.createHash('sha256').update(token).digest('hex');
|
|
184
|
+
}
|
|
185
|
+
function readTokenIssueJson(filePath) {
|
|
186
|
+
const resolved = path_1.default.resolve(filePath);
|
|
187
|
+
if (!pathExists(resolved)) {
|
|
188
|
+
throw rolePreflightError('token_issue_missing', resolved);
|
|
189
|
+
}
|
|
190
|
+
let parsed;
|
|
191
|
+
try {
|
|
192
|
+
parsed = readJson(resolved);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
196
|
+
throw rolePreflightError('token_issue_invalid', detail);
|
|
197
|
+
}
|
|
198
|
+
const token = trimOptional(parsed.data?.token);
|
|
199
|
+
if (!token) {
|
|
200
|
+
throw rolePreflightError('token_issue_invalid', 'missing data.token');
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
token,
|
|
204
|
+
remoteId: trimOptional(parsed.data?.payload?.remote_id),
|
|
205
|
+
endpoint: trimOptional(parsed.data?.payload?.endpoint),
|
|
206
|
+
appId: trimOptional(parsed.data?.payload?.app_id),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function readBootstrap(bootstrapPath) {
|
|
210
|
+
const resolved = path_1.default.resolve(bootstrapPath);
|
|
211
|
+
const parsed = readJson(resolved);
|
|
212
|
+
if (parsed.schema_version !== 1 || !parsed.remote_id || !parsed.token) {
|
|
213
|
+
throw roleUsageError('bootstrap_invalid');
|
|
214
|
+
}
|
|
215
|
+
return parsed;
|
|
216
|
+
}
|
|
217
|
+
function requestMediaSourcePath(request) {
|
|
218
|
+
const media = request.media;
|
|
219
|
+
const sourcePath = media?.source?.path;
|
|
220
|
+
return typeof sourcePath === 'string' && sourcePath.trim() ? sourcePath.trim() : undefined;
|
|
221
|
+
}
|
|
222
|
+
function resolveDriverAssetRoot(request, roots) {
|
|
223
|
+
const source = requestMediaSourcePath(request);
|
|
224
|
+
if (source) {
|
|
225
|
+
const sourcePath = path_1.default.resolve(source);
|
|
226
|
+
if (fs_1.default.existsSync(sourcePath) && fs_1.default.statSync(sourcePath).isDirectory()) {
|
|
227
|
+
return sourcePath;
|
|
228
|
+
}
|
|
229
|
+
if (path_1.default.basename(sourcePath) === 'manifest.json') {
|
|
230
|
+
return path_1.default.dirname(sourcePath);
|
|
231
|
+
}
|
|
232
|
+
if (path_1.default.basename(path_1.default.dirname(sourcePath)) === 'video') {
|
|
233
|
+
return path_1.default.dirname(path_1.default.dirname(sourcePath));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return resolveAssetRoot(roots);
|
|
237
|
+
}
|
|
238
|
+
function codecOrDefault(raw) {
|
|
239
|
+
const codec = raw?.trim() || 'h264';
|
|
240
|
+
if (codec !== 'h264' && codec !== 'h265' && codec !== 'mjpeg') {
|
|
241
|
+
throw roleUsageError('video-codec must be h264, h265, or mjpeg');
|
|
242
|
+
}
|
|
243
|
+
return codec;
|
|
244
|
+
}
|
|
245
|
+
function consumerOrDefault(raw) {
|
|
246
|
+
const consumer = raw?.trim() || 'frame_dump';
|
|
247
|
+
if (consumer !== 'frame_dump' && consumer !== 'packet_dump') {
|
|
248
|
+
throw roleUsageError('consumer must be packet_dump or frame_dump');
|
|
249
|
+
}
|
|
250
|
+
return consumer;
|
|
251
|
+
}
|
|
252
|
+
function failedStage(summary) {
|
|
253
|
+
for (const [name, stage] of Object.entries(summary.stage_status ?? {})) {
|
|
254
|
+
if (stage.status === 'failed') {
|
|
255
|
+
return name;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
function printEnvelope(options, code, message, data) {
|
|
261
|
+
if (options.json) {
|
|
262
|
+
console.log(JSON.stringify({ code, message, data }));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (code === 0) {
|
|
266
|
+
console.log('OK:', JSON.stringify(data, null, 2));
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.error('Error:', message);
|
|
270
|
+
if (data !== undefined) {
|
|
271
|
+
console.error(JSON.stringify(data, null, 2));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function buildSendRequest(roots, artifactRoot, options) {
|
|
276
|
+
const codec = codecOrDefault(options.videoCodec);
|
|
277
|
+
const executionId = trimOptional(options.executionId) ?? 'cli-send-' + codec + '-' + executionSuffix();
|
|
278
|
+
const caseId = trimOptional(options.caseId) ?? 'devtools-cli-send.' + codec;
|
|
279
|
+
let remoteId = trimOptional(options.remoteId);
|
|
280
|
+
let endpoint = trimOptional(process.env.TIRTC_ENDPOINT);
|
|
281
|
+
let appId = trimOptional(options.appId) ?? trimOptional(process.env.TIRTC_APP_ID);
|
|
282
|
+
let token;
|
|
283
|
+
try {
|
|
284
|
+
if (options.bootstrapTokenJson) {
|
|
285
|
+
const tokenIssue = readTokenIssueJson(options.bootstrapTokenJson);
|
|
286
|
+
token = tokenIssue.token;
|
|
287
|
+
remoteId = remoteId ?? tokenIssue.remoteId;
|
|
288
|
+
endpoint = tokenIssue.endpoint ?? endpoint;
|
|
289
|
+
appId = appId ?? tokenIssue.appId;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
remoteId = remoteId ?? requireEnv('TIRTC_DEVICE_ID');
|
|
293
|
+
appId = appId ?? requireEnv('TIRTC_APP_ID');
|
|
294
|
+
token = await (0, token_tool_1.issueToken)({
|
|
295
|
+
accessId: requireEnv('TIRTC_ACCESS_KEY_ID'),
|
|
296
|
+
secretKey: requireEnv('TIRTC_SECRET_KEY_ID'),
|
|
297
|
+
appId,
|
|
298
|
+
remoteId,
|
|
299
|
+
openapiEndpoint: process.env.TIRTC_OPEN_API_ENDPOINT || process.env.TIRTC_OPENAPI_ENDPOINT,
|
|
300
|
+
endpoint,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
if (error instanceof RoleCommandError) {
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
309
|
+
throw rolePreflightError('token_issue_failed', detail);
|
|
310
|
+
}
|
|
311
|
+
remoteId = remoteId ?? requireEnv('TIRTC_DEVICE_ID');
|
|
312
|
+
endpoint = endpoint ?? requireEnv('TIRTC_ENDPOINT');
|
|
313
|
+
appId = appId ?? requireEnv('TIRTC_APP_ID');
|
|
314
|
+
if (!token) {
|
|
315
|
+
throw rolePreflightError('token_issue_invalid', 'missing client token');
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
schema_version: 1,
|
|
319
|
+
execution_id: executionId,
|
|
320
|
+
case_id: caseId,
|
|
321
|
+
role: 'send',
|
|
322
|
+
endpoint,
|
|
323
|
+
identity: {
|
|
324
|
+
license: remoteId + ',' + requireEnv('TIRTC_DEVICE_SECRET_KEY'),
|
|
325
|
+
remote_id: remoteId,
|
|
326
|
+
},
|
|
327
|
+
bootstrap: {
|
|
328
|
+
client_token: token,
|
|
329
|
+
token_fingerprint: tokenFingerprint(token),
|
|
330
|
+
},
|
|
331
|
+
streams: {
|
|
332
|
+
audio_stream_id: defaultAudioStreamId,
|
|
333
|
+
video_stream_id: defaultVideoStreamId,
|
|
334
|
+
},
|
|
335
|
+
media: {
|
|
336
|
+
source: { kind: 'encoded_asset', path: options.source ?? resolveAssetRoot(roots) },
|
|
337
|
+
video: { codec },
|
|
338
|
+
},
|
|
339
|
+
output: { consumer: 'frame_dump', video: { frame_limit: defaultFrameLimit } },
|
|
340
|
+
run: {
|
|
341
|
+
duration_ms: parsePositiveInt(options.durationMs, defaultDurationMs, '--duration-ms'),
|
|
342
|
+
connect_timeout_ms: parsePositiveInt(options.connectTimeoutMs, defaultConnectTimeoutMs, '--connect-timeout-ms'),
|
|
343
|
+
first_packet_timeout_ms: parsePositiveInt(options.firstPacketTimeoutMs, defaultFirstPacketTimeoutMs, '--first-packet-timeout-ms'),
|
|
344
|
+
first_output_timeout_ms: defaultFirstOutputTimeoutMs,
|
|
345
|
+
},
|
|
346
|
+
artifact: { root_dir: artifactRoot },
|
|
347
|
+
probe: { app_id: appId },
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function buildReceiveRequest(roots, artifactRoot, options) {
|
|
351
|
+
const bootstrap = options.bootstrap ? readBootstrap(options.bootstrap) : undefined;
|
|
352
|
+
const remoteId = options.remoteId?.trim() || bootstrap?.remote_id || process.env.TIRTC_REMOTE_ID?.trim() || process.env.TIRTC_DEVICE_ID?.trim();
|
|
353
|
+
const token = options.token?.trim() || bootstrap?.token || process.env.TIRTC_TOKEN?.trim();
|
|
354
|
+
if (!remoteId) {
|
|
355
|
+
throw rolePreflightError('missing_env', 'missing remote id: pass --remote-id, --bootstrap, or TIRTC_REMOTE_ID');
|
|
356
|
+
}
|
|
357
|
+
if (!token) {
|
|
358
|
+
throw rolePreflightError('missing_env', 'missing token: pass --token, --bootstrap, or TIRTC_TOKEN');
|
|
359
|
+
}
|
|
360
|
+
const executionId = 'cli-receive-' + executionSuffix();
|
|
361
|
+
const identityOverride = Boolean(bootstrap && (options.remoteId || options.token));
|
|
362
|
+
const videoCodec = codecOrDefault(bootstrap?.video_codec);
|
|
363
|
+
return {
|
|
364
|
+
schema_version: 1,
|
|
365
|
+
execution_id: executionId,
|
|
366
|
+
case_id: 'devtools-cli-receive',
|
|
367
|
+
role: 'receive',
|
|
368
|
+
endpoint: process.env.TIRTC_ENDPOINT?.trim() || bootstrap?.endpoint || '',
|
|
369
|
+
identity: {
|
|
370
|
+
remote_id: remoteId,
|
|
371
|
+
token,
|
|
372
|
+
bootstrap_path: options.bootstrap ? path_1.default.resolve(options.bootstrap) : undefined,
|
|
373
|
+
bootstrap_id: bootstrap?.bootstrap_id,
|
|
374
|
+
identity_override: identityOverride,
|
|
375
|
+
},
|
|
376
|
+
streams: {
|
|
377
|
+
audio_stream_id: parsePositiveInt(options.audioStreamId, bootstrap?.audio_stream_id ?? defaultAudioStreamId, '--audio-stream-id'),
|
|
378
|
+
video_stream_id: parsePositiveInt(options.videoStreamId, bootstrap?.video_stream_id ?? defaultVideoStreamId, '--video-stream-id'),
|
|
379
|
+
},
|
|
380
|
+
media: {
|
|
381
|
+
source: { kind: 'encoded_asset', path: resolveAssetRoot(roots) },
|
|
382
|
+
video: { codec: videoCodec },
|
|
383
|
+
},
|
|
384
|
+
output: {
|
|
385
|
+
consumer: consumerOrDefault(options.consumer),
|
|
386
|
+
video: { frame_limit: parsePositiveInt(options.frameLimit, defaultFrameLimit, '--frame-limit') },
|
|
387
|
+
},
|
|
388
|
+
run: {
|
|
389
|
+
duration_ms: parsePositiveInt(options.durationMs, defaultDurationMs, '--duration-ms'),
|
|
390
|
+
connect_timeout_ms: parsePositiveInt(options.connectTimeoutMs, defaultConnectTimeoutMs, '--connect-timeout-ms'),
|
|
391
|
+
first_packet_timeout_ms: parsePositiveInt(options.firstPacketTimeoutMs, defaultFirstPacketTimeoutMs, '--first-packet-timeout-ms'),
|
|
392
|
+
first_output_timeout_ms: parsePositiveInt(options.firstOutputTimeoutMs, defaultFirstOutputTimeoutMs, '--first-output-timeout-ms'),
|
|
393
|
+
},
|
|
394
|
+
artifact: { root_dir: artifactRoot },
|
|
395
|
+
probe: { app_id: process.env.TIRTC_APP_ID?.trim() || bootstrap?.app_id || '' },
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function runDriver(request, artifactRoot, roots) {
|
|
399
|
+
const platform = resolveRuntimePlatform();
|
|
400
|
+
const driverPath = resolveDriverPath(roots, platform);
|
|
401
|
+
const runtimeRoot = resolveRuntimeRoot(roots, platform);
|
|
402
|
+
const assetRoot = resolveDriverAssetRoot(request, roots);
|
|
403
|
+
if (!pathExists(driverPath)) {
|
|
404
|
+
throw rolePreflightError('driver_not_found', driverPath);
|
|
405
|
+
}
|
|
406
|
+
if (!pathIsExecutable(driverPath)) {
|
|
407
|
+
throw rolePreflightError('driver_not_executable', driverPath);
|
|
408
|
+
}
|
|
409
|
+
if (!hasRuntimeBundle(runtimeRoot)) {
|
|
410
|
+
throw rolePreflightError('runtime_bundle_missing', runtimeRoot);
|
|
411
|
+
}
|
|
412
|
+
if (!pathExists(path_1.default.join(assetRoot, 'manifest.json'))) {
|
|
413
|
+
throw rolePreflightError('asset_missing', assetRoot);
|
|
414
|
+
}
|
|
415
|
+
const requestTempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'tirtc-devtools-cli-request-'));
|
|
416
|
+
const requestPath = path_1.default.join(requestTempDir, 'request.json');
|
|
417
|
+
writeJson(requestPath, request);
|
|
418
|
+
writeJson(path_1.default.join(artifactRoot, 'request.redacted.json'), redactRequestValue(request));
|
|
419
|
+
const stdoutFd = fs_1.default.openSync(path_1.default.join(artifactRoot, 'stdout.log'), 'w');
|
|
420
|
+
const stderrFd = fs_1.default.openSync(path_1.default.join(artifactRoot, 'stderr.log'), 'w');
|
|
421
|
+
const result = child_process_1.default.spawnSync(driverPath, [
|
|
422
|
+
'--request', requestPath,
|
|
423
|
+
'--runtime-root', runtimeRoot,
|
|
424
|
+
'--asset-root', assetRoot,
|
|
425
|
+
'--artifact-root', artifactRoot,
|
|
426
|
+
], {
|
|
427
|
+
stdio: ['ignore', stdoutFd, stderrFd],
|
|
428
|
+
});
|
|
429
|
+
fs_1.default.closeSync(stdoutFd);
|
|
430
|
+
fs_1.default.closeSync(stderrFd);
|
|
431
|
+
fs_1.default.rmSync(requestTempDir, { recursive: true, force: true });
|
|
432
|
+
const summaryPath = path_1.default.join(artifactRoot, 'summary.json');
|
|
433
|
+
if (!pathExists(summaryPath)) {
|
|
434
|
+
const message = result.error instanceof Error
|
|
435
|
+
? result.error.message
|
|
436
|
+
: 'driver exited without summary: status=' + String(result.status);
|
|
437
|
+
if (result.error) {
|
|
438
|
+
throw new RoleCommandError('artifact_write_failed', 'artifact', roleFailedExitCode, message);
|
|
439
|
+
}
|
|
440
|
+
throw new RoleCommandError('artifact_write_failed', 'artifact', roleFailedExitCode, message);
|
|
441
|
+
}
|
|
442
|
+
return readJson(summaryPath);
|
|
443
|
+
}
|
|
444
|
+
function normalizeRoleError(error) {
|
|
445
|
+
if (error instanceof RoleCommandError) {
|
|
446
|
+
return error;
|
|
447
|
+
}
|
|
448
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
449
|
+
return new RoleCommandError('artifact_write_failed', 'artifact', roleFailedExitCode, message);
|
|
450
|
+
}
|
|
451
|
+
async function runRole(role, commandOptions, options) {
|
|
452
|
+
const roots = resolveRoleDriverRoots();
|
|
453
|
+
const defaultBaseRoot = roots.repoRoot ?? roots.packageRoot;
|
|
454
|
+
const defaultRoot = path_1.default.join(defaultBaseRoot, '.build/devtools-cli', role + '-' + executionSuffix());
|
|
455
|
+
const artifactRoot = path_1.default.resolve(commandOptions.artifactRoot ?? defaultRoot);
|
|
456
|
+
ensureDir(artifactRoot);
|
|
457
|
+
try {
|
|
458
|
+
const request = role === 'send' ?
|
|
459
|
+
await buildSendRequest(roots, artifactRoot, commandOptions) :
|
|
460
|
+
buildReceiveRequest(roots, artifactRoot, commandOptions);
|
|
461
|
+
const summary = runDriver(request, artifactRoot, roots);
|
|
462
|
+
const summaryPath = path_1.default.join(artifactRoot, 'summary.json');
|
|
463
|
+
const data = {
|
|
464
|
+
status: summary.status,
|
|
465
|
+
exit_code: summary.exit_code,
|
|
466
|
+
role: summary.role,
|
|
467
|
+
execution_id: summary.execution_id,
|
|
468
|
+
artifact_root: artifactRoot,
|
|
469
|
+
summary_path: summaryPath,
|
|
470
|
+
bootstrap_path: summary.bootstrap_path,
|
|
471
|
+
reason_code: summary.reason_code,
|
|
472
|
+
failed_stage: failedStage(summary),
|
|
473
|
+
};
|
|
474
|
+
if (summary.exit_code === 0 && summary.status === 'completed') {
|
|
475
|
+
printEnvelope(options, 0, 'OK', data);
|
|
476
|
+
return 0;
|
|
477
|
+
}
|
|
478
|
+
printEnvelope(options, 1, summary.reason_code ?? 'driver failed', data);
|
|
479
|
+
return summary.exit_code || 1;
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
const normalized = normalizeRoleError(error);
|
|
483
|
+
printEnvelope(options, 1, normalized.message, {
|
|
484
|
+
status: 'failed',
|
|
485
|
+
exit_code: normalized.exitCode,
|
|
486
|
+
role,
|
|
487
|
+
reason_code: normalized.reasonCode,
|
|
488
|
+
failed_stage: normalized.failedStage,
|
|
489
|
+
artifact_root: artifactRoot,
|
|
490
|
+
summary_path: path_1.default.join(artifactRoot, 'summary.json'),
|
|
491
|
+
});
|
|
492
|
+
return normalized.exitCode;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function runSendStart(commandOptions, options) {
|
|
496
|
+
return runRole('send', commandOptions, options);
|
|
497
|
+
}
|
|
498
|
+
function runReceiveStart(commandOptions, options) {
|
|
499
|
+
return runRole('receive', commandOptions, options);
|
|
500
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerTokenCommands = registerTokenCommands;
|
|
4
|
-
const facade_1 = require("./facade");
|
|
5
4
|
const token_tool_1 = require("./token_tool");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const kTokenIssueAccessKeyIdEnvVar = 'TIRTC_ACCESS_KEY_ID';
|
|
6
|
+
const kTokenIssueSecretKeyIdEnvVar = 'TIRTC_SECRET_KEY_ID';
|
|
7
|
+
const kTokenIssueAppIdEnvVar = 'TIRTC_APP_ID';
|
|
8
|
+
const errorReasonCodeMapping = {
|
|
9
|
+
internal_error: 5,
|
|
10
|
+
};
|
|
8
11
|
function normalizeTokenCommandError(error) {
|
|
9
12
|
if (error instanceof Error) {
|
|
10
13
|
return {
|
|
@@ -30,7 +33,7 @@ function normalizeTokenCommandError(error) {
|
|
|
30
33
|
function printTokenCommandError(error, options) {
|
|
31
34
|
const normalized = normalizeTokenCommandError(error);
|
|
32
35
|
const reasonCode = normalized.reasonCode;
|
|
33
|
-
const exitCode =
|
|
36
|
+
const exitCode = errorReasonCodeMapping[reasonCode] ?? 1;
|
|
34
37
|
if (options.json) {
|
|
35
38
|
console.log(JSON.stringify({
|
|
36
39
|
code: exitCode,
|
|
@@ -45,7 +48,16 @@ function printTokenCommandError(error, options) {
|
|
|
45
48
|
}
|
|
46
49
|
async function runTokenIssue(params, options) {
|
|
47
50
|
try {
|
|
48
|
-
const result = await (0, token_tool_1.issueTokenWithQrcode)(
|
|
51
|
+
const result = await (0, token_tool_1.issueTokenWithQrcode)({
|
|
52
|
+
accessId: params.accessKeyId,
|
|
53
|
+
secretKey: params.secretKeyId,
|
|
54
|
+
appId: params.appId,
|
|
55
|
+
remoteId: params.remoteId,
|
|
56
|
+
openapiEndpoint: params.openapiEndpoint,
|
|
57
|
+
endpoint: params.endpoint,
|
|
58
|
+
qrErrorCorrectionLevel: params.qrErrorCorrectionLevel,
|
|
59
|
+
asciiMaxColumns: params.asciiMaxColumns,
|
|
60
|
+
});
|
|
49
61
|
if (options.json) {
|
|
50
62
|
console.log(JSON.stringify({
|
|
51
63
|
code: 0,
|
|
@@ -90,7 +102,7 @@ async function runLicenseQrcode(params, options) {
|
|
|
90
102
|
return printTokenCommandError(error, options);
|
|
91
103
|
}
|
|
92
104
|
}
|
|
93
|
-
function
|
|
105
|
+
function resolveRequiredTokenIssueValue(explicitValue, fieldName, envVarName, optionName) {
|
|
94
106
|
const normalizedExplicit = explicitValue?.trim();
|
|
95
107
|
if (normalizedExplicit) {
|
|
96
108
|
return normalizedExplicit;
|
|
@@ -99,7 +111,7 @@ function resolveTokenIssueCredential(explicitValue, envVarName, optionName) {
|
|
|
99
111
|
if (normalizedEnv) {
|
|
100
112
|
return normalizedEnv;
|
|
101
113
|
}
|
|
102
|
-
throw new Error('missing
|
|
114
|
+
throw new Error('missing required ' + fieldName + ': set environment variable ' + envVarName +
|
|
103
115
|
' or pass ' + optionName + ' explicitly');
|
|
104
116
|
}
|
|
105
117
|
async function runTokenIssueFromCli(remoteId, commandOptions, options) {
|
|
@@ -124,11 +136,13 @@ async function runTokenIssueFromCli(remoteId, commandOptions, options) {
|
|
|
124
136
|
return normalized;
|
|
125
137
|
};
|
|
126
138
|
try {
|
|
127
|
-
const
|
|
128
|
-
const
|
|
139
|
+
const accessKeyId = resolveRequiredTokenIssueValue(commandOptions.accessKeyId, 'access_key_id', kTokenIssueAccessKeyIdEnvVar, '--access-key-id');
|
|
140
|
+
const secretKeyId = resolveRequiredTokenIssueValue(commandOptions.secretKeyId, 'secret_key_id', kTokenIssueSecretKeyIdEnvVar, '--secret-key-id');
|
|
141
|
+
const appId = resolveRequiredTokenIssueValue(commandOptions.appId, 'app_id', kTokenIssueAppIdEnvVar, '--app-id');
|
|
129
142
|
return await runTokenIssue({
|
|
130
|
-
|
|
131
|
-
|
|
143
|
+
accessKeyId,
|
|
144
|
+
secretKeyId,
|
|
145
|
+
appId,
|
|
132
146
|
remoteId,
|
|
133
147
|
openapiEndpoint: commandOptions.openapiEndpoint,
|
|
134
148
|
endpoint: commandOptions.endpoint,
|
|
@@ -181,9 +195,10 @@ async function runLicenseQrcodeFromCli(license, commandOptions, options) {
|
|
|
181
195
|
function registerTokenCommands(program, getCliOptions, runAndExit) {
|
|
182
196
|
const token = program.command('token').description('Token 工具:签发 token,并输出可直接使用的 JSON 与本地二维码 PNG');
|
|
183
197
|
token.command('issue <remote_id>')
|
|
184
|
-
.description('默认从环境变量读取
|
|
185
|
-
.option('--access-id <
|
|
186
|
-
.option('--secret-key <
|
|
198
|
+
.description('默认从环境变量读取 access_key_id / secret_key_id / app_id,并基于 remote_id 签发 token')
|
|
199
|
+
.option('--access-key-id <accessKeyId>', '显式 access_key_id;不传时读取 ' + kTokenIssueAccessKeyIdEnvVar)
|
|
200
|
+
.option('--secret-key-id <secretKeyId>', '显式 secret_key_id;不传时读取 ' + kTokenIssueSecretKeyIdEnvVar)
|
|
201
|
+
.option('--app-id <appId>', '必填 app_id;不传时读取 ' + kTokenIssueAppIdEnvVar)
|
|
187
202
|
.option('--openapi-endpoint <url>', '可选 openapi endpoint;传了就透传到底层签发')
|
|
188
203
|
.option('--endpoint <entry>', '可选 endpoint;传了就写入 payload 与二维码')
|
|
189
204
|
.option('--qr-error-correction-level <level>', '二维码纠错级别:L/M/Q/H;默认 M')
|