tirtc-devtools-cli 0.0.4 → 0.0.5
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/USAGE.md +16 -1
- package/dist/devtools/cli/src/guide.js +4 -1
- package/dist/devtools/cli/src/index.js +76 -36
- package/package.json +1 -1
package/USAGE.md
CHANGED
|
@@ -118,10 +118,13 @@ node devtools/cli/bin/tirtc-devtools-cli.js --help
|
|
|
118
118
|
|
|
119
119
|
用途:直接签发 token,并把调试所需的核心信息一次性输出到控制台,同时在本地生成二维码 PNG。
|
|
120
120
|
|
|
121
|
-
- `tirtc-devtools-cli token issue <
|
|
121
|
+
- `tirtc-devtools-cli token issue <peerId>`:签发 token;默认从环境变量读取凭据,并使用 `peerId` 作为默认 `localId`。
|
|
122
122
|
|
|
123
123
|
可选参数:
|
|
124
124
|
|
|
125
|
+
- `--access-id <accessId>`:显式传 access id;不传时读取 `TIRTC_CONN_ACCESS_ID`。
|
|
126
|
+
- `--secret-key <secretKey>`:显式传 secret key;不传时读取 `TIRTC_CONN_SECRET_KEY`。
|
|
127
|
+
- `--local-id <localId>`:显式传 local id;不传时默认使用 `peerId`。
|
|
125
128
|
- `--openapi-entry <url>`:覆盖默认 openapi entry。
|
|
126
129
|
- `--service-entry <entry>`:附加到组合 payload,便于扫码后直接连到目标服务。
|
|
127
130
|
- `--user-ttl-seconds <seconds>`:覆盖 user token ttl。
|
|
@@ -141,9 +144,21 @@ node devtools/cli/bin/tirtc-devtools-cli.js --help
|
|
|
141
144
|
|
|
142
145
|
- 组合 JSON 的 `type` 固定为 `tirtc-connect-token`。
|
|
143
146
|
- PNG 二维码承载的是组合 JSON,不再暴露 `secret_key`。
|
|
147
|
+
- CLI 不会在最终 JSON、控制台输出或二维码内容里打印 `access_id` 和 `secret_key`。
|
|
144
148
|
- `--json` 模式下只输出 `payload`、`payloadJson`、`token` 和 `qrCodePngPath`,不输出 ASCII 二维码。
|
|
145
149
|
- 如果觉得 ASCII 二维码太密,可把纠错级别从默认 `M` 调低到 `L`;如果希望更耐遮挡,可调高到 `Q` 或 `H`,但二维码会更密。
|
|
146
150
|
|
|
151
|
+
推荐默认做法:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
export TIRTC_CONN_ACCESS_ID="<ACCESS_ID>"
|
|
155
|
+
export TIRTC_CONN_SECRET_KEY="<SECRET_KEY>"
|
|
156
|
+
tirtc-devtools-cli --json token issue "<PEER_ID>"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
只有在你明确需要覆盖环境变量时,才额外传 `--access-id` 和 `--secret-key`。
|
|
160
|
+
只有在你明确需要不同的本地用户标识时,才额外传 `--local-id`。
|
|
161
|
+
|
|
147
162
|
### Stream
|
|
148
163
|
|
|
149
164
|
用途:管理音视频流的发送/接收与远端请求策略。
|
|
@@ -31,9 +31,12 @@ function printQuickstartGuide() {
|
|
|
31
31
|
' - 持 token + peer_id 连接服务端;连接成功后请求 audio_stream_id/video_stream_id',
|
|
32
32
|
'',
|
|
33
33
|
'额外:如果你只想本地直接签发并拿到可扫码 payload,可执行:',
|
|
34
|
-
'
|
|
34
|
+
' export TIRTC_CONN_ACCESS_ID="<ACCESS_ID>"',
|
|
35
|
+
' export TIRTC_CONN_SECRET_KEY="<SECRET_KEY>"',
|
|
36
|
+
' node devtools/cli/bin/tirtc-devtools-cli.js token issue "<LOCAL_ID>" "<PEER_ID>" \\',
|
|
35
37
|
' --service-entry "<SERVICE_ENTRY>"',
|
|
36
38
|
' # CLI 会直接打印摘要、payload JSON、token,并生成本地二维码 PNG 路径',
|
|
39
|
+
' # 如需临时覆盖,也可显式传 --access-id / --secret-key',
|
|
37
40
|
'',
|
|
38
41
|
'步骤 5:服务端观测',
|
|
39
42
|
' node devtools/cli/bin/tirtc-devtools-cli.js --session <SESSION_ID> events tail',
|
|
@@ -9,9 +9,11 @@ const session_manager_1 = require("./session_manager");
|
|
|
9
9
|
const media_assets_1 = require("./media_assets");
|
|
10
10
|
const transport_1 = require("./transport");
|
|
11
11
|
const token_tool_1 = require("./token_tool");
|
|
12
|
-
const CLI_VERSION = '0.0.
|
|
12
|
+
const CLI_VERSION = '0.0.5';
|
|
13
13
|
const HOST_VERSION = '1.0.0';
|
|
14
14
|
const PROTOCOL_VERSION = '1.0.0';
|
|
15
|
+
const kTokenIssueAccessIdEnvVar = 'TIRTC_CONN_ACCESS_ID';
|
|
16
|
+
const kTokenIssueSecretKeyEnvVar = 'TIRTC_CONN_SECRET_KEY';
|
|
15
17
|
if (process.argv.includes('--version') || process.argv.includes('-V')) {
|
|
16
18
|
console.log('CLI Version: ' + CLI_VERSION);
|
|
17
19
|
console.log('Host Version: ' + HOST_VERSION);
|
|
@@ -325,6 +327,60 @@ async function runTokenIssue(params, options) {
|
|
|
325
327
|
return exitCode;
|
|
326
328
|
}
|
|
327
329
|
}
|
|
330
|
+
async function runTokenIssueFromCli(peerId, commandOptions, options) {
|
|
331
|
+
const parsePositiveInt = (name, raw) => {
|
|
332
|
+
if (raw === undefined) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
const parsed = Number.parseInt(raw, 10);
|
|
336
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
337
|
+
throw new Error(name + ' must be a positive integer');
|
|
338
|
+
}
|
|
339
|
+
return parsed;
|
|
340
|
+
};
|
|
341
|
+
const parseQrErrorCorrectionLevel = (raw) => {
|
|
342
|
+
if (raw === undefined) {
|
|
343
|
+
return undefined;
|
|
344
|
+
}
|
|
345
|
+
const normalized = raw.trim().toUpperCase();
|
|
346
|
+
if (normalized !== 'L' && normalized !== 'M' && normalized !== 'Q' && normalized !== 'H') {
|
|
347
|
+
throw new Error('qr-error-correction-level must be one of: L, M, Q, H');
|
|
348
|
+
}
|
|
349
|
+
return normalized;
|
|
350
|
+
};
|
|
351
|
+
try {
|
|
352
|
+
const accessId = resolveTokenIssueCredential(commandOptions.accessId, kTokenIssueAccessIdEnvVar, '--access-id');
|
|
353
|
+
const secretKey = resolveTokenIssueCredential(commandOptions.secretKey, kTokenIssueSecretKeyEnvVar, '--secret-key');
|
|
354
|
+
return await runTokenIssue({
|
|
355
|
+
accessId,
|
|
356
|
+
secretKey,
|
|
357
|
+
localId: commandOptions.localId?.trim() || peerId,
|
|
358
|
+
peerId,
|
|
359
|
+
openapiEntry: commandOptions.openapiEntry,
|
|
360
|
+
serviceEntry: commandOptions.serviceEntry,
|
|
361
|
+
userTtlSeconds: parsePositiveInt('user-ttl-seconds', commandOptions.userTtlSeconds),
|
|
362
|
+
channelTtlSeconds: parsePositiveInt('channel-ttl-seconds', commandOptions.channelTtlSeconds),
|
|
363
|
+
qrErrorCorrectionLevel: parseQrErrorCorrectionLevel(commandOptions.qrErrorCorrectionLevel),
|
|
364
|
+
asciiMaxColumns: parsePositiveInt('ascii-max-columns', commandOptions.asciiMaxColumns),
|
|
365
|
+
}, options);
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
const normalized = normalizeError(error);
|
|
369
|
+
const reasonCode = normalized.reasonCode;
|
|
370
|
+
const exitCode = facade_1.ErrorReasonCodeMapping[reasonCode] ?? 1;
|
|
371
|
+
if (options.json) {
|
|
372
|
+
console.log(JSON.stringify({
|
|
373
|
+
code: exitCode,
|
|
374
|
+
message: normalized.message,
|
|
375
|
+
data: normalized.data,
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
console.error('Error (' + reasonCode + '): ' + normalized.message);
|
|
380
|
+
}
|
|
381
|
+
return exitCode;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
328
384
|
function runAndExit(promise) {
|
|
329
385
|
promise.then((code) => {
|
|
330
386
|
process.exit(code);
|
|
@@ -339,6 +395,18 @@ function mustParseJsonPayload(input) {
|
|
|
339
395
|
throw new Error('payloadJson must be valid JSON text');
|
|
340
396
|
}
|
|
341
397
|
}
|
|
398
|
+
function resolveTokenIssueCredential(explicitValue, envVarName, optionName) {
|
|
399
|
+
const normalizedExplicit = explicitValue?.trim();
|
|
400
|
+
if (normalizedExplicit) {
|
|
401
|
+
return normalizedExplicit;
|
|
402
|
+
}
|
|
403
|
+
const normalizedEnv = process.env[envVarName]?.trim();
|
|
404
|
+
if (normalizedEnv) {
|
|
405
|
+
return normalizedEnv;
|
|
406
|
+
}
|
|
407
|
+
throw new Error('missing credential: set environment variable ' + envVarName +
|
|
408
|
+
' or pass ' + optionName + ' explicitly');
|
|
409
|
+
}
|
|
342
410
|
program.name('tirtc-devtools-cli')
|
|
343
411
|
.description('TiRTC DevTools CLI')
|
|
344
412
|
.option('--config <path>', '配置文件路径(TOML)')
|
|
@@ -545,47 +613,19 @@ connection.command('disconnect').description('断开当前连接').action(() =>
|
|
|
545
613
|
runAndExit(runCommand('connection disconnect', {}, getCliOptions()));
|
|
546
614
|
});
|
|
547
615
|
const token = program.command('token').description('Token 工具:签发 token,并输出可直接使用的 JSON 与本地二维码 PNG');
|
|
548
|
-
token.command('issue <
|
|
549
|
-
.description('
|
|
616
|
+
token.command('issue <peer_id>')
|
|
617
|
+
.description('默认从环境变量读取 access/secret,并以 peer_id 作为默认 local_id 来签发 token')
|
|
618
|
+
.option('--access-id <accessId>', '显式 access id;不传时读取 ' + kTokenIssueAccessIdEnvVar)
|
|
619
|
+
.option('--secret-key <secretKey>', '显式 secret key;不传时读取 ' + kTokenIssueSecretKeyEnvVar)
|
|
620
|
+
.option('--local-id <localId>', '显式 local id;不传时默认使用 peer_id')
|
|
550
621
|
.option('--openapi-entry <url>', '可选 openapi entry;留空时走 runtime 默认值')
|
|
551
622
|
.option('--service-entry <entry>', '可选 service entry;用于组合连接 payload 与二维码 PNG')
|
|
552
623
|
.option('--user-ttl-seconds <seconds>', '可选 user token ttl(秒)')
|
|
553
624
|
.option('--channel-ttl-seconds <seconds>', '可选 channel token ttl(秒)')
|
|
554
625
|
.option('--qr-error-correction-level <level>', '二维码纠错级别:L/M/Q/H;默认 M')
|
|
555
626
|
.option('--ascii-max-columns <columns>', 'ASCII 二维码最大宽度;不传时优先读取当前终端宽度或 COLUMNS')
|
|
556
|
-
.action((
|
|
557
|
-
|
|
558
|
-
if (raw === undefined) {
|
|
559
|
-
return undefined;
|
|
560
|
-
}
|
|
561
|
-
const parsed = Number.parseInt(raw, 10);
|
|
562
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
563
|
-
throw new Error(name + ' must be a positive integer');
|
|
564
|
-
}
|
|
565
|
-
return parsed;
|
|
566
|
-
};
|
|
567
|
-
const parseQrErrorCorrectionLevel = (raw) => {
|
|
568
|
-
if (raw === undefined) {
|
|
569
|
-
return undefined;
|
|
570
|
-
}
|
|
571
|
-
const normalized = raw.trim().toUpperCase();
|
|
572
|
-
if (normalized !== 'L' && normalized !== 'M' && normalized !== 'Q' && normalized !== 'H') {
|
|
573
|
-
throw new Error('qr-error-correction-level must be one of: L, M, Q, H');
|
|
574
|
-
}
|
|
575
|
-
return normalized;
|
|
576
|
-
};
|
|
577
|
-
runAndExit(runTokenIssue({
|
|
578
|
-
accessId: access_id,
|
|
579
|
-
secretKey: secret_key,
|
|
580
|
-
localId: local_id,
|
|
581
|
-
peerId: peer_id,
|
|
582
|
-
openapiEntry: commandOptions.openapiEntry,
|
|
583
|
-
serviceEntry: commandOptions.serviceEntry,
|
|
584
|
-
userTtlSeconds: parsePositiveInt('user-ttl-seconds', commandOptions.userTtlSeconds),
|
|
585
|
-
channelTtlSeconds: parsePositiveInt('channel-ttl-seconds', commandOptions.channelTtlSeconds),
|
|
586
|
-
qrErrorCorrectionLevel: parseQrErrorCorrectionLevel(commandOptions.qrErrorCorrectionLevel),
|
|
587
|
-
asciiMaxColumns: parsePositiveInt('ascii-max-columns', commandOptions.asciiMaxColumns),
|
|
588
|
-
}, getCliOptions()));
|
|
627
|
+
.action((peer_id, commandOptions) => {
|
|
628
|
+
runAndExit(runTokenIssueFromCli(peer_id, commandOptions, getCliOptions()));
|
|
589
629
|
});
|
|
590
630
|
const stream = program.command('stream').description('流控制:发送/接收/请求策略');
|
|
591
631
|
stream.command('list').description('查看流快照列表').action(() => {
|