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 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 <accessId> <secretKey> <localId> <peerId>`:签发 token。
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
- ' node devtools/cli/bin/tirtc-devtools-cli.js token issue "<ACCESS_ID>" "<SECRET_KEY>" "<LOCAL_ID>" "<PEER_ID>" \\',
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.4';
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 <access_id> <secret_key> <local_id> <peer_id>')
549
- .description('使用 access/secret/local/peer 签发 token;输出摘要、payload JSON、token 和二维码 PNG 路径')
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((access_id, secret_key, local_id, peer_id, commandOptions) => {
557
- const parsePositiveInt = (name, raw) => {
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(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirtc-devtools-cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "bin": {