tirtc-devtools-cli 0.0.11 → 0.0.13

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.
Files changed (31) hide show
  1. package/README.md +1 -1
  2. package/USAGE.md +85 -13
  3. package/dist/cli/src/guide.js +4 -3
  4. package/dist/cli/src/index.js +13 -13
  5. package/dist/cli/src/token_command.js +39 -31
  6. package/dist/cli/src/token_tool.d.ts +10 -17
  7. package/dist/cli/src/token_tool.js +84 -31
  8. package/package.json +1 -1
  9. package/vendor/app-server/bin/native/linux-x64/credential_napi.node +0 -0
  10. package/vendor/app-server/bin/native/macos-arm64/credential_napi.node +0 -0
  11. package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/error.h +36 -17
  12. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_credential.a +0 -0
  13. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_http.a +0 -0
  14. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  15. package/vendor/app-server/bin/runtime/linux-x64/manifest.txt +1 -1
  16. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/audio.h +39 -316
  17. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/av.h +33 -372
  18. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/error.h +36 -17
  19. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_downlink.h +47 -0
  20. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/trp.h +57 -325
  21. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_audio.a +0 -0
  22. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_credential.a +0 -0
  23. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
  24. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_foundation_http.a +0 -0
  25. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  26. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
  27. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
  28. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
  29. package/vendor/app-server/bin/runtime/macos-arm64/manifest.txt +14 -14
  30. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.d.ts +2 -5
  31. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +2 -5
package/README.md CHANGED
@@ -20,7 +20,7 @@
20
20
  - **产品级 Observability**:将底层的运行时事件和状态翻译为结构化输出 (JSON) 或友好的终端日志输出;对长耗时命令补轻量进度提示。
21
21
  - **调试期工具内聚**:承接调试期必要工具(如 token bootstrap、二维码与媒体预处理)的产品化入口,避免把调试流程散落在 runtime 或外部手工步骤中。
22
22
  - **本地 token 工具**:提供直接签发 token、打印组合 JSON、单独 token 与本地二维码 PNG 路径的公开 CLI 能力,服务本地联调与体验验证。
23
- - **本地 license 二维码工具**:提供 server 扫码用的 license JSON 二维码生成能力,支持可选 `service_entry`。
23
+ - **本地 license 二维码工具**:提供 server 扫码用的 license JSON 二维码生成能力,支持可选 `endpoint`。
24
24
 
25
25
  ## 不负责什么
26
26
 
package/USAGE.md CHANGED
@@ -70,6 +70,7 @@ node products/cli/bin/tirtc-devtools-cli.js service --help
70
70
  node products/cli/bin/tirtc-devtools-cli.js stream --help
71
71
  node products/cli/bin/tirtc-devtools-cli.js command --help
72
72
  node products/cli/bin/tirtc-devtools-cli.js token issue --help
73
+ node products/cli/bin/tirtc-devtools-cli.js license qrcode --help
73
74
  ```
74
75
 
75
76
  当前关键子菜单快照:
@@ -96,20 +97,22 @@ Commands:
96
97
  tail 持续监听命令相关事件
97
98
 
98
99
  $ node ... token issue --help
100
+ Usage: tirtc-devtools-cli token issue [options] <remote_id>
101
+
99
102
  Options:
100
- --access-id <accessId>
101
- --secret-key <secretKey>
102
- --local-id <localId>
103
- --openapi-entry <url>
104
- --service-entry <entry>
105
- --user-ttl-seconds <seconds>
106
- --channel-ttl-seconds <seconds>
103
+ --access-key-id <accessKeyId>
104
+ --secret-key-id <secretKeyId>
105
+ --app-id <appId>
106
+ --openapi-endpoint <url>
107
+ --endpoint <entry>
107
108
  --qr-error-correction-level <level>
108
109
  --ascii-max-columns <columns>
109
110
 
110
111
  $ node ... license qrcode --help
112
+ Usage: tirtc-devtools-cli license qrcode [options] <license>
113
+
111
114
  Options:
112
- --service-entry <entry>
115
+ --endpoint <entry>
113
116
  --qr-error-correction-level <level>
114
117
  --ascii-max-columns <columns>
115
118
  ```
@@ -143,7 +146,6 @@ license = "runtime-license"
143
146
  mp4_path = "/Users/allenfeng/Development/Repositories/tirtc-nexus/tirtc-matrix/.refers/simple.mp4"
144
147
  video_stream_id = 11
145
148
  audio_stream_id = 10
