polyv-live-cli 1.2.12 → 1.2.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.
Files changed (144) hide show
  1. package/dist/commands/chat.commands.d.ts +5 -0
  2. package/dist/commands/chat.commands.d.ts.map +1 -0
  3. package/dist/commands/chat.commands.js +203 -0
  4. package/dist/commands/chat.commands.js.map +1 -0
  5. package/dist/commands/document.commands.d.ts +6 -0
  6. package/dist/commands/document.commands.d.ts.map +1 -0
  7. package/dist/commands/document.commands.js +391 -0
  8. package/dist/commands/document.commands.js.map +1 -0
  9. package/dist/commands/playback.commands.d.ts +5 -0
  10. package/dist/commands/playback.commands.d.ts.map +1 -0
  11. package/dist/commands/playback.commands.js +406 -0
  12. package/dist/commands/playback.commands.js.map +1 -0
  13. package/dist/commands/player.commands.d.ts +7 -0
  14. package/dist/commands/player.commands.d.ts.map +1 -0
  15. package/dist/commands/player.commands.js +240 -0
  16. package/dist/commands/player.commands.js.map +1 -0
  17. package/dist/commands/product.commands.d.ts.map +1 -1
  18. package/dist/commands/product.commands.js +24 -13
  19. package/dist/commands/product.commands.js.map +1 -1
  20. package/dist/commands/record.commands.d.ts +8 -0
  21. package/dist/commands/record.commands.d.ts.map +1 -0
  22. package/dist/commands/record.commands.js +359 -0
  23. package/dist/commands/record.commands.js.map +1 -0
  24. package/dist/commands/session.commands.d.ts +4 -0
  25. package/dist/commands/session.commands.d.ts.map +1 -0
  26. package/dist/commands/session.commands.js +238 -0
  27. package/dist/commands/session.commands.js.map +1 -0
  28. package/dist/commands/statistics.commands.d.ts +6 -0
  29. package/dist/commands/statistics.commands.d.ts.map +1 -0
  30. package/dist/commands/statistics.commands.export.d.ts +7 -0
  31. package/dist/commands/statistics.commands.export.d.ts.map +1 -0
  32. package/dist/commands/statistics.commands.export.js +232 -0
  33. package/dist/commands/statistics.commands.export.js.map +1 -0
  34. package/dist/commands/statistics.commands.js +401 -0
  35. package/dist/commands/statistics.commands.js.map +1 -0
  36. package/dist/handlers/chat.handler.d.ts +19 -0
  37. package/dist/handlers/chat.handler.d.ts.map +1 -0
  38. package/dist/handlers/chat.handler.js +170 -0
  39. package/dist/handlers/chat.handler.js.map +1 -0
  40. package/dist/handlers/document.handler.d.ts +51 -0
  41. package/dist/handlers/document.handler.d.ts.map +1 -0
  42. package/dist/handlers/document.handler.js +221 -0
  43. package/dist/handlers/document.handler.js.map +1 -0
  44. package/dist/handlers/playback.handler.d.ts +43 -0
  45. package/dist/handlers/playback.handler.d.ts.map +1 -0
  46. package/dist/handlers/playback.handler.js +260 -0
  47. package/dist/handlers/playback.handler.js.map +1 -0
  48. package/dist/handlers/player.handler.d.ts +21 -0
  49. package/dist/handlers/player.handler.d.ts.map +1 -0
  50. package/dist/handlers/player.handler.js +84 -0
  51. package/dist/handlers/player.handler.js.map +1 -0
  52. package/dist/handlers/product.handler.d.ts +1 -0
  53. package/dist/handlers/product.handler.d.ts.map +1 -1
  54. package/dist/handlers/product.handler.js +34 -17
  55. package/dist/handlers/product.handler.js.map +1 -1
  56. package/dist/handlers/record.handler.d.ts +24 -0
  57. package/dist/handlers/record.handler.d.ts.map +1 -0
  58. package/dist/handlers/record.handler.js +202 -0
  59. package/dist/handlers/record.handler.js.map +1 -0
  60. package/dist/handlers/session.handler.d.ts +27 -0
  61. package/dist/handlers/session.handler.d.ts.map +1 -0
  62. package/dist/handlers/session.handler.js +135 -0
  63. package/dist/handlers/session.handler.js.map +1 -0
  64. package/dist/handlers/statistics.handler.d.ts +37 -0
  65. package/dist/handlers/statistics.handler.d.ts.map +1 -0
  66. package/dist/handlers/statistics.handler.js +302 -0
  67. package/dist/handlers/statistics.handler.js.map +1 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +22 -5
  70. package/dist/index.js.map +1 -1
  71. package/dist/services/chat.service.sdk.d.ts +15 -0
  72. package/dist/services/chat.service.sdk.d.ts.map +1 -0
  73. package/dist/services/chat.service.sdk.js +110 -0
  74. package/dist/services/chat.service.sdk.js.map +1 -0
  75. package/dist/services/document.service.sdk.d.ts +27 -0
  76. package/dist/services/document.service.sdk.d.ts.map +1 -0
  77. package/dist/services/document.service.sdk.js +151 -0
  78. package/dist/services/document.service.sdk.js.map +1 -0
  79. package/dist/services/playback.service.sdk.d.ts +31 -0
  80. package/dist/services/playback.service.sdk.d.ts.map +1 -0
  81. package/dist/services/playback.service.sdk.js +165 -0
  82. package/dist/services/playback.service.sdk.js.map +1 -0
  83. package/dist/services/player.service.sdk.d.ts +15 -0
  84. package/dist/services/player.service.sdk.d.ts.map +1 -0
  85. package/dist/services/player.service.sdk.js +110 -0
  86. package/dist/services/player.service.sdk.js.map +1 -0
  87. package/dist/services/product.service.sdk.d.ts.map +1 -1
  88. package/dist/services/product.service.sdk.js +39 -21
  89. package/dist/services/product.service.sdk.js.map +1 -1
  90. package/dist/services/record.service.sdk.d.ts +13 -0
  91. package/dist/services/record.service.sdk.d.ts.map +1 -0
  92. package/dist/services/record.service.sdk.js +132 -0
  93. package/dist/services/record.service.sdk.js.map +1 -0
  94. package/dist/services/session.service.sdk.d.ts +19 -0
  95. package/dist/services/session.service.sdk.d.ts.map +1 -0
  96. package/dist/services/session.service.sdk.js +105 -0
  97. package/dist/services/session.service.sdk.js.map +1 -0
  98. package/dist/services/statistics.service.sdk.d.ts +23 -0
  99. package/dist/services/statistics.service.sdk.d.ts.map +1 -0
  100. package/dist/services/statistics.service.sdk.js +284 -0
  101. package/dist/services/statistics.service.sdk.js.map +1 -0
  102. package/dist/types/chat.d.ts +35 -0
  103. package/dist/types/chat.d.ts.map +1 -0
  104. package/dist/types/chat.js +3 -0
  105. package/dist/types/chat.js.map +1 -0
  106. package/dist/types/document.d.ts +115 -0
  107. package/dist/types/document.d.ts.map +1 -0
  108. package/dist/types/document.js +12 -0
  109. package/dist/types/document.js.map +1 -0
  110. package/dist/types/index.d.ts +2 -0
  111. package/dist/types/index.d.ts.map +1 -1
  112. package/dist/types/index.js +2 -0
  113. package/dist/types/index.js.map +1 -1
  114. package/dist/types/playback.d.ts +107 -0
  115. package/dist/types/playback.d.ts.map +1 -0
  116. package/dist/types/playback.js +10 -0
  117. package/dist/types/playback.js.map +1 -0
  118. package/dist/types/player.d.ts +34 -0
  119. package/dist/types/player.d.ts.map +1 -0
  120. package/dist/types/player.js +3 -0
  121. package/dist/types/player.js.map +1 -0
  122. package/dist/types/product.d.ts +1 -0
  123. package/dist/types/product.d.ts.map +1 -1
  124. package/dist/types/record.d.ts +76 -0
  125. package/dist/types/record.d.ts.map +1 -0
  126. package/dist/types/record.js +3 -0
  127. package/dist/types/record.js.map +1 -0
  128. package/dist/types/session.d.ts +78 -0
  129. package/dist/types/session.d.ts.map +1 -0
  130. package/dist/types/session.js +8 -0
  131. package/dist/types/session.js.map +1 -0
  132. package/dist/types/statistics-export.d.ts +42 -0
  133. package/dist/types/statistics-export.d.ts.map +1 -0
  134. package/dist/types/statistics-export.js +8 -0
  135. package/dist/types/statistics-export.js.map +1 -0
  136. package/dist/types/statistics.d.ts +72 -0
  137. package/dist/types/statistics.d.ts.map +1 -0
  138. package/dist/types/statistics.js +3 -0
  139. package/dist/types/statistics.js.map +1 -0
  140. package/dist/utils/date-validation.d.ts +22 -0
  141. package/dist/utils/date-validation.d.ts.map +1 -0
  142. package/dist/utils/date-validation.js +118 -0
  143. package/dist/utils/date-validation.js.map +1 -0
  144. package/package.json +3 -3
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOutputFormat = validateOutputFormat;
4
+ exports.validateDateTimeFormat = validateDateTimeFormat;
5
+ exports.validateWatchType = validateWatchType;
6
+ exports.validateSameMonth = validateSameMonth;
7
+ exports.registerStatisticsExportCommands = registerStatisticsExportCommands;
8
+ const statistics_handler_1 = require("../handlers/statistics.handler");
9
+ const manager_1 = require("../config/manager");
10
+ const auth_adapter_1 = require("../config/auth-adapter");
11
+ const errors_1 = require("../utils/errors");
12
+ async function loadAuthAndServiceConfig(parentOptions) {
13
+ const authResult = auth_adapter_1.authAdapter.tryGetAuthConfig(parentOptions);
14
+ if (!authResult) {
15
+ throw new Error(auth_adapter_1.authAdapter.getStatusMessage(parentOptions));
16
+ }
17
+ let configResult;
18
+ try {
19
+ configResult = await manager_1.configManager.load({
20
+ cliOptions: parentOptions,
21
+ });
22
+ }
23
+ catch (error) {
24
+ if (error instanceof Error && error.message.includes('Auth configuration is incomplete')) {
25
+ configResult = {
26
+ config: {
27
+ baseUrl: 'https://api.polyv.net',
28
+ timeout: 30000,
29
+ debug: false
30
+ }
31
+ };
32
+ }
33
+ else {
34
+ throw error;
35
+ }
36
+ }
37
+ const serviceConfig = {
38
+ baseUrl: configResult.config.baseUrl,
39
+ timeout: configResult.config.timeout,
40
+ debug: configResult.config.debug
41
+ };
42
+ const isVerbose = !!parentOptions.verbose;
43
+ if (isVerbose) {
44
+ console.log(`Authentication Source: ${authResult.source}`);
45
+ if (authResult.accountName) {
46
+ console.log(`Account: ${authResult.accountName}`);
47
+ }
48
+ console.log('');
49
+ }
50
+ const result = {
51
+ authConfig: authResult.config,
52
+ serviceConfig,
53
+ isVerbose,
54
+ };
55
+ if (authResult.source) {
56
+ result.authSource = authResult.source;
57
+ }
58
+ if (authResult.accountName) {
59
+ result.accountName = authResult.accountName;
60
+ }
61
+ return result;
62
+ }
63
+ function validateOutputFormat(value) {
64
+ if (!['table', 'json'].includes(value)) {
65
+ throw new Error('Output format must be either "table" or "json"');
66
+ }
67
+ return value;
68
+ }
69
+ function validateDateTimeFormat(value) {
70
+ const regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
71
+ if (!regex.test(value)) {
72
+ throw new Error('DateTime format must be yyyy-MM-dd HH:mm:ss');
73
+ }
74
+ const date = new Date(value);
75
+ if (isNaN(date.getTime())) {
76
+ throw new Error(`Invalid datetime: ${value}`);
77
+ }
78
+ return value;
79
+ }
80
+ function validateWatchType(value) {
81
+ if (!['live', 'vod'].includes(value)) {
82
+ throw new Error('watchType must be either "live" or "vod"');
83
+ }
84
+ return value;
85
+ }
86
+ function validateSameMonth(startDate, endDate) {
87
+ const startMonth = startDate.substring(0, 7);
88
+ const endMonth = endDate.substring(0, 7);
89
+ if (startMonth !== endMonth) {
90
+ throw new Error('startDate and endDate must be in the same month');
91
+ }
92
+ }
93
+ function registerStatisticsExportCommands(program) {
94
+ const statisticsCmd = program.commands.find((cmd) => cmd.name() === 'statistics');
95
+ if (!statisticsCmd) {
96
+ return;
97
+ }
98
+ const exportCmd = statisticsCmd.command('export');
99
+ exportCmd.description('export statistics data');
100
+ const viewlogCmd = exportCmd
101
+ .command('viewlog')
102
+ .description('Export channel viewlog (观看日志) data')
103
+ .requiredOption('-c, --channel-id <channelId>', 'Channel ID')
104
+ .requiredOption('--start-time <datetime>', 'Start time (yyyy-MM-dd HH:mm:ss)', validateDateTimeFormat)
105
+ .requiredOption('--end-time <datetime>', 'End time (yyyy-MM-dd HH:mm:ss)', validateDateTimeFormat)
106
+ .option('--watch-type <type>', 'Watch type filter (live or vod)', validateWatchType)
107
+ .option('-o, --output <format>', 'Output format (table or json)', validateOutputFormat, 'table')
108
+ .option('--output-file <path>', 'Output CSV file path for export')
109
+ .action(async (options) => {
110
+ try {
111
+ validateSameMonth(options.startTime, options.endTime);
112
+ const parentOptions = program.opts();
113
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
114
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
115
+ const viewlogOptions = {
116
+ channelId: options.channelId,
117
+ startTime: options.startTime,
118
+ endTime: options.endTime,
119
+ output: options.output,
120
+ };
121
+ if (options.watchType) {
122
+ viewlogOptions.watchType = options.watchType;
123
+ }
124
+ if (options.outputFile) {
125
+ viewlogOptions.outputFile = options.outputFile;
126
+ }
127
+ await statisticsHandler.exportViewlog(viewlogOptions);
128
+ }
129
+ catch (error) {
130
+ if (error instanceof Error && error.message.includes('Authentication')) {
131
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
132
+ console.error('\nAuthentication Diagnostics:');
133
+ diagnostics.availableSources.forEach(source => {
134
+ const status = source.appId && source.appSecret ? 'OK' : 'X';
135
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
136
+ });
137
+ if (diagnostics.errors.length > 0) {
138
+ console.error('\nErrors:');
139
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
140
+ }
141
+ }
142
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
143
+ process.exit(1);
144
+ }
145
+ });
146
+ viewlogCmd.addHelpText('after', `
147
+ Examples:
148
+ # Export viewlog data for a channel
149
+ $ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59"
150
+
151
+ # Export with watch type filter
152
+ $ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --watch-type live
153
+
154
+ # Export to CSV file
155
+ $ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --output-file ./viewlog.csv
156
+
157
+ # Output in JSON format
158
+ $ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --output json
159
+
160
+ DateTime Format:
161
+ --start-time Start time in yyyy-MM-dd HH:mm:ss format (required)
162
+ --end-time End time in yyyy-MM-dd HH:mm:ss format (required)
163
+ Note: Start and end time must be in the same month
164
+
165
+ Watch Types:
166
+ live Live streaming
167
+ vod Video on demand (playback)
168
+
169
+ Output Formats:
170
+ table Formatted table output (default)
171
+ json JSON format for programmatic use
172
+
173
+ Output Options:
174
+ --output-file Path to save CSV file with Chinese headers
175
+ `);
176
+ const sessionCmd = exportCmd
177
+ .command('session')
178
+ .description('Export channel session statistics report - 场次报表 (returns download link)')
179
+ .requiredOption('-c, --channel-id <channelId>', 'Channel ID')
180
+ .requiredOption('--session-id <sessionId>', 'Session ID')
181
+ .option('-o, --output <format>', 'Output format (table or json)', validateOutputFormat, 'table')
182
+ .action(async (options) => {
183
+ try {
184
+ const parentOptions = program.opts();
185
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
186
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
187
+ const sessionOptions = {
188
+ channelId: options.channelId,
189
+ sessionId: options.sessionId,
190
+ output: options.output,
191
+ };
192
+ await statisticsHandler.exportSessionStats(sessionOptions);
193
+ }
194
+ catch (error) {
195
+ if (error instanceof Error && error.message.includes('Authentication')) {
196
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
197
+ console.error('\nAuthentication Diagnostics:');
198
+ diagnostics.availableSources.forEach(source => {
199
+ const status = source.appId && source.appSecret ? '[OK]' : '[FAIL]';
200
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
201
+ });
202
+ if (diagnostics.errors.length > 0) {
203
+ console.error('\nErrors:');
204
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
205
+ }
206
+ }
207
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
208
+ process.exit(1);
209
+ }
210
+ });
211
+ sessionCmd.addHelpText('after', `
212
+ Examples:
213
+ # Export session statistics report
214
+ $ polyv-live-cli statistics export session -c "3151318" --session-id "fv3ma84e63"
215
+
216
+ # Output in JSON format
217
+ $ polyv-live-cli statistics export session -c "3151318" --session-id "fv3ma84e63" --output json
218
+
219
+ Parameters:
220
+ --channel-id Channel ID (required)
221
+ --session-id Session ID (required)
222
+
223
+ Output Formats:
224
+ table Formatted table output (default)
225
+ json JSON format for programmatic use
226
+
227
+ Notes:
228
+ - Returns a download URL for the session report
229
+ - Download link is valid for 60 days
230
+ `);
231
+ }
232
+ //# sourceMappingURL=statistics.commands.export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistics.commands.export.js","sourceRoot":"","sources":["../../src/commands/statistics.commands.export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOutputFormat = validateOutputFormat;
4
+ exports.validateDateFormat = validateDateFormat;
5
+ exports.validateDateRange = validateDateRange;
6
+ exports.registerStatisticsCommands = registerStatisticsCommands;
7
+ const statistics_handler_1 = require("../handlers/statistics.handler");
8
+ const manager_1 = require("../config/manager");
9
+ const auth_adapter_1 = require("../config/auth-adapter");
10
+ const errors_1 = require("../utils/errors");
11
+ const date_validation_1 = require("../utils/date-validation");
12
+ async function loadAuthAndServiceConfig(parentOptions) {
13
+ const authResult = auth_adapter_1.authAdapter.tryGetAuthConfig(parentOptions);
14
+ if (!authResult) {
15
+ throw new Error(auth_adapter_1.authAdapter.getStatusMessage(parentOptions));
16
+ }
17
+ let configResult;
18
+ try {
19
+ configResult = await manager_1.configManager.load({
20
+ cliOptions: parentOptions,
21
+ });
22
+ }
23
+ catch (error) {
24
+ if (error instanceof Error && error.message.includes('Auth configuration is incomplete')) {
25
+ configResult = {
26
+ config: {
27
+ baseUrl: 'https://api.polyv.net',
28
+ timeout: 30000,
29
+ debug: false
30
+ }
31
+ };
32
+ }
33
+ else {
34
+ throw error;
35
+ }
36
+ }
37
+ const serviceConfig = {
38
+ baseUrl: configResult.config.baseUrl,
39
+ timeout: configResult.config.timeout,
40
+ debug: configResult.config.debug
41
+ };
42
+ const isVerbose = !!parentOptions.verbose;
43
+ if (isVerbose) {
44
+ console.log(`🔐 Authentication Source: ${authResult.source}`);
45
+ if (authResult.accountName) {
46
+ console.log(`👤 Account: ${authResult.accountName}`);
47
+ }
48
+ console.log('');
49
+ }
50
+ const result = {
51
+ authConfig: authResult.config,
52
+ serviceConfig,
53
+ isVerbose,
54
+ };
55
+ if (authResult.source) {
56
+ result.authSource = authResult.source;
57
+ }
58
+ if (authResult.accountName) {
59
+ result.accountName = authResult.accountName;
60
+ }
61
+ return result;
62
+ }
63
+ function validateOutputFormat(value) {
64
+ if (!['table', 'json'].includes(value)) {
65
+ throw new Error('Output format must be either "table" or "json"');
66
+ }
67
+ return value;
68
+ }
69
+ function validateDateFormat(value) {
70
+ const regex = /^\d{4}-\d{2}-\d{2}$/;
71
+ if (!regex.test(value)) {
72
+ throw new Error('Date format must be yyyy-MM-dd');
73
+ }
74
+ const date = new Date(value);
75
+ if (isNaN(date.getTime())) {
76
+ throw new Error(`Invalid date: ${value}`);
77
+ }
78
+ const [year, month, day] = value.split('-').map(Number);
79
+ if (date.getFullYear() !== year ||
80
+ date.getMonth() + 1 !== month ||
81
+ date.getDate() !== day) {
82
+ throw new Error(`Invalid date: ${value}`);
83
+ }
84
+ return value;
85
+ }
86
+ function validateDateRange(startDay, endDay) {
87
+ const result = (0, date_validation_1.validateDateRange)(startDay, endDay);
88
+ if (!result.valid) {
89
+ throw new Error(result.error || 'Invalid date range');
90
+ }
91
+ }
92
+ function registerStatisticsCommands(program) {
93
+ const statisticsCmd = program.command('statistics');
94
+ statisticsCmd.description('View live streaming statistics data');
95
+ const viewCmd = statisticsCmd
96
+ .command('view')
97
+ .description('View daily statistics for a channel')
98
+ .requiredOption('-c, --channel-id <channelId>', 'channel ID')
99
+ .requiredOption('--start-day <date>', 'start date (yyyy-MM-dd)', validateDateFormat)
100
+ .requiredOption('--end-day <date>', 'end date (yyyy-MM-dd)', validateDateFormat)
101
+ .option('-o, --output <format>', 'output format (table|json)', validateOutputFormat, 'table')
102
+ .action(async (options) => {
103
+ try {
104
+ validateDateRange(options.startDay, options.endDay);
105
+ const parentOptions = program.opts();
106
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
107
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
108
+ const viewOptions = {
109
+ channelId: options.channelId,
110
+ startDay: options.startDay,
111
+ endDay: options.endDay,
112
+ output: options.output
113
+ };
114
+ await statisticsHandler.viewStatistics(viewOptions);
115
+ }
116
+ catch (error) {
117
+ if (error instanceof Error && error.message.includes('Authentication')) {
118
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
119
+ console.error('\n🔍 Authentication Diagnostics:');
120
+ diagnostics.availableSources.forEach(source => {
121
+ const status = source.appId && source.appSecret ? '✅' : '❌';
122
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
123
+ });
124
+ if (diagnostics.errors.length > 0) {
125
+ console.error('\n❌ Errors:');
126
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
127
+ }
128
+ }
129
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
130
+ process.exit(1);
131
+ }
132
+ });
133
+ viewCmd.addHelpText('after', `
134
+ Examples:
135
+ # View daily statistics for a channel
136
+ $ polyv-live-cli statistics view -c "3151318" --start-day "2024-01-01" --end-day "2024-01-31"
137
+
138
+ # Output in JSON format
139
+ $ polyv-live-cli statistics view -c "3151318" --start-day "2024-01-01" --end-day "2024-01-31" -o json
140
+
141
+ # With full parameter names
142
+ $ polyv-live-cli statistics view --channel-id "3151318" --start-day "2024-01-01" --end-day "2024-01-31" --output table
143
+
144
+ Date Range:
145
+ --start-day Start date in yyyy-MM-dd format (required)
146
+ --end-day End date in yyyy-MM-dd format (required)
147
+ Note: Date range cannot exceed 60 days
148
+
149
+ Output Formats:
150
+ table Formatted table output (default)
151
+ json JSON format for programmatic use
152
+
153
+ Notes:
154
+ - Channel ID is required for all statistics queries
155
+ - Date range cannot exceed 60 days
156
+ - Statistics include PC and mobile view data
157
+ `);
158
+ const concurrencyCmd = statisticsCmd
159
+ .command('concurrency')
160
+ .description('查看历史并发数据')
161
+ .requiredOption('-c, --channel-id <channelId>', '频道ID')
162
+ .requiredOption('--start-date <date>', '开始日期 (yyyy-MM-dd)', validateDateFormat)
163
+ .requiredOption('--end-date <date>', '结束日期 (yyyy-MM-dd)', validateDateFormat)
164
+ .option('-o, --output <format>', '输出格式 (table|json)', validateOutputFormat, 'table')
165
+ .action(async (options) => {
166
+ try {
167
+ validateDateRange(options.startDate, options.endDate);
168
+ const parentOptions = program.opts();
169
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
170
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
171
+ const concurrencyOptions = {
172
+ channelId: options.channelId,
173
+ startDate: options.startDate,
174
+ endDate: options.endDate,
175
+ output: options.output
176
+ };
177
+ await statisticsHandler.viewConcurrency(concurrencyOptions);
178
+ }
179
+ catch (error) {
180
+ if (error instanceof Error && error.message.includes('Authentication')) {
181
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
182
+ console.error('\n🔍 Authentication Diagnostics:');
183
+ diagnostics.availableSources.forEach(source => {
184
+ const status = source.appId && source.appSecret ? '✅' : '❌';
185
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
186
+ });
187
+ if (diagnostics.errors.length > 0) {
188
+ console.error('\n❌ Errors:');
189
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
190
+ }
191
+ }
192
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
193
+ process.exit(1);
194
+ }
195
+ });
196
+ concurrencyCmd.addHelpText('after', `
197
+ Examples:
198
+ # View historical concurrency data
199
+ $ polyv-live-cli statistics concurrency -c "3151318" --start-date "2024-01-01" --end-date "2024-01-31"
200
+
201
+ # Output in JSON format
202
+ $ polyv-live-cli statistics concurrency -c "3151318" --start-date "2024-01-01" --end-date "2024-01-31" -o json
203
+
204
+ Date Range:
205
+ --start-date Start date in yyyy-MM-dd format (required)
206
+ --end-date End date in yyyy-MM-dd format (required)
207
+ Note: Date range cannot exceed 60 days
208
+
209
+ Output Formats:
210
+ table Formatted table output (default)
211
+ json JSON format for programmatic use
212
+ `);
213
+ const maxConcurrentCmd = statisticsCmd
214
+ .command('max-concurrent')
215
+ .description('查看历史最高并发人数')
216
+ .requiredOption('-c, --channel-id <channelId>', '频道ID')
217
+ .requiredOption('--start-time <timestamp>', '开始时间戳 (13位毫秒)', parseInt)
218
+ .requiredOption('--end-time <timestamp>', '结束时间戳 (13位毫秒)', parseInt)
219
+ .option('-o, --output <format>', '输出格式 (table|json)', validateOutputFormat, 'table')
220
+ .action(async (options) => {
221
+ try {
222
+ const rangeValidation = (0, date_validation_1.validateTimestampRange)(options.startTime, options.endTime);
223
+ if (!rangeValidation.valid) {
224
+ throw new Error(rangeValidation.error || 'Invalid time range');
225
+ }
226
+ const parentOptions = program.opts();
227
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
228
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
229
+ const maxConcurrentOptions = {
230
+ channelId: options.channelId,
231
+ startTime: options.startTime,
232
+ endTime: options.endTime,
233
+ output: options.output
234
+ };
235
+ await statisticsHandler.viewMaxConcurrent(maxConcurrentOptions);
236
+ }
237
+ catch (error) {
238
+ if (error instanceof Error && error.message.includes('Authentication')) {
239
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
240
+ console.error('\n🔍 Authentication Diagnostics:');
241
+ diagnostics.availableSources.forEach(source => {
242
+ const status = source.appId && source.appSecret ? '✅' : '❌';
243
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
244
+ });
245
+ if (diagnostics.errors.length > 0) {
246
+ console.error('\n❌ Errors:');
247
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
248
+ }
249
+ }
250
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
251
+ process.exit(1);
252
+ }
253
+ });
254
+ maxConcurrentCmd.addHelpText('after', `
255
+ Examples:
256
+ # View maximum historical concurrent viewers
257
+ $ polyv-live-cli statistics max-concurrent -c "3151318" --start-time 1704067200000 --end-time 1735689600000
258
+
259
+ # Output in JSON format
260
+ $ polyv-live-cli statistics max-concurrent -c "3151318" --start-time 1704067200000 --end-time 1735689600000 -o json
261
+
262
+ Timestamp Range:
263
+ --start-time Start timestamp in 13-digit milliseconds (required)
264
+ --end-time End timestamp in 13-digit milliseconds (required)
265
+ Note: Time range cannot exceed 3 months
266
+
267
+ Output Formats:
268
+ table Formatted output (default)
269
+ json JSON format for programmatic use
270
+ `);
271
+ const audienceCmd = statisticsCmd.command('audience');
272
+ audienceCmd.description('View audience statistics');
273
+ const regionCmd = audienceCmd
274
+ .command('region')
275
+ .description('View audience region distribution')
276
+ .requiredOption('-c, --channel-id <channelId>', '频道ID')
277
+ .requiredOption('--start-time <timestamp>', '开始时间戳 (13位毫秒)', parseInt)
278
+ .requiredOption('--end-time <timestamp>', '结束时间戳 (13位毫秒)', parseInt)
279
+ .option('-t, --type <type>', '地域类型 (country/province/city)', 'province')
280
+ .option('-o, --output <format>', '输出格式 (table|json)', validateOutputFormat, 'table')
281
+ .action(async (options) => {
282
+ try {
283
+ const rangeValidation = (0, date_validation_1.validate90DayTimestampRange)(options.startTime, options.endTime);
284
+ if (!rangeValidation.valid) {
285
+ throw new Error(rangeValidation.error || 'Invalid time range');
286
+ }
287
+ const parentOptions = program.opts();
288
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
289
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
290
+ const regionOptions = {
291
+ channelId: options.channelId,
292
+ startTime: options.startTime,
293
+ endTime: options.endTime,
294
+ type: options.type,
295
+ output: options.output
296
+ };
297
+ await statisticsHandler.viewRegionDistribution(regionOptions);
298
+ }
299
+ catch (error) {
300
+ if (error instanceof Error && error.message.includes('Authentication')) {
301
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
302
+ console.error('\n🔍 Authentication Diagnostics:');
303
+ diagnostics.availableSources.forEach(source => {
304
+ const status = source.appId && source.appSecret ? '✅' : '❌';
305
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
306
+ });
307
+ if (diagnostics.errors.length > 0) {
308
+ console.error('\n❌ Errors:');
309
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
310
+ }
311
+ }
312
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
313
+ process.exit(1);
314
+ }
315
+ });
316
+ regionCmd.addHelpText('after', `
317
+ Examples:
318
+ # View region distribution
319
+ $ polyv-live-cli statistics audience region -c "3151318" --start-time 1648742400000 --end-time 1651334399000
320
+
321
+ # With city type
322
+ $ polyv-live-cli statistics audience region -c "3151318" --start-time 1648742400000 --end-time 1651334399000 --type city
323
+
324
+ # Output in JSON format
325
+ $ polyv-live-cli statistics audience region -c "3151318" --start-time 1648742400000 --end-time 1651334399000 -o json
326
+
327
+ Timestamp Range:
328
+ --start-time Start timestamp in 13-digit milliseconds (required)
329
+ --end-time End timestamp in 13-digit milliseconds (required)
330
+ Note: Time range cannot exceed 90 days
331
+
332
+ Region Types:
333
+ --type Region type (default: province)
334
+ country: View by country
335
+ province: View by province (default)
336
+ city: View by city
337
+
338
+ Output Formats:
339
+ table Formatted table output (default)
340
+ json JSON format for programmatic use
341
+ `);
342
+ const deviceCmd = audienceCmd
343
+ .command('device')
344
+ .description('View audience device distribution')
345
+ .requiredOption('-c, --channel-id <channelId>', '频道ID')
346
+ .requiredOption('--start-time <timestamp>', '开始时间戳 (13位毫秒)', parseInt)
347
+ .requiredOption('--end-time <timestamp>', '结束时间戳 (13位毫秒)', parseInt)
348
+ .option('-o, --output <format>', '输出格式 (table|json)', validateOutputFormat, 'table')
349
+ .action(async (options) => {
350
+ try {
351
+ const rangeValidation = (0, date_validation_1.validate90DayTimestampRange)(options.startTime, options.endTime);
352
+ if (!rangeValidation.valid) {
353
+ throw new Error(rangeValidation.error || 'Invalid time range');
354
+ }
355
+ const parentOptions = program.opts();
356
+ const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
357
+ const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
358
+ const deviceOptions = {
359
+ channelId: options.channelId,
360
+ startTime: options.startTime,
361
+ endTime: options.endTime,
362
+ output: options.output
363
+ };
364
+ await statisticsHandler.viewDeviceDistribution(deviceOptions);
365
+ }
366
+ catch (error) {
367
+ if (error instanceof Error && error.message.includes('Authentication')) {
368
+ const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
369
+ console.error('\n🔍 Authentication Diagnostics:');
370
+ diagnostics.availableSources.forEach(source => {
371
+ const status = source.appId && source.appSecret ? '✅' : '❌';
372
+ console.error(` ${status} ${source.metadata.source}: ${source.type}`);
373
+ });
374
+ if (diagnostics.errors.length > 0) {
375
+ console.error('\n❌ Errors:');
376
+ diagnostics.errors.forEach(err => console.error(` - ${err}`));
377
+ }
378
+ }
379
+ (0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
380
+ process.exit(1);
381
+ }
382
+ });
383
+ deviceCmd.addHelpText('after', `
384
+ Examples:
385
+ # View device distribution
386
+ $ polyv-live-cli statistics audience device -c "3151318" --start-time 1651386101000 --end-time 1652336501462
387
+
388
+ # Output in JSON format
389
+ $ polyv-live-cli statistics audience device -c "3151318" --start-time 1651386101000 --end-time 1652336501462 -o json
390
+
391
+ Timestamp Range:
392
+ --start-time Start timestamp in 13-digit milliseconds (required)
393
+ --end-time End timestamp in 13-digit milliseconds (required)
394
+ Note: Time range cannot exceed 90 days
395
+
396
+ Output Formats:
397
+ table Formatted table output (default)
398
+ json JSON format for programmatic use
399
+ `);
400
+ }
401
+ //# sourceMappingURL=statistics.commands.js.map