tirtc-devtools-cli 0.0.13 → 0.0.15
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 +87 -312
- 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 +4 -2
- 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 +2 -4
- package/dist/cli/src/token_tool.js +12 -186
- package/package.json +3 -2
- 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 +56 -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 +52 -0
- package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/error.h +11 -0
- package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_downlink.h +11 -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 +7 -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 -48
- 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/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 -52
- 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 -23
- package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +0 -115
- 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,11 +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
5
|
const kTokenIssueAccessKeyIdEnvVar = 'TIRTC_ACCESS_KEY_ID';
|
|
7
6
|
const kTokenIssueSecretKeyIdEnvVar = 'TIRTC_SECRET_KEY_ID';
|
|
8
7
|
const kTokenIssueAppIdEnvVar = 'TIRTC_APP_ID';
|
|
8
|
+
const errorReasonCodeMapping = {
|
|
9
|
+
internal_error: 5,
|
|
10
|
+
};
|
|
9
11
|
function normalizeTokenCommandError(error) {
|
|
10
12
|
if (error instanceof Error) {
|
|
11
13
|
return {
|
|
@@ -31,7 +33,7 @@ function normalizeTokenCommandError(error) {
|
|
|
31
33
|
function printTokenCommandError(error, options) {
|
|
32
34
|
const normalized = normalizeTokenCommandError(error);
|
|
33
35
|
const reasonCode = normalized.reasonCode;
|
|
34
|
-
const exitCode =
|
|
36
|
+
const exitCode = errorReasonCodeMapping[reasonCode] ?? 1;
|
|
35
37
|
if (options.json) {
|
|
36
38
|
console.log(JSON.stringify({
|
|
37
39
|
code: exitCode,
|