146
-
147
149
  ```
148
150
 
149
151
  说明:
@@ -250,10 +252,80 @@ CLI 仍会在本地收紧最小组合矩阵:
250
252
 
251
253
  `command request` 是 canonical 主语,`command send` 只保留为兼容别名。若要发 JSON,请把 JSON 文本作为 `payload` 传入。`command pending list` 用于恢复或轮询当前积压,`command reply` 基于 `remoteRequestId` 显式回复待处理请求。
252
254
 
253
- ## 十、token / debug / report
255
+ ## 十、token / license / debug / report
256
+
257
+ ### token issue
258
+
259
+ 命令形态:
260
+
261
+ ```bash
262
+ export TIRTC_ACCESS_KEY_ID="<ACCESS_KEY_ID>"
263
+ export TIRTC_SECRET_KEY_ID="<SECRET_KEY_ID>"
264
+ export TIRTC_APP_ID="<APP_ID>"
265
+ node products/cli/bin/tirtc-devtools-cli.js --json token issue <REMOTE_ID>
266
+ ```
267
+
268
+ 如果要覆盖默认 endpoint,并显式透传给底层签发路径:
269
+
270
+ ```bash
271
+ node products/cli/bin/tirtc-devtools-cli.js --json token issue <REMOTE_ID> \
272
+ --endpoint <ENDPOINT> \
273
+ --openapi-endpoint <OPENAPI_ENDPOINT>
274
+ ```
275
+
276
+ 当前 CLI 合同:
277
+
278
+ - 位置参数改为 `<remote_id>`。
279
+ - `app_id` 必填;可通过 `--app-id` 或 `TIRTC_APP_ID` 提供。
280
+ - `--endpoint` 取代旧 `--service-entry`。
281
+ - `--openapi-endpoint` 取代旧 `--openapi-entry`。
282
+ - 不再接收 `local_id`。
283
+ - 显式传入的 `endpoint` / `openapi_endpoint` 会透传给 C 层签发路径;其中 `app_id` / `endpoint` / `openapi_endpoint` 会进入二维码 payload。
284
+ - 若未显式传入 `endpoint` / `openapi_endpoint`,则 payload 中不再补默认字段。
285
+
286
+ `--json` 输出保持外层 envelope 不变:
287
+
288
+ ```json
289
+ {
290
+ "code": 0,
291
+ "message": "OK",
292
+ "data": {
293
+ "payload": {
294
+ "app_id": "AD_testapp",
295
+ "remote_id": "TESTFENGJUN4",
296
+ "token": "<TOKEN>",
297
+ "endpoint": "http://ep-test-tirtc.tange365.com",
298
+ "openapi_endpoint": "http://api-test-tirtc.tange365.com"
299
+ },
300
+ "payloadJson": "{\"app_id\":\"AD_testapp\",\"remote_id\":\"TESTFENGJUN4\",\"token\":\"<TOKEN>\",\"endpoint\":\"http://ep-test-tirtc.tange365.com\",\"openapi_endpoint\":\"http://api-test-tirtc.tange365.com\"}",
301
+ "token": "<TOKEN>",
302
+ "qrCodePngPath": "/absolute/path/to/token-*.png"
303
+ }
304
+ }
305
+ ```
306
+
307
+ 说明:
308
+
309
+ - payload 只保留 `app_id`、`remote_id`、`token`、可选 `endpoint`、可选 `openapi_endpoint`。
310
+ - 已删除字段不再出现:`version`、`type`、`local_id`、`peer_id`、`openapi_entry`、`service_entry`、`user_ttl_seconds`、`channel_ttl_seconds`、`generated_at`。
311
+
312
+ ### license qrcode
313
+
314
+ 命令形态:
315
+
316
+ ```bash
317
+ node products/cli/bin/tirtc-devtools-cli.js --json license qrcode <LICENSE>
318
+ node products/cli/bin/tirtc-devtools-cli.js --json license qrcode <LICENSE> --endpoint <ENDPOINT>
319
+ ```
320
+
321
+ 当前 CLI 合同:
322
+
323
+ - 只保留 `license` 和可选 `endpoint`。
324
+ - `--endpoint` 取代旧 `--service-entry`。
325
+ - 若未显式传入 `endpoint`,payload 中不再补默认字段。
326
+
327
+ ### 其他命令
254
328
 
255
- - `token issue <peerId>`:本地签发 token。
256
- - `license qrcode <license>`:本地生成 server 扫码二维码。
257
329
  - `debug bootstrap qrcode ...` / `debug bootstrap qrcode-from-config`:生成联调用二维码。
258
330
  - `events tail`:实时查看事件流。
259
331
  - `logs export <outputPath>`:导出日志。
@@ -267,7 +339,7 @@ CLI 仍会在本地收紧最小组合矩阵:
267
339
  - `client.local.toml` 字段:`[client]` + `[debug.token_issue]`
268
340
  - CLI server-only E2E 不再要求先手工 `media assets prepare` 再回填 `assetsDir`
269
341
 
270
- ## 十一、Android 人工闭环脚本
342
+ ## 十二、Android 人工闭环脚本
271
343
 
272
344
  如果需要把 CLI 侧闭环常驻起来,再手工去操作 Android example,使用:
273
345
 
@@ -21,9 +21,10 @@ function printQuickstartGuide() {
21
21
  ' # service start 成功后会自动 prepare 并按 AUTO_ON_CONNECTED 进入待发流语义',
22
22
  '',
23
23
  '步骤 3:显式签发 client token(可本地执行,也可由外部系统提供)',
24
- ' export TIRTC_CONN_ACCESS_ID="<ACCESS_ID>"',
25
- ' export TIRTC_CONN_SECRET_KEY="<SECRET_KEY>"',
26
- ' node products/cli/bin/tirtc-devtools-cli.js --json token issue "<PEER_ID>" --service-entry "<SERVICE_ENTRY>"',
24
+ ' export TIRTC_ACCESS_KEY_ID="<ACCESS_KEY_ID>"',
25
+ ' export TIRTC_SECRET_KEY_ID="<SECRET_KEY_ID>"',
26
+ ' export TIRTC_APP_ID="<APP_ID>"',
27
+ ' node products/cli/bin/tirtc-devtools-cli.js --json token issue "<REMOTE_ID>" --endpoint "<ENDPOINT>"',
27
28
  '',
28
29
  '步骤 4:启动 client 本地 web preview',
29
30
  ' node products/cli/bin/tirtc-devtools-cli.js --config ./client.toml client start --token "<TOKEN>"',
@@ -11,7 +11,7 @@ const media_assets_1 = require("./media_assets");
11
11
  const token_command_1 = require("./token_command");
12
12
  const transport_1 = require("./transport");
13
13
  const progress_1 = require("./progress");
14
- const CLI_VERSION = '0.0.10';
14
+ const CLI_VERSION = '0.0.13';
15
15
  const HOST_VERSION = '1.0.0';
16
16
  const PROTOCOL_VERSION = '1.0.0';
17
17
  if (process.argv.includes('--version') || process.argv.includes('-V')) {
@@ -585,15 +585,15 @@ const debugBootstrap = debug.command('bootstrap').description('连接 bootstrap
585
585
  debugBootstrap.command('qrcode <access_id> <secret_key> <peer_id> [service_entry]')
586
586
  .description('生成客户端连接 bootstrap 二维码(payload 包含 access_id/secret_key/peer_id)')
587
587
  .action((accessId, secretKey, peerId, serviceEntry) => {
588
- const payload = JSON.stringify({
589
- version: 1,
590
- type: 'tirtc-connect-bootstrap',
588
+ const payloadObject = {
591
589
  access_id: accessId,
592
590
  secret_key: secretKey,
593
591
  peer_id: peerId,
594
- service_entry: serviceEntry ?? '',
595
- generated_at: new Date().toISOString(),
596
- });
592
+ };
593
+ if (serviceEntry && serviceEntry.length > 0) {
594
+ payloadObject.service_entry = serviceEntry;
595
+ }
596
+ const payload = JSON.stringify(payloadObject);
597
597
  runAndExit(runCommand('debug bootstrap qrcode', { payload, outputStem: 'connect-bootstrap' }, getCliOptions()));
598
598
  });
599
599
  debugBootstrap.command('qrcode-from-config')
@@ -607,15 +607,15 @@ debugBootstrap.command('qrcode-from-config')
607
607
  if (!bootstrap.access_id || !bootstrap.secret_key || !bootstrap.peer_id) {
608
608
  throw new Error('debug.connect_bootstrap requires access_id + secret_key + peer_id');
609
609
  }
610
- const payload = JSON.stringify({
611
- version: 1,
612
- type: 'tirtc-connect-bootstrap',
610
+ const payloadObject = {
613
611
  access_id: bootstrap.access_id,
614
612
  secret_key: bootstrap.secret_key,
615
613
  peer_id: bootstrap.peer_id,
616
- service_entry: bootstrap.service_entry ?? '',
617
- generated_at: new Date().toISOString(),
618
- });
614
+ };
615
+ if (bootstrap.service_entry && bootstrap.service_entry.length > 0) {
616
+ payloadObject.service_entry = bootstrap.service_entry;
617
+ }
618
+ const payload = JSON.stringify(payloadObject);
619
619
  runAndExit(runCommand('debug bootstrap qrcode', { payload, outputStem: 'connect-bootstrap' }, getCliOptions()));
620
620
  });
621
621
  const events = program.command('events').description('事件订阅:实时观察 Host 事件');
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerTokenCommands = registerTokenCommands;
4
4
  const facade_1 = require("./facade");
5
5
  const token_tool_1 = require("./token_tool");
6
- const kTokenIssueAccessIdEnvVar = 'TIRTC_CONN_ACCESS_ID';
7
- const kTokenIssueSecretKeyEnvVar = 'TIRTC_CONN_SECRET_KEY';
6
+ const kTokenIssueAccessKeyIdEnvVar = 'TIRTC_ACCESS_KEY_ID';
7
+ const kTokenIssueSecretKeyIdEnvVar = 'TIRTC_SECRET_KEY_ID';
8
+ const kTokenIssueAppIdEnvVar = 'TIRTC_APP_ID';
8
9
  function normalizeTokenCommandError(error) {
9
10
  if (error instanceof Error) {
10
11
  return {
@@ -45,7 +46,16 @@ function printTokenCommandError(error, options) {
45
46
  }
46
47
  async function runTokenIssue(params, options) {
47
48
  try {
48
- const result = await (0, token_tool_1.issueTokenWithQrcode)(params);
49
+ const result = await (0, token_tool_1.issueTokenWithQrcode)({
50
+ accessId: params.accessKeyId,
51
+ secretKey: params.secretKeyId,
52
+ appId: params.appId,
53
+ remoteId: params.remoteId,
54
+ openapiEndpoint: params.openapiEndpoint,
55
+ endpoint: params.endpoint,
56
+ qrErrorCorrectionLevel: params.qrErrorCorrectionLevel,
57
+ asciiMaxColumns: params.asciiMaxColumns,
58
+ });
49
59
  if (options.json) {
50
60
  console.log(JSON.stringify({
51
61
  code: 0,
@@ -90,7 +100,7 @@ async function runLicenseQrcode(params, options) {
90
100
  return printTokenCommandError(error, options);
91
101
  }
92
102
  }
93
- function resolveTokenIssueCredential(explicitValue, envVarName, optionName) {
103
+ function resolveRequiredTokenIssueValue(explicitValue, fieldName, envVarName, optionName) {
94
104
  const normalizedExplicit = explicitValue?.trim();
95
105
  if (normalizedExplicit) {
96
106
  return normalizedExplicit;
@@ -99,10 +109,10 @@ function resolveTokenIssueCredential(explicitValue, envVarName, optionName) {
99
109
  if (normalizedEnv) {
100
110
  return normalizedEnv;
101
111
  }
102
- throw new Error('missing credential: set environment variable ' + envVarName +
112
+ throw new Error('missing required ' + fieldName + ': set environment variable ' + envVarName +
103
113
  ' or pass ' + optionName + ' explicitly');
104
114
  }
105
- async function runTokenIssueFromCli(peerId, commandOptions, options) {
115
+ async function runTokenIssueFromCli(remoteId, commandOptions, options) {
106
116
  const parsePositiveInt = (name, raw) => {
107
117
  if (raw === undefined) {
108
118
  return undefined;
@@ -124,17 +134,16 @@ async function runTokenIssueFromCli(peerId, commandOptions, options) {
124
134
  return normalized;
125
135
  };
126
136
  try {
127
- const accessId = resolveTokenIssueCredential(commandOptions.accessId, kTokenIssueAccessIdEnvVar, '--access-id');
128
- const secretKey = resolveTokenIssueCredential(commandOptions.secretKey, kTokenIssueSecretKeyEnvVar, '--secret-key');
137
+ const accessKeyId = resolveRequiredTokenIssueValue(commandOptions.accessKeyId, 'access_key_id', kTokenIssueAccessKeyIdEnvVar, '--access-key-id');
138
+ const secretKeyId = resolveRequiredTokenIssueValue(commandOptions.secretKeyId, 'secret_key_id', kTokenIssueSecretKeyIdEnvVar, '--secret-key-id');
139
+ const appId = resolveRequiredTokenIssueValue(commandOptions.appId, 'app_id', kTokenIssueAppIdEnvVar, '--app-id');
129
140
  return await runTokenIssue({
130
- accessId,
131
- secretKey,
132
- localId: commandOptions.localId?.trim() || peerId,
133
- peerId,
134
- openapiEntry: commandOptions.openapiEntry,
135
- serviceEntry: commandOptions.serviceEntry,
136
- userTtlSeconds: parsePositiveInt('user-ttl-seconds', commandOptions.userTtlSeconds),
137
- channelTtlSeconds: parsePositiveInt('channel-ttl-seconds', commandOptions.channelTtlSeconds),
141
+ accessKeyId,
142
+ secretKeyId,
143
+ appId,
144
+ remoteId,
145
+ openapiEndpoint: commandOptions.openapiEndpoint,
146
+ endpoint: commandOptions.endpoint,
138
147
  qrErrorCorrectionLevel: parseQrErrorCorrectionLevel(commandOptions.qrErrorCorrectionLevel),
139
148
  asciiMaxColumns: parsePositiveInt('ascii-max-columns', commandOptions.asciiMaxColumns),
140
149
  }, options);
@@ -169,11 +178,12 @@ async function runLicenseQrcodeFromCli(license, commandOptions, options) {
169
178
  if (normalizedLicense.length === 0) {
170
179
  throw new Error('license must not be empty');
171
180
  }
181
+ const asciiMaxColumns = commandOptions.asciiMaxColumns === undefined ? undefined : parsePositiveInt('ascii-max-columns', commandOptions.asciiMaxColumns);
172
182
  return await runLicenseQrcode({
173
183
  license: normalizedLicense,
174
- serviceEntry: commandOptions.serviceEntry,
184
+ endpoint: commandOptions.endpoint,
175
185
  qrErrorCorrectionLevel: parseQrErrorCorrectionLevel(commandOptions.qrErrorCorrectionLevel),
176
- asciiMaxColumns: parsePositiveInt('ascii-max-columns', commandOptions.asciiMaxColumns),
186
+ asciiMaxColumns,
177
187
  }, options);
178
188
  }
179
189
  catch (error) {
@@ -182,24 +192,22 @@ async function runLicenseQrcodeFromCli(license, commandOptions, options) {
182
192
  }
183
193
  function registerTokenCommands(program, getCliOptions, runAndExit) {
184
194
  const token = program.command('token').description('Token 工具:签发 token,并输出可直接使用的 JSON 与本地二维码 PNG');
185
- token.command('issue <peer_id>')
186
- .description('默认从环境变量读取 access/secret,并以 peer_id 作为默认 local_id 来签发 token')
187
- .option('--access-id <accessId>', '显式 access id;不传时读取 ' + kTokenIssueAccessIdEnvVar)
188
- .option('--secret-key <secretKey>', '显式 secret key;不传时读取 ' + kTokenIssueSecretKeyEnvVar)
189
- .option('--local-id <localId>', '显式 local id;不传时默认使用 peer_id')
190
- .option('--openapi-entry <url>', '可选 openapi entry;留空时走 runtime 默认值')
191
- .option('--service-entry <entry>', '可选 service entry;用于组合连接 payload 与二维码 PNG')
192
- .option('--user-ttl-seconds <seconds>', '可选 user token ttl(秒)')
193
- .option('--channel-ttl-seconds <seconds>', '可选 channel token ttl(秒)')
195
+ token.command('issue <remote_id>')
196
+ .description('默认从环境变量读取 access_key_id / secret_key_id / app_id,并基于 remote_id 签发 token')
197
+ .option('--access-key-id <accessKeyId>', '显式 access_key_id;不传时读取 ' + kTokenIssueAccessKeyIdEnvVar)
198
+ .option('--secret-key-id <secretKeyId>', '显式 secret_key_id;不传时读取 ' + kTokenIssueSecretKeyIdEnvVar)
199
+ .option('--app-id <appId>', '必填 app_id;不传时读取 ' + kTokenIssueAppIdEnvVar)
200
+ .option('--openapi-endpoint <url>', '可选 openapi endpoint;传了就透传到底层签发')
201
+ .option('--endpoint <entry>', '可选 endpoint;传了就写入 payload 与二维码')
194
202
  .option('--qr-error-correction-level <level>', '二维码纠错级别:L/M/Q/H;默认 M')
195
203
  .option('--ascii-max-columns <columns>', 'ASCII 二维码最大宽度;不传时优先读取当前终端宽度或 COLUMNS')
196
- .action((peerId, commandOptions) => {
197
- runAndExit(runTokenIssueFromCli(peerId, commandOptions, getCliOptions()));
204
+ .action((remoteId, commandOptions) => {
205
+ runAndExit(runTokenIssueFromCli(remoteId, commandOptions, getCliOptions()));
198
206
  });
199
207
  const license = program.command('license').description('License 工具:生成 server 扫码 JSON 与本地二维码 PNG');
200
208
  license.command('qrcode <license>')
201
- .description('生成包含 license 与可选 service_entry 的本地二维码')
202
- .option('--service-entry <entry>', '可选 service entry;留空时消费端走默认值')
209
+ .description('生成包含 license 与可选 endpoint 的本地二维码')
210
+ .option('--endpoint <entry>', '可选 endpoint;传了就写入 payload 与二维码')
203
211
  .option('--qr-error-correction-level <level>', '二维码纠错级别:L/M/Q/H;默认 M')
204
212
  .option('--ascii-max-columns <columns>', 'ASCII 二维码最大宽度;不传时优先读取当前终端宽度或 COLUMNS')
205
213
  .action((licenseValue, commandOptions) => {
@@ -1,26 +1,19 @@
1
1
  export type TokenIssueInput = {
2
2
  accessId: string;
3
3
  secretKey: string;
4
- localId: string;
5
- peerId: string;
6
- openapiEntry?: string;
7
- serviceEntry?: string;
8
- userTtlSeconds?: number;
9
- channelTtlSeconds?: number;
4
+ appId: string;
5
+ remoteId: string;
6
+ openapiEndpoint?: string;
7
+ endpoint?: string;
10
8
  qrErrorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
11
9
  asciiMaxColumns?: number;
12
10
  };
13
11
  export type IssuedTokenPayload = {
14
- version: 1;
15
- type: 'tirtc-connect-token';
16
- peer_id: string;
17
- local_id: string;
18
- service_entry: string;
12
+ app_id: string;
13
+ remote_id: string;
19
14
  token: string;
20
- openapi_entry: string;
21
- user_ttl_seconds: number;
22
- channel_ttl_seconds: number;
23
- generated_at: string;
15
+ endpoint?: string;
16
+ openapi_endpoint?: string;
24
17
  };
25
18
  export type TokenIssueOutput = {
26
19
  payload: IssuedTokenPayload;
@@ -32,13 +25,13 @@ export type TokenIssueOutput = {
32
25
  };
33
26
  export type LicenseQrcodeInput = {
34
27
  license: string;
35
- serviceEntry?: string;
28
+ endpoint?: string;
36
29
  qrErrorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
37
30
  asciiMaxColumns?: number;
38
31
  };
39
32
  export type LicenseQrcodePayload = {
40
33
  license: string;
41
- service_entry: string;
34
+ endpoint?: string;
42
35
  };
43
36
  export type LicenseQrcodeOutput = {
44
37
  payload: LicenseQrcodePayload;
@@ -51,9 +51,6 @@ const fs_1 = __importDefault(require("fs"));
51
51
  const path_1 = __importDefault(require("path"));
52
52
  const qrcode_1 = __importDefault(require("qrcode"));
53
53
  const embedded_paths_1 = require("./embedded_paths");
54
- const kDefaultOpenapiEntry = 'http://api-test-tirtc.tange365.com';
55
- const kDefaultUserTtlSeconds = 86400;
56
- const kDefaultChannelTtlSeconds = 300;
57
54
  const kAsciiQrQuietZoneModules = 2;
58
55
  function pathExists(filePath) {
59
56
  return fs_1.default.existsSync(filePath);
@@ -76,7 +73,7 @@ function buildQrCodePngPath(prefix, ...parts) {
76
73
  return path_1.default.join(resolveQrCodeOutputDir(), fileName);
77
74
  }
78
75
  function buildTokenQrCodePngPath(payload) {
79
- return buildQrCodePngPath('token', payload.local_id, payload.peer_id);
76
+ return buildQrCodePngPath('token', payload.remote_id);
80
77
  }
81
78
  function buildLicenseQrCodePngPath(payload) {
82
79
  return buildQrCodePngPath('license', payload.license);
@@ -206,13 +203,10 @@ function buildIssueTokenHelperSource() {
206
203
  '});',
207
204
  'try {',
208
205
  ' const token = addon.issueToken({',
209
- ' openapiEntry: input.openapiEntry,',
206
+ ' openapiEndpoint: input.openapiEndpoint,',
210
207
  ' accessId: input.accessId,',
211
208
  ' secretKey: input.secretKey,',
212
- ' localId: input.localId,',
213
- ' peerId: input.peerId,',
214
- ' userTtlSeconds: input.userTtlSeconds,',
215
- ' channelTtlSeconds: input.channelTtlSeconds,',
209
+ ' remoteId: input.remoteId,',
216
210
  ' });',
217
211
  ' process.stdout.write(String(token).trim());',
218
212
  '} finally {',
@@ -220,6 +214,62 @@ function buildIssueTokenHelperSource() {
220
214
  '}',
221
215
  ].join('\n');
222
216
  }
217
+ function parseIssueTokenFailure(message) {
218
+ const matched = message.match(/issue token failed error=(\d+) http_status=(\d+)/i);
219
+ if (!matched) {
220
+ return {};
221
+ }
222
+ const errorCode = Number.parseInt(matched[1] ?? '', 10);
223
+ const httpStatus = Number.parseInt(matched[2] ?? '', 10);
224
+ return {
225
+ errorCode: Number.isNaN(errorCode) ? undefined : errorCode,
226
+ httpStatus: Number.isNaN(httpStatus) ? undefined : httpStatus,
227
+ };
228
+ }
229
+ function isNodeStackNoise(line) {
230
+ return line.startsWith('[eval]:') ||
231
+ line.startsWith('at [eval]') ||
232
+ line.startsWith('at runScriptInThisContext') ||
233
+ line.startsWith('at node:internal/') ||
234
+ line.startsWith('Node.js v');
235
+ }
236
+ function sanitizeIssueTokenFailureText(message) {
237
+ const lines = message
238
+ .split(/\r?\n/)
239
+ .map((line) => line.trim())
240
+ .filter((line) => line.length > 0 && !isNodeStackNoise(line));
241
+ const collapsed = lines.join(' | ');
242
+ if (collapsed.length === 0) {
243
+ return 'token issuing failed';
244
+ }
245
+ return collapsed;
246
+ }
247
+ function formatIssueTokenFailureMessage(message) {
248
+ const parsed = parseIssueTokenFailure(message);
249
+ const detail = sanitizeIssueTokenFailureText(message);
250
+ if (parsed.httpStatus === 200 && parsed.errorCode === 3) {
251
+ return [
252
+ 'token issuing failed: remote service rejected the request.',
253
+ 'Check whether remote_id, access_key_id, secret_key_id, and openapi-endpoint are correct.',
254
+ 'detail: error=3 http_status=200',
255
+ ].join(' ');
256
+ }
257
+ if (parsed.httpStatus !== undefined || parsed.errorCode !== undefined) {
258
+ const detailParts = [];
259
+ if (parsed.errorCode !== undefined) {
260
+ detailParts.push('error=' + parsed.errorCode);
261
+ }
262
+ if (parsed.httpStatus !== undefined) {
263
+ detailParts.push('http_status=' + parsed.httpStatus);
264
+ }
265
+ return [
266
+ 'token issuing failed: remote authentication request was not accepted.',
267
+ 'Check whether remote_id, access_key_id, secret_key_id, and openapi-endpoint are correct.',
268
+ 'detail: ' + detailParts.join(' '),
269
+ ].join(' ');
270
+ }
271
+ return 'token issuing failed: ' + detail;
272
+ }
223
273
  function issueTokenViaSubprocess(addonPath, input) {
224
274
  const result = childProcess.spawnSync(process.execPath, ['-e', buildIssueTokenHelperSource()], {
225
275
  encoding: 'utf8',
@@ -235,7 +285,7 @@ function issueTokenViaSubprocess(addonPath, input) {
235
285
  }
236
286
  if (result.status !== 0) {
237
287
  const details = String(result.stderr || result.stdout || 'issue token subprocess failed').trim();
238
- throw new Error(details || 'issue token subprocess failed');
288
+ throw new Error(formatIssueTokenFailureMessage(details || 'issue token subprocess failed'));
239
289
  }
240
290
  return normalizeIssuedToken(String(result.stdout || ''));
241
291
  }
@@ -301,28 +351,34 @@ async function issueToken(input) {
301
351
  }
302
352
  catch (error) {
303
353
  const message = error instanceof Error ? error.message : String(error);
304
- throw new Error('issue token failed: ' + message);
354
+ throw new Error(message);
305
355
  }
306
356
  }
307
357
  function buildIssuedTokenPayload(input, token) {
308
- return {
309
- version: 1,
310
- type: 'tirtc-connect-token',
311
- peer_id: input.peerId,
312
- local_id: input.localId,
313
- service_entry: input.serviceEntry ?? '',
358
+ const payload = {
359
+ app_id: input.appId.trim(),
360
+ remote_id: input.remoteId,
314
361
  token,
315
- openapi_entry: input.openapiEntry?.trim() || kDefaultOpenapiEntry,
316
- user_ttl_seconds: input.userTtlSeconds ?? kDefaultUserTtlSeconds,
317
- channel_ttl_seconds: input.channelTtlSeconds ?? kDefaultChannelTtlSeconds,
318
- generated_at: new Date().toISOString(),
319
362
  };
363
+ const normalizedEndpoint = input.endpoint?.trim();
364
+ if (normalizedEndpoint) {
365
+ payload.endpoint = normalizedEndpoint;
366
+ }
367
+ const normalizedOpenapiEndpoint = input.openapiEndpoint?.trim();
368
+ if (normalizedOpenapiEndpoint) {
369
+ payload.openapi_endpoint = normalizedOpenapiEndpoint;
370
+ }
371
+ return payload;
320
372
  }
321
373
  function buildLicenseQrcodePayload(input) {
322
- return {
374
+ const payload = {
323
375
  license: input.license.trim(),
324
- service_entry: input.serviceEntry?.trim() ?? '',
325
376
  };
377
+ const normalizedEndpoint = input.endpoint?.trim();
378
+ if (normalizedEndpoint) {
379
+ payload.endpoint = normalizedEndpoint;
380
+ }
381
+ return payload;
326
382
  }
327
383
  async function writePngQrcode(payloadJson, outputPath, errorCorrectionLevel) {
328
384
  const resolvedPath = path_1.default.resolve(outputPath);
@@ -382,13 +438,10 @@ async function buildLicenseQrcode(input) {
382
438
  function formatTokenIssueConsoleOutput(output) {
383
439
  const summaryLines = [
384
440
  'Issued Token Summary:',
385
- ' local_id: ' + output.payload.local_id,
386
- ' peer_id: ' + output.payload.peer_id,
387
- ' service_entry: ' + (output.payload.service_entry || '(empty)'),
388
- ' openapi_entry: ' + output.payload.openapi_entry,
389
- ' user_ttl_seconds: ' + output.payload.user_ttl_seconds,
390
- ' channel_ttl_seconds: ' + output.payload.channel_ttl_seconds,
391
- ' generated_at: ' + output.payload.generated_at,
441
+ ' app_id: ' + output.payload.app_id,
442
+ ' remote_id: ' + output.payload.remote_id,
443
+ ' endpoint: ' + (output.payload.endpoint ?? '(omitted)'),
444
+ ' openapi_endpoint: ' + (output.payload.openapi_endpoint ?? '(omitted)'),
392
445
  '',
393
446
  'Token:',
394
447
  output.token,
@@ -408,7 +461,7 @@ function formatLicenseQrcodeConsoleOutput(output) {
408
461
  const summaryLines = [
409
462
  'License QR Code Summary:',
410
463
  ' license: ' + output.payload.license,
411
- ' service_entry: ' + (output.payload.service_entry || '(empty)'),
464
+ ' endpoint: ' + (output.payload.endpoint ?? '(omitted)'),
412
465
  '',
413
466
  'Payload JSON:',
414
467
  JSON.stringify(output.payload, null, 2),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirtc-devtools-cli",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "private": false,
5
5
  "main": "dist/cli/src/index.js",
6
6
  "types": "dist/cli/src/index.d.ts",
@@ -7,25 +7,44 @@ extern "C" {
7
7
 
8
8
  typedef enum TirtcError {
9
9
  TIRTC_ERROR_OK = 0,
10
- TIRTC_ERROR_INVALID_ARGUMENT = 1,
11
- TIRTC_ERROR_NOT_INITIALIZED = 2,
12
- TIRTC_ERROR_INTERNAL = 3,
13
- TIRTC_ERROR_NOT_READY = 4,
14
- TIRTC_ERROR_UNSUPPORTED_LOOP_POLICY = 5,
15
- TIRTC_ERROR_SOURCE_HASH_MISMATCH = 6,
16
- TIRTC_ERROR_STOPPED = 7,
17
- TIRTC_ERROR_DESTROYED = 8,
18
- TIRTC_ERROR_TRANSPORT_INVALID_LICENSE = 9,
19
- TIRTC_ERROR_TRANSPORT_TIMEOUT = 10,
20
- TIRTC_ERROR_TRANSPORT_BUSY = 11,
21
- TIRTC_ERROR_TRANSPORT_CONNECTION_TIMEOUT_CLOSED = 12,
22
- TIRTC_ERROR_TRANSPORT_REMOTE_CLOSED = 13,
23
- TIRTC_ERROR_TRANSPORT_CONNECTION_OTHER_ERROR = 14,
24
- TIRTC_ERROR_TRANSPORT_TOKEN_EXPIRED = 15,
25
- TIRTC_ERROR_DUMP_ROOT_UNAVAILABLE = 16,
26
- TIRTC_ERROR_DUMP_ALREADY_ACTIVE = 17,
10
+ TIRTC_ERROR_INVALID_ARGUMENT = 6000,
11
+ TIRTC_ERROR_NOT_INITIALIZED = 6001,
12
+ TIRTC_ERROR_INTERNAL = 6002,
13
+ TIRTC_ERROR_NOT_READY = 6003,
14
+ TIRTC_ERROR_UNSUPPORTED_LOOP_POLICY = 6004,
15
+ TIRTC_ERROR_SOURCE_HASH_MISMATCH = 6005,
16
+ TIRTC_ERROR_ALREADY_STOPPED = 6006,
17
+ TIRTC_ERROR_STOPPED = TIRTC_ERROR_ALREADY_STOPPED,
18
+ TIRTC_ERROR_ALREADY_DESTROYED = 6007,
19
+ TIRTC_ERROR_DESTROYED = TIRTC_ERROR_ALREADY_DESTROYED,
20
+ TIRTC_ERROR_TRANSPORT_INVALID_LICENSE = 6008,
21
+ TIRTC_ERROR_TRANSPORT_TIMEOUT = 6009,
22
+ TIRTC_ERROR_TRANSPORT_BUSY = 6010,
23
+ TIRTC_ERROR_TRANSPORT_CONNECTION_TIMEOUT_CLOSED = 6011,
24
+ TIRTC_ERROR_TRANSPORT_REMOTE_CLOSED = 6012,
25
+ TIRTC_ERROR_TRANSPORT_CONNECTION_OTHER_ERROR = 6013,
26
+ TIRTC_ERROR_TRANSPORT_TOKEN_EXPIRED = 6014,
27
+ TIRTC_ERROR_DUMP_ROOT_UNAVAILABLE = 6015,
28
+ TIRTC_ERROR_DUMP_ALREADY_ACTIVE = 6016,
29
+ TIRTC_ERROR_TRANSPORT_RESOURCE_EXHAUSTED = 6017,
30
+ TIRTC_ERROR_TRANSPORT_SERVER_ERROR = 6018,
31
+ TIRTC_ERROR_TRANSPORT_BACKEND_INTERNAL_ERROR = 6019,
32
+ TIRTC_ERROR_TRANSPORT_NO_SECRET_KEY = 6020,
33
+ TIRTC_ERROR_TRANSPORT_UNEXPECTED_RESPONSE = 6021,
34
+ TIRTC_ERROR_ALREADY_INITIALIZED = 6022,
35
+ TIRTC_ERROR_INVALID_THREAD = 6023,
36
+ TIRTC_ERROR_PERMISSION_DENIED = 6024,
37
+ TIRTC_ERROR_ALREADY_BOUND = 6025,
38
+ TIRTC_ERROR_IN_USE = 6026,
39
+ TIRTC_ERROR_NOT_STARTED = 6027,
40
+ TIRTC_ERROR_NOT_CONNECTED = 6028,
41
+ TIRTC_ERROR_NOT_BOUND = 6029,
42
+ TIRTC_ERROR_NOT_CONFIGURED = 6030,
43
+ TIRTC_ERROR_NOT_OPEN = 6031,
27
44
  } TirtcError;
28
45
 
46
+ const char* tirtc_error_to_string(TirtcError error);
47
+
29
48
  #ifdef __cplusplus
30
49
  }
31
50
  #endif