polyv-live-api-sdk 1.0.2 → 1.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/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/index.cjs +959 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5894 -4891
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +956 -15
- package/dist/index.js.map +1 -1
- package/dist/services/channel.service.d.ts +43 -2
- package/dist/services/channel.service.d.ts.map +1 -1
- package/dist/services/player.service.d.ts +38 -1
- package/dist/services/player.service.d.ts.map +1 -1
- package/dist/services/statistics.service.d.ts +211 -0
- package/dist/services/statistics.service.d.ts.map +1 -0
- package/dist/services/v4/channel.service.d.ts.map +1 -1
- package/dist/services/v4/user.service.d.ts +31 -1
- package/dist/services/v4/user.service.d.ts.map +1 -1
- package/dist/services/web.service.d.ts +11 -1
- package/dist/services/web.service.d.ts.map +1 -1
- package/dist/types/channel.d.ts +119 -5
- package/dist/types/channel.d.ts.map +1 -1
- package/dist/types/index.d.ts +7 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/player.d.ts +103 -0
- package/dist/types/player.d.ts.map +1 -1
- package/dist/types/statistics-export.d.ts +133 -0
- package/dist/types/statistics-export.d.ts.map +1 -0
- package/dist/types/statistics.d.ts +217 -0
- package/dist/types/statistics.d.ts.map +1 -0
- package/dist/types/v4-channel.d.ts +16 -16
- package/dist/types/v4-channel.d.ts.map +1 -1
- package/dist/types/v4-user.d.ts +42 -0
- package/dist/types/v4-user.d.ts.map +1 -1
- package/dist/types/web.d.ts +9 -5
- package/dist/types/web.d.ts.map +1 -1
- package/dist/utils/date-validation.d.ts +128 -0
- package/dist/utils/date-validation.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -431,6 +431,117 @@ async function collectAll(fetcher, options = {}) {
|
|
|
431
431
|
return allItems;
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
+
// src/utils/date-validation.ts
|
|
435
|
+
var MAX_DATE_RANGE_DAYS = 60;
|
|
436
|
+
var MAX_TIME_RANGE_MONTHS = 3;
|
|
437
|
+
var MAX_AUDIENCE_TIME_RANGE_DAYS = 90;
|
|
438
|
+
var DATE_FORMAT_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
439
|
+
function isValidDateFormat(dateStr) {
|
|
440
|
+
if (!dateStr || typeof dateStr !== "string") {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
if (!DATE_FORMAT_REGEX.test(dateStr)) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
const date = new Date(dateStr);
|
|
447
|
+
if (isNaN(date.getTime())) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
const [year, month, day] = dateStr.split("-").map(Number);
|
|
451
|
+
return date.getFullYear() === year && date.getMonth() + 1 === month && date.getDate() === day;
|
|
452
|
+
}
|
|
453
|
+
function isStartDateBeforeEndDate(startDay, endDay) {
|
|
454
|
+
const startDate = new Date(startDay);
|
|
455
|
+
const endDate = new Date(endDay);
|
|
456
|
+
return startDate <= endDate;
|
|
457
|
+
}
|
|
458
|
+
function isStartTimeBeforeEndTime(startTime, endTime) {
|
|
459
|
+
return startTime <= endTime;
|
|
460
|
+
}
|
|
461
|
+
function isValidTimestamp(value) {
|
|
462
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
return value > 9466848e5;
|
|
466
|
+
}
|
|
467
|
+
function validateDateRange(startDay, endDay, maxDays = MAX_DATE_RANGE_DAYS) {
|
|
468
|
+
if (!isStartDateBeforeEndDate(startDay, endDay)) {
|
|
469
|
+
return {
|
|
470
|
+
valid: false,
|
|
471
|
+
error: "startDay must be before or equal to endDay"
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
const startDate = new Date(startDay);
|
|
475
|
+
const endDate = new Date(endDay);
|
|
476
|
+
const diffTime = endDate.getTime() - startDate.getTime();
|
|
477
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
478
|
+
if (diffDays > maxDays) {
|
|
479
|
+
return {
|
|
480
|
+
valid: false,
|
|
481
|
+
error: `Date range cannot exceed ${maxDays} days`,
|
|
482
|
+
daysDiff: diffDays
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
return { valid: true, daysDiff: diffDays };
|
|
486
|
+
}
|
|
487
|
+
function validateTimestampRange(startTime, endTime, maxMonths = MAX_TIME_RANGE_MONTHS) {
|
|
488
|
+
if (!isStartTimeBeforeEndTime(startTime, endTime)) {
|
|
489
|
+
return {
|
|
490
|
+
valid: false,
|
|
491
|
+
error: "startTime must be before or equal to endTime"
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
const diffTime = endTime - startTime;
|
|
495
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
496
|
+
const maxDays = maxMonths * 31;
|
|
497
|
+
if (diffDays > maxDays) {
|
|
498
|
+
return {
|
|
499
|
+
valid: false,
|
|
500
|
+
error: `Time range cannot exceed ${maxMonths} months`,
|
|
501
|
+
daysDiff: diffDays
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
return { valid: true, daysDiff: diffDays };
|
|
505
|
+
}
|
|
506
|
+
function validate90DayTimestampRange(startTime, endTime) {
|
|
507
|
+
if (!isStartTimeBeforeEndTime(startTime, endTime)) {
|
|
508
|
+
return {
|
|
509
|
+
valid: false,
|
|
510
|
+
error: "startTime must be before or equal to endTime"
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
const diffTime = endTime - startTime;
|
|
514
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
515
|
+
if (diffDays > MAX_AUDIENCE_TIME_RANGE_DAYS) {
|
|
516
|
+
return {
|
|
517
|
+
valid: false,
|
|
518
|
+
error: `Time range cannot exceed ${MAX_AUDIENCE_TIME_RANGE_DAYS} days`,
|
|
519
|
+
daysDiff: diffDays
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
return { valid: true, daysDiff: diffDays };
|
|
523
|
+
}
|
|
524
|
+
function validateConcurrencyDateRange(startDate, endDate, maxDays = MAX_DATE_RANGE_DAYS) {
|
|
525
|
+
if (!isStartDateBeforeEndDate(startDate, endDate)) {
|
|
526
|
+
return {
|
|
527
|
+
valid: false,
|
|
528
|
+
error: "startDate must be before or equal to endDate"
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
const start = new Date(startDate);
|
|
532
|
+
const end = new Date(endDate);
|
|
533
|
+
const diffTime = end.getTime() - start.getTime();
|
|
534
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
535
|
+
if (diffDays > maxDays) {
|
|
536
|
+
return {
|
|
537
|
+
valid: false,
|
|
538
|
+
error: `Date range cannot exceed ${maxDays} days`,
|
|
539
|
+
daysDiff: diffDays
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
return { valid: true, daysDiff: diffDays };
|
|
543
|
+
}
|
|
544
|
+
|
|
434
545
|
// src/services/channel.service.ts
|
|
435
546
|
var ChannelService = class {
|
|
436
547
|
client;
|
|
@@ -1846,17 +1957,21 @@ var ChannelService = class {
|
|
|
1846
1957
|
* await channelService.setRecordDefault('ch123456', 'file123');
|
|
1847
1958
|
* ```
|
|
1848
1959
|
*/
|
|
1849
|
-
async setRecordDefault(channelId, fileId) {
|
|
1960
|
+
async setRecordDefault(channelId, fileId, listType) {
|
|
1850
1961
|
if (!channelId || channelId.trim() === "") {
|
|
1851
1962
|
throw PolyVValidationError.required("channelId");
|
|
1852
1963
|
}
|
|
1853
1964
|
if (!fileId || fileId.trim() === "") {
|
|
1854
1965
|
throw PolyVValidationError.required("fileId");
|
|
1855
1966
|
}
|
|
1967
|
+
const params = { channelId, fileId };
|
|
1968
|
+
if (listType) {
|
|
1969
|
+
params.listType = listType;
|
|
1970
|
+
}
|
|
1856
1971
|
await this.client.httpClient.post(
|
|
1857
1972
|
"/live/v3/channel/record/set-default",
|
|
1858
1973
|
null,
|
|
1859
|
-
{ params
|
|
1974
|
+
{ params }
|
|
1860
1975
|
);
|
|
1861
1976
|
return true;
|
|
1862
1977
|
}
|
|
@@ -1970,6 +2085,38 @@ var ChannelService = class {
|
|
|
1970
2085
|
);
|
|
1971
2086
|
return response;
|
|
1972
2087
|
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Set playback setting (Story 9.7)
|
|
2090
|
+
*
|
|
2091
|
+
* Sets the playback settings for a channel.
|
|
2092
|
+
* API: POST /live/v3/channel/playback/set-setting
|
|
2093
|
+
*
|
|
2094
|
+
* @param channelId - The channel ID
|
|
2095
|
+
* @param options - Playback setting options
|
|
2096
|
+
* @returns true if operation was successful
|
|
2097
|
+
* @throws PolyVValidationError if channelId is empty
|
|
2098
|
+
*
|
|
2099
|
+
* @example
|
|
2100
|
+
* ```typescript
|
|
2101
|
+
* await channelService.setPlaybackSetting('ch123456', {
|
|
2102
|
+
* playbackEnabled: 'Y',
|
|
2103
|
+
* type: 'single',
|
|
2104
|
+
* origin: 'playback',
|
|
2105
|
+
* });
|
|
2106
|
+
* ```
|
|
2107
|
+
*/
|
|
2108
|
+
async setPlaybackSetting(channelId, options) {
|
|
2109
|
+
if (!channelId || channelId.trim() === "") {
|
|
2110
|
+
throw PolyVValidationError.required("channelId");
|
|
2111
|
+
}
|
|
2112
|
+
const params = { channelId, ...options };
|
|
2113
|
+
await this.client.httpClient.post(
|
|
2114
|
+
"/live/v3/channel/playback/set-setting",
|
|
2115
|
+
null,
|
|
2116
|
+
{ params }
|
|
2117
|
+
);
|
|
2118
|
+
return true;
|
|
2119
|
+
}
|
|
1973
2120
|
/**
|
|
1974
2121
|
* Set playback sort
|
|
1975
2122
|
*
|
|
@@ -2299,6 +2446,15 @@ var ChannelService = class {
|
|
|
2299
2446
|
if (options.callbackUrl !== void 0) {
|
|
2300
2447
|
params.callbackUrl = options.callbackUrl;
|
|
2301
2448
|
}
|
|
2449
|
+
if (options.autoConvert !== void 0) {
|
|
2450
|
+
params.autoConvert = options.autoConvert;
|
|
2451
|
+
}
|
|
2452
|
+
if (options.mergeMp4 !== void 0) {
|
|
2453
|
+
params.mergeMp4 = options.mergeMp4;
|
|
2454
|
+
}
|
|
2455
|
+
if (options.orderByCustom !== void 0) {
|
|
2456
|
+
params.orderByCustom = options.orderByCustom;
|
|
2457
|
+
}
|
|
2302
2458
|
await this.client.httpClient.post(
|
|
2303
2459
|
"/live/v3/channel/record/merge-async",
|
|
2304
2460
|
null,
|
|
@@ -4035,6 +4191,44 @@ var ChannelService = class {
|
|
|
4035
4191
|
// ============================================
|
|
4036
4192
|
// Product APIs (Story 8-2)
|
|
4037
4193
|
// ============================================
|
|
4194
|
+
/**
|
|
4195
|
+
* List channel products
|
|
4196
|
+
*
|
|
4197
|
+
* Lists products in a channel with pagination support.
|
|
4198
|
+
*
|
|
4199
|
+
* @param params - Query parameters including channelId (required)
|
|
4200
|
+
* @returns Paginated product list
|
|
4201
|
+
* @throws PolyVValidationError if channelId is missing
|
|
4202
|
+
*
|
|
4203
|
+
* @example
|
|
4204
|
+
* ```typescript
|
|
4205
|
+
* const result = await channelService.listChannelProducts({
|
|
4206
|
+
* channelId: 'ch123456',
|
|
4207
|
+
* pageNumber: 1,
|
|
4208
|
+
* pageSize: 20,
|
|
4209
|
+
* });
|
|
4210
|
+
* console.log(result.contents);
|
|
4211
|
+
* ```
|
|
4212
|
+
*/
|
|
4213
|
+
async listChannelProducts(params) {
|
|
4214
|
+
if (!params.channelId || params.channelId.trim() === "") {
|
|
4215
|
+
throw PolyVValidationError.required("channelId");
|
|
4216
|
+
}
|
|
4217
|
+
const queryParams = {
|
|
4218
|
+
channelId: params.channelId
|
|
4219
|
+
};
|
|
4220
|
+
if (params.pageNumber !== void 0) {
|
|
4221
|
+
queryParams.pageNumber = params.pageNumber;
|
|
4222
|
+
}
|
|
4223
|
+
if (params.pageSize !== void 0) {
|
|
4224
|
+
queryParams.pageSize = params.pageSize;
|
|
4225
|
+
}
|
|
4226
|
+
const response = await this.client.httpClient.get(
|
|
4227
|
+
"/live/v3/channel/product/list",
|
|
4228
|
+
{ params: queryParams }
|
|
4229
|
+
);
|
|
4230
|
+
return response;
|
|
4231
|
+
}
|
|
4038
4232
|
/**
|
|
4039
4233
|
* Add channel product
|
|
4040
4234
|
*
|
|
@@ -7432,7 +7626,8 @@ var WebService = class {
|
|
|
7432
7626
|
* ```typescript
|
|
7433
7627
|
* const result = await client.web.updateWhiteList({
|
|
7434
7628
|
* rank: 1,
|
|
7435
|
-
*
|
|
7629
|
+
* oldCode: '13800138000',
|
|
7630
|
+
* code: '13900139000',
|
|
7436
7631
|
* name: 'Updated Name',
|
|
7437
7632
|
* channelId: '123456',
|
|
7438
7633
|
* });
|
|
@@ -7442,6 +7637,9 @@ var WebService = class {
|
|
|
7442
7637
|
if (params.rank !== 1 && params.rank !== 2) {
|
|
7443
7638
|
throw new PolyVValidationError("rank must be 1 or 2");
|
|
7444
7639
|
}
|
|
7640
|
+
if (!params.oldCode || params.oldCode.trim() === "") {
|
|
7641
|
+
throw new PolyVValidationError("oldCode is required");
|
|
7642
|
+
}
|
|
7445
7643
|
if (!params.code || params.code.trim() === "") {
|
|
7446
7644
|
throw new PolyVValidationError("code is required");
|
|
7447
7645
|
}
|
|
@@ -7453,6 +7651,7 @@ var WebService = class {
|
|
|
7453
7651
|
}
|
|
7454
7652
|
const apiParams = {
|
|
7455
7653
|
rank: params.rank,
|
|
7654
|
+
oldCode: params.oldCode,
|
|
7456
7655
|
code: params.code
|
|
7457
7656
|
};
|
|
7458
7657
|
if (params.name) {
|
|
@@ -7477,24 +7676,39 @@ var WebService = class {
|
|
|
7477
7676
|
*
|
|
7478
7677
|
* @example
|
|
7479
7678
|
* ```typescript
|
|
7679
|
+
* // Delete specific codes
|
|
7480
7680
|
* const result = await client.web.deleteWhiteList({
|
|
7481
7681
|
* rank: 1,
|
|
7682
|
+
* isClear: 'N',
|
|
7482
7683
|
* codes: '13800138000,13800138001',
|
|
7483
7684
|
* channelId: '123456',
|
|
7484
7685
|
* });
|
|
7686
|
+
*
|
|
7687
|
+
* // Clear all
|
|
7688
|
+
* const result = await client.web.deleteWhiteList({
|
|
7689
|
+
* rank: 1,
|
|
7690
|
+
* isClear: 'Y',
|
|
7691
|
+
* channelId: '123456',
|
|
7692
|
+
* });
|
|
7485
7693
|
* ```
|
|
7486
7694
|
*/
|
|
7487
7695
|
async deleteWhiteList(params) {
|
|
7488
7696
|
if (params.rank !== 1 && params.rank !== 2) {
|
|
7489
7697
|
throw new PolyVValidationError("rank must be 1 or 2");
|
|
7490
7698
|
}
|
|
7491
|
-
if (!params.
|
|
7492
|
-
throw new PolyVValidationError("
|
|
7699
|
+
if (!params.isClear) {
|
|
7700
|
+
throw new PolyVValidationError("isClear is required");
|
|
7701
|
+
}
|
|
7702
|
+
if (params.isClear === "N" && (!params.codes || params.codes.trim() === "")) {
|
|
7703
|
+
throw new PolyVValidationError("codes is required when isClear=N");
|
|
7493
7704
|
}
|
|
7494
7705
|
const apiParams = {
|
|
7495
7706
|
rank: params.rank,
|
|
7496
|
-
|
|
7707
|
+
isClear: params.isClear
|
|
7497
7708
|
};
|
|
7709
|
+
if (params.codes) {
|
|
7710
|
+
apiParams.code = params.codes;
|
|
7711
|
+
}
|
|
7498
7712
|
if (params.channelId) {
|
|
7499
7713
|
apiParams.channelId = params.channelId;
|
|
7500
7714
|
}
|
|
@@ -9399,6 +9613,112 @@ var PlayerService = class {
|
|
|
9399
9613
|
}
|
|
9400
9614
|
}
|
|
9401
9615
|
}
|
|
9616
|
+
// ============================================
|
|
9617
|
+
// Channel Decorate APIs (Story 10.5)
|
|
9618
|
+
// ============================================
|
|
9619
|
+
/**
|
|
9620
|
+
* Get channel decorate settings
|
|
9621
|
+
* Query channel player decoration settings (watermark, warmup image, etc.)
|
|
9622
|
+
*
|
|
9623
|
+
* @param channelId - Channel ID
|
|
9624
|
+
* @returns Channel decorate settings
|
|
9625
|
+
*
|
|
9626
|
+
* @example
|
|
9627
|
+
* ```typescript
|
|
9628
|
+
* const decorate = await client.player.getChannelDecorate(123456);
|
|
9629
|
+
* console.log(decorate.player.watermarkEnabled);
|
|
9630
|
+
* ```
|
|
9631
|
+
*/
|
|
9632
|
+
async getChannelDecorate(channelId) {
|
|
9633
|
+
this.validateChannelId(channelId);
|
|
9634
|
+
const response = await this.client.httpClient.get(
|
|
9635
|
+
"/live/v4/channel/decorate/get",
|
|
9636
|
+
{ params: { channelId } }
|
|
9637
|
+
);
|
|
9638
|
+
return response;
|
|
9639
|
+
}
|
|
9640
|
+
/**
|
|
9641
|
+
* Update channel decorate settings
|
|
9642
|
+
* Update channel player decoration settings (watermark, warmup image, etc.)
|
|
9643
|
+
*
|
|
9644
|
+
* @param channelId - Channel ID
|
|
9645
|
+
* @param params - Channel decorate update parameters
|
|
9646
|
+
* @returns true on success
|
|
9647
|
+
*
|
|
9648
|
+
* @example
|
|
9649
|
+
* ```typescript
|
|
9650
|
+
* await client.player.updateChannelDecorate(123456, {
|
|
9651
|
+
* watermarkEnabled: 'Y',
|
|
9652
|
+
* iconUrl: 'http://example.com/logo.png',
|
|
9653
|
+
* iconPosition: 'br',
|
|
9654
|
+
* logoOpacity: 0.8,
|
|
9655
|
+
* });
|
|
9656
|
+
* ```
|
|
9657
|
+
*/
|
|
9658
|
+
async updateChannelDecorate(channelId, params) {
|
|
9659
|
+
this.validateChannelId(channelId);
|
|
9660
|
+
if (params.iconPosition !== void 0) {
|
|
9661
|
+
this.validateLogoPosition(params.iconPosition);
|
|
9662
|
+
}
|
|
9663
|
+
if (params.logoOpacity !== void 0) {
|
|
9664
|
+
this.validateDecorateOpacity(params.logoOpacity);
|
|
9665
|
+
}
|
|
9666
|
+
if (params.watermarkEnabled !== void 0) {
|
|
9667
|
+
this.validateYNValue(params.watermarkEnabled, "watermarkEnabled");
|
|
9668
|
+
}
|
|
9669
|
+
if (params.warmUpEnabled !== void 0) {
|
|
9670
|
+
this.validateYNValue(params.warmUpEnabled, "warmUpEnabled");
|
|
9671
|
+
}
|
|
9672
|
+
const playerBody = {};
|
|
9673
|
+
if (params.watermarkEnabled !== void 0) {
|
|
9674
|
+
playerBody.watermarkEnabled = params.watermarkEnabled;
|
|
9675
|
+
}
|
|
9676
|
+
if (params.iconUrl !== void 0) {
|
|
9677
|
+
playerBody.iconUrl = params.iconUrl;
|
|
9678
|
+
}
|
|
9679
|
+
if (params.iconPosition !== void 0) {
|
|
9680
|
+
playerBody.iconPosition = params.iconPosition;
|
|
9681
|
+
}
|
|
9682
|
+
if (params.logoOpacity !== void 0) {
|
|
9683
|
+
playerBody.logoOpacity = params.logoOpacity;
|
|
9684
|
+
}
|
|
9685
|
+
if (params.iconLink !== void 0) {
|
|
9686
|
+
playerBody.iconLink = params.iconLink;
|
|
9687
|
+
}
|
|
9688
|
+
if (params.warmUpEnabled !== void 0) {
|
|
9689
|
+
playerBody.warmUpEnabled = params.warmUpEnabled;
|
|
9690
|
+
}
|
|
9691
|
+
if (params.warmUpImageUrl !== void 0) {
|
|
9692
|
+
playerBody.warmUpImageUrl = params.warmUpImageUrl;
|
|
9693
|
+
}
|
|
9694
|
+
if (params.coverJumpUrl !== void 0) {
|
|
9695
|
+
playerBody.coverJumpUrl = params.coverJumpUrl;
|
|
9696
|
+
}
|
|
9697
|
+
if (params.backgroundUrl !== void 0) {
|
|
9698
|
+
playerBody.backgroundUrl = params.backgroundUrl;
|
|
9699
|
+
}
|
|
9700
|
+
if (params.basePV !== void 0) {
|
|
9701
|
+
playerBody.basePV = params.basePV;
|
|
9702
|
+
}
|
|
9703
|
+
if (params.actualPV !== void 0) {
|
|
9704
|
+
playerBody.actualPV = params.actualPV;
|
|
9705
|
+
}
|
|
9706
|
+
const body = { player: playerBody };
|
|
9707
|
+
const response = await this.client.httpClient.post(
|
|
9708
|
+
"/live/v4/channel/decorate/update",
|
|
9709
|
+
body,
|
|
9710
|
+
{ params: { channelId } }
|
|
9711
|
+
);
|
|
9712
|
+
return response;
|
|
9713
|
+
}
|
|
9714
|
+
/**
|
|
9715
|
+
* Validate decorate opacity (0-1)
|
|
9716
|
+
*/
|
|
9717
|
+
validateDecorateOpacity(opacity) {
|
|
9718
|
+
if (typeof opacity !== "number" || opacity < 0 || opacity > 1) {
|
|
9719
|
+
throw new PolyVValidationError("logoOpacity must be a number between 0 and 1");
|
|
9720
|
+
}
|
|
9721
|
+
}
|
|
9402
9722
|
};
|
|
9403
9723
|
|
|
9404
9724
|
// src/services/other.service.ts
|
|
@@ -10860,7 +11180,9 @@ var V4ChannelService = class {
|
|
|
10860
11180
|
* @returns Sessions list
|
|
10861
11181
|
*/
|
|
10862
11182
|
async sessionList(params) {
|
|
10863
|
-
|
|
11183
|
+
if (params.channelId) {
|
|
11184
|
+
this.validateChannelId(params.channelId);
|
|
11185
|
+
}
|
|
10864
11186
|
this.validatePaginationParams(params);
|
|
10865
11187
|
const response = await this.client.httpClient.get(
|
|
10866
11188
|
"/live/v4/channel/session/new/list",
|
|
@@ -12031,8 +12353,16 @@ var V4ChannelService = class {
|
|
|
12031
12353
|
* Validate channel ID
|
|
12032
12354
|
*/
|
|
12033
12355
|
validateChannelId(channelId) {
|
|
12034
|
-
if (
|
|
12035
|
-
|
|
12356
|
+
if (typeof channelId === "string") {
|
|
12357
|
+
if (!channelId || channelId.trim() === "") {
|
|
12358
|
+
throw new PolyVValidationError("channelId is required and cannot be empty", "channelId");
|
|
12359
|
+
}
|
|
12360
|
+
} else if (typeof channelId === "number") {
|
|
12361
|
+
if (!channelId || channelId <= 0) {
|
|
12362
|
+
throw new PolyVValidationError("channelId is required and must be a positive number", "channelId");
|
|
12363
|
+
}
|
|
12364
|
+
} else {
|
|
12365
|
+
throw new PolyVValidationError("channelId must be a string or number", "channelId");
|
|
12036
12366
|
}
|
|
12037
12367
|
}
|
|
12038
12368
|
/**
|
|
@@ -12816,7 +13146,7 @@ var V4UserService = class {
|
|
|
12816
13146
|
*/
|
|
12817
13147
|
async listViewerLabels() {
|
|
12818
13148
|
const response = await this.client.httpClient.get(
|
|
12819
|
-
"/live/v4/user/viewer-
|
|
13149
|
+
"/live/v4/user/viewer-label/list",
|
|
12820
13150
|
{}
|
|
12821
13151
|
);
|
|
12822
13152
|
return response;
|
|
@@ -12896,8 +13226,11 @@ var V4UserService = class {
|
|
|
12896
13226
|
this.validateRequiredString(params.viewerUnionId, "viewerUnionId");
|
|
12897
13227
|
this.validateRequiredNumber(params.labelId, "labelId");
|
|
12898
13228
|
await this.client.httpClient.post(
|
|
12899
|
-
"/live/v4/user/viewer-
|
|
12900
|
-
|
|
13229
|
+
"/live/v4/user/viewer-label/add-viewers-label",
|
|
13230
|
+
{
|
|
13231
|
+
viewerUnionIds: [params.viewerUnionId],
|
|
13232
|
+
labelIds: [params.labelId]
|
|
13233
|
+
}
|
|
12901
13234
|
);
|
|
12902
13235
|
}
|
|
12903
13236
|
/**
|
|
@@ -12917,8 +13250,11 @@ var V4UserService = class {
|
|
|
12917
13250
|
this.validateRequiredString(params.viewerUnionId, "viewerUnionId");
|
|
12918
13251
|
this.validateRequiredNumber(params.labelId, "labelId");
|
|
12919
13252
|
await this.client.httpClient.post(
|
|
12920
|
-
"/live/v4/user/viewer-
|
|
12921
|
-
|
|
13253
|
+
"/live/v4/user/viewer-label/remove-viewers-label",
|
|
13254
|
+
{
|
|
13255
|
+
viewerUnionIds: [params.viewerUnionId],
|
|
13256
|
+
labelIds: [params.labelId]
|
|
13257
|
+
}
|
|
12922
13258
|
);
|
|
12923
13259
|
}
|
|
12924
13260
|
// ============================================
|
|
@@ -13932,6 +14268,47 @@ var V4UserService = class {
|
|
|
13932
14268
|
return response;
|
|
13933
14269
|
}
|
|
13934
14270
|
// ============================================
|
|
14271
|
+
// Story 13-3: Global Channel Settings APIs
|
|
14272
|
+
// ============================================
|
|
14273
|
+
/**
|
|
14274
|
+
* Get global channel settings
|
|
14275
|
+
*
|
|
14276
|
+
* @returns Global channel settings
|
|
14277
|
+
*
|
|
14278
|
+
* @example
|
|
14279
|
+
* ```typescript
|
|
14280
|
+
* const settings = await client.v4User.getGlobalChannelSettings();
|
|
14281
|
+
* ```
|
|
14282
|
+
*/
|
|
14283
|
+
async getGlobalChannelSettings() {
|
|
14284
|
+
const response = await this.client.httpClient.get(
|
|
14285
|
+
"/live/v4/user/global-setting/switch/get",
|
|
14286
|
+
{}
|
|
14287
|
+
);
|
|
14288
|
+
return response;
|
|
14289
|
+
}
|
|
14290
|
+
/**
|
|
14291
|
+
* Update global channel settings
|
|
14292
|
+
*
|
|
14293
|
+
* @param params - Update parameters
|
|
14294
|
+
*
|
|
14295
|
+
* @example
|
|
14296
|
+
* ```typescript
|
|
14297
|
+
* await client.v4User.updateGlobalChannelSettings({
|
|
14298
|
+
* channelConcurrencesEnabled: 'Y',
|
|
14299
|
+
* donateEnabled: 'N',
|
|
14300
|
+
* coverImgType: 'contain',
|
|
14301
|
+
* });
|
|
14302
|
+
* ```
|
|
14303
|
+
*/
|
|
14304
|
+
async updateGlobalChannelSettings(params) {
|
|
14305
|
+
this.validateGlobalSettingsParams(params);
|
|
14306
|
+
await this.client.httpClient.post(
|
|
14307
|
+
"/live/v4/user/global-setting/switch/update",
|
|
14308
|
+
params
|
|
14309
|
+
);
|
|
14310
|
+
}
|
|
14311
|
+
// ============================================
|
|
13935
14312
|
// Private Validation Helpers
|
|
13936
14313
|
// ============================================
|
|
13937
14314
|
/**
|
|
@@ -13961,6 +14338,31 @@ var V4UserService = class {
|
|
|
13961
14338
|
throw new PolyVValidationError(`${fieldName} is required`, fieldName, value);
|
|
13962
14339
|
}
|
|
13963
14340
|
}
|
|
14341
|
+
/**
|
|
14342
|
+
* Validate global settings update parameters
|
|
14343
|
+
*/
|
|
14344
|
+
validateGlobalSettingsParams(params) {
|
|
14345
|
+
const booleanFields = [
|
|
14346
|
+
"channelConcurrencesEnabled",
|
|
14347
|
+
"timelyConvertEnabled",
|
|
14348
|
+
"donateEnabled",
|
|
14349
|
+
"rebirthAutoUploadEnabled",
|
|
14350
|
+
"rebirthAutoConvertEnabled",
|
|
14351
|
+
"pptCoveredEnabled",
|
|
14352
|
+
"testModeButtonEnabled"
|
|
14353
|
+
];
|
|
14354
|
+
for (const field of booleanFields) {
|
|
14355
|
+
const value = params[field];
|
|
14356
|
+
if (value !== void 0 && value !== "Y" && value !== "N") {
|
|
14357
|
+
throw new PolyVValidationError(`${field} must be 'Y' or 'N'`, field, value);
|
|
14358
|
+
}
|
|
14359
|
+
}
|
|
14360
|
+
if (params.coverImgType !== void 0) {
|
|
14361
|
+
if (params.coverImgType !== "contain" && params.coverImgType !== "cover") {
|
|
14362
|
+
throw new PolyVValidationError("coverImgType must be 'contain' or 'cover'", "coverImgType", params.coverImgType);
|
|
14363
|
+
}
|
|
14364
|
+
}
|
|
14365
|
+
}
|
|
13964
14366
|
};
|
|
13965
14367
|
|
|
13966
14368
|
// src/services/v4/global.service.ts
|
|
@@ -14839,6 +15241,540 @@ var V4WebAppService = class {
|
|
|
14839
15241
|
}
|
|
14840
15242
|
};
|
|
14841
15243
|
|
|
15244
|
+
// src/services/statistics.service.ts
|
|
15245
|
+
var StatisticsService = class {
|
|
15246
|
+
client;
|
|
15247
|
+
/**
|
|
15248
|
+
* Create a new StatisticsService instance
|
|
15249
|
+
*
|
|
15250
|
+
* @param client - The PolyVClient instance to use for API calls
|
|
15251
|
+
*/
|
|
15252
|
+
constructor(client) {
|
|
15253
|
+
this.client = client;
|
|
15254
|
+
}
|
|
15255
|
+
// ============================================
|
|
15256
|
+
// Daily View Statistics API
|
|
15257
|
+
// ============================================
|
|
15258
|
+
/**
|
|
15259
|
+
* Get daily view statistics
|
|
15260
|
+
*
|
|
15261
|
+
* Query daily view statistics for a channel within a date range.
|
|
15262
|
+
* The date range cannot exceed 60 days.
|
|
15263
|
+
*
|
|
15264
|
+
* @param params - Query parameters
|
|
15265
|
+
* @returns Daily view statistics response
|
|
15266
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15267
|
+
*
|
|
15268
|
+
* @example
|
|
15269
|
+
* ```typescript
|
|
15270
|
+
* const result = await client.statistics.getDailyViewStatistics({
|
|
15271
|
+
* channelId: '123456',
|
|
15272
|
+
* startDay: '2024-01-01',
|
|
15273
|
+
* endDay: '2024-01-31',
|
|
15274
|
+
* });
|
|
15275
|
+
* console.log(result.contents);
|
|
15276
|
+
* ```
|
|
15277
|
+
*/
|
|
15278
|
+
async getDailyViewStatistics(params) {
|
|
15279
|
+
this.validateGetDailyViewStatisticsParams(params);
|
|
15280
|
+
const response = await this.client.httpClient.get(
|
|
15281
|
+
"/live/v3/channel/statistics/daily/summary",
|
|
15282
|
+
{ params }
|
|
15283
|
+
);
|
|
15284
|
+
return {
|
|
15285
|
+
contents: response
|
|
15286
|
+
};
|
|
15287
|
+
}
|
|
15288
|
+
// ============================================
|
|
15289
|
+
// Private Validation Helpers
|
|
15290
|
+
// ============================================
|
|
15291
|
+
/**
|
|
15292
|
+
* Validate parameters for getDailyViewStatistics
|
|
15293
|
+
*/
|
|
15294
|
+
validateGetDailyViewStatisticsParams(params) {
|
|
15295
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15296
|
+
throw new PolyVValidationError(
|
|
15297
|
+
"channelId is required and must be a non-empty string",
|
|
15298
|
+
"channelId",
|
|
15299
|
+
params.channelId
|
|
15300
|
+
);
|
|
15301
|
+
}
|
|
15302
|
+
if (!params.startDay || !isValidDateFormat(params.startDay)) {
|
|
15303
|
+
throw new PolyVValidationError(
|
|
15304
|
+
"startDay is required and must be in yyyy-MM-dd format",
|
|
15305
|
+
"startDay",
|
|
15306
|
+
params.startDay
|
|
15307
|
+
);
|
|
15308
|
+
}
|
|
15309
|
+
if (!params.endDay || !isValidDateFormat(params.endDay)) {
|
|
15310
|
+
throw new PolyVValidationError(
|
|
15311
|
+
"endDay is required and must be in yyyy-MM-dd format",
|
|
15312
|
+
"endDay",
|
|
15313
|
+
params.endDay
|
|
15314
|
+
);
|
|
15315
|
+
}
|
|
15316
|
+
const rangeValidation = validateDateRange(params.startDay, params.endDay, MAX_DATE_RANGE_DAYS);
|
|
15317
|
+
if (!rangeValidation.valid) {
|
|
15318
|
+
throw new PolyVValidationError(
|
|
15319
|
+
rangeValidation.error || "Invalid date range",
|
|
15320
|
+
"dateRange",
|
|
15321
|
+
{ startDay: params.startDay, endDay: params.endDay, daysDiff: rangeValidation.daysDiff }
|
|
15322
|
+
);
|
|
15323
|
+
}
|
|
15324
|
+
}
|
|
15325
|
+
// ============================================
|
|
15326
|
+
// Concurrency Data API (Story 10.2)
|
|
15327
|
+
// ============================================
|
|
15328
|
+
/**
|
|
15329
|
+
* Get historical concurrency data
|
|
15330
|
+
*
|
|
15331
|
+
* Query historical concurrency data for a channel within a date range.
|
|
15332
|
+
* The date range cannot exceed 60 days.
|
|
15333
|
+
*
|
|
15334
|
+
* @param params - Query parameters
|
|
15335
|
+
* @returns Concurrency data response
|
|
15336
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15337
|
+
*
|
|
15338
|
+
* @example
|
|
15339
|
+
* ```typescript
|
|
15340
|
+
* const result = await client.statistics.getConcurrencyData({
|
|
15341
|
+
* channelId: '123456',
|
|
15342
|
+
* startDate: '2024-01-01',
|
|
15343
|
+
* endDate: '2024-01-31',
|
|
15344
|
+
* });
|
|
15345
|
+
* console.log(result.contents);
|
|
15346
|
+
* ```
|
|
15347
|
+
*/
|
|
15348
|
+
async getConcurrencyData(params) {
|
|
15349
|
+
this.validateGetConcurrencyDataParams(params);
|
|
15350
|
+
const response = await this.client.httpClient.get(
|
|
15351
|
+
"/live/v3/channel/statistics/concurrence",
|
|
15352
|
+
{ params }
|
|
15353
|
+
);
|
|
15354
|
+
return {
|
|
15355
|
+
contents: response
|
|
15356
|
+
};
|
|
15357
|
+
}
|
|
15358
|
+
/**
|
|
15359
|
+
* Validate parameters for getConcurrencyData
|
|
15360
|
+
*/
|
|
15361
|
+
validateGetConcurrencyDataParams(params) {
|
|
15362
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15363
|
+
throw new PolyVValidationError(
|
|
15364
|
+
"channelId is required and must be a non-empty string",
|
|
15365
|
+
"channelId",
|
|
15366
|
+
params.channelId
|
|
15367
|
+
);
|
|
15368
|
+
}
|
|
15369
|
+
if (!params.startDate || !isValidDateFormat(params.startDate)) {
|
|
15370
|
+
throw new PolyVValidationError(
|
|
15371
|
+
"startDate is required and must be in yyyy-MM-dd format",
|
|
15372
|
+
"startDate",
|
|
15373
|
+
params.startDate
|
|
15374
|
+
);
|
|
15375
|
+
}
|
|
15376
|
+
if (!params.endDate || !isValidDateFormat(params.endDate)) {
|
|
15377
|
+
throw new PolyVValidationError(
|
|
15378
|
+
"endDate is required and must be in yyyy-MM-dd format",
|
|
15379
|
+
"endDate",
|
|
15380
|
+
params.endDate
|
|
15381
|
+
);
|
|
15382
|
+
}
|
|
15383
|
+
const rangeValidation = validateConcurrencyDateRange(params.startDate, params.endDate, MAX_DATE_RANGE_DAYS);
|
|
15384
|
+
if (!rangeValidation.valid) {
|
|
15385
|
+
throw new PolyVValidationError(
|
|
15386
|
+
rangeValidation.error || "Invalid date range",
|
|
15387
|
+
"dateRange",
|
|
15388
|
+
{ startDate: params.startDate, endDate: params.endDate, daysDiff: rangeValidation.daysDiff }
|
|
15389
|
+
);
|
|
15390
|
+
}
|
|
15391
|
+
}
|
|
15392
|
+
// ============================================
|
|
15393
|
+
// Max Concurrent API (Story 10.2)
|
|
15394
|
+
// ============================================
|
|
15395
|
+
/**
|
|
15396
|
+
* Get maximum historical concurrent viewers
|
|
15397
|
+
*
|
|
15398
|
+
* Query the maximum concurrent viewers for a channel within a time range.
|
|
15399
|
+
* The time range cannot exceed 3 months.
|
|
15400
|
+
*
|
|
15401
|
+
* @param params - Query parameters
|
|
15402
|
+
* @returns Max concurrent response
|
|
15403
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15404
|
+
*
|
|
15405
|
+
* @example
|
|
15406
|
+
* ```typescript
|
|
15407
|
+
* const result = await client.statistics.getMaxConcurrent({
|
|
15408
|
+
* channelId: '123456',
|
|
15409
|
+
* startTime: 1704067200000,
|
|
15410
|
+
* endTime: 1735689600000,
|
|
15411
|
+
* });
|
|
15412
|
+
* console.log(result.contents);
|
|
15413
|
+
* ```
|
|
15414
|
+
*/
|
|
15415
|
+
async getMaxConcurrent(params) {
|
|
15416
|
+
this.validateGetMaxConcurrentParams(params);
|
|
15417
|
+
const response = await this.client.httpClient.get(
|
|
15418
|
+
"/live/v3/channel/statistics/get-max-history-concurrent",
|
|
15419
|
+
{ params }
|
|
15420
|
+
);
|
|
15421
|
+
return {
|
|
15422
|
+
contents: response
|
|
15423
|
+
};
|
|
15424
|
+
}
|
|
15425
|
+
/**
|
|
15426
|
+
* Validate parameters for getMaxConcurrent
|
|
15427
|
+
*/
|
|
15428
|
+
validateGetMaxConcurrentParams(params) {
|
|
15429
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15430
|
+
throw new PolyVValidationError(
|
|
15431
|
+
"channelId is required and must be a non-empty string",
|
|
15432
|
+
"channelId",
|
|
15433
|
+
params.channelId
|
|
15434
|
+
);
|
|
15435
|
+
}
|
|
15436
|
+
if (!isValidTimestamp(params.startTime)) {
|
|
15437
|
+
throw new PolyVValidationError(
|
|
15438
|
+
"startTime is required and must be a valid timestamp",
|
|
15439
|
+
"startTime",
|
|
15440
|
+
params.startTime
|
|
15441
|
+
);
|
|
15442
|
+
}
|
|
15443
|
+
if (!isValidTimestamp(params.endTime)) {
|
|
15444
|
+
throw new PolyVValidationError(
|
|
15445
|
+
"endTime is required and must be a valid timestamp",
|
|
15446
|
+
"endTime",
|
|
15447
|
+
params.endTime
|
|
15448
|
+
);
|
|
15449
|
+
}
|
|
15450
|
+
const rangeValidation = validateTimestampRange(params.startTime, params.endTime);
|
|
15451
|
+
if (!rangeValidation.valid) {
|
|
15452
|
+
throw new PolyVValidationError(
|
|
15453
|
+
rangeValidation.error || "Invalid time range",
|
|
15454
|
+
"timeRange",
|
|
15455
|
+
{ startTime: params.startTime, endTime: params.endTime, daysDiff: rangeValidation.daysDiff }
|
|
15456
|
+
);
|
|
15457
|
+
}
|
|
15458
|
+
}
|
|
15459
|
+
// ============================================
|
|
15460
|
+
// Region Distribution API (Story 10.3)
|
|
15461
|
+
// ============================================
|
|
15462
|
+
/**
|
|
15463
|
+
* Get region distribution
|
|
15464
|
+
*
|
|
15465
|
+
* Query the geographic distribution of viewers for a channel.
|
|
15466
|
+
* The time range cannot exceed 90 days.
|
|
15467
|
+
*
|
|
15468
|
+
* @param params - Query parameters
|
|
15469
|
+
* @returns Region distribution response
|
|
15470
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15471
|
+
*
|
|
15472
|
+
* @example
|
|
15473
|
+
* ```typescript
|
|
15474
|
+
* const result = await client.statistics.getRegionDistribution({
|
|
15475
|
+
* channelId: '123456',
|
|
15476
|
+
* startTime: 1648742400000,
|
|
15477
|
+
* endTime: 1651334399000,
|
|
15478
|
+
* type: 'province',
|
|
15479
|
+
* });
|
|
15480
|
+
* console.log(result.data);
|
|
15481
|
+
* ```
|
|
15482
|
+
*/
|
|
15483
|
+
async getRegionDistribution(params) {
|
|
15484
|
+
this.validateGetRegionDistributionParams(params);
|
|
15485
|
+
const requestParams = {
|
|
15486
|
+
channelId: params.channelId,
|
|
15487
|
+
startTime: params.startTime,
|
|
15488
|
+
endTime: params.endTime
|
|
15489
|
+
};
|
|
15490
|
+
if (params.type) {
|
|
15491
|
+
requestParams.type = params.type;
|
|
15492
|
+
}
|
|
15493
|
+
const response = await this.client.httpClient.get(
|
|
15494
|
+
"/live/v4/channel/statistics/geo-summary-mc",
|
|
15495
|
+
{ params: requestParams }
|
|
15496
|
+
);
|
|
15497
|
+
return response;
|
|
15498
|
+
}
|
|
15499
|
+
/**
|
|
15500
|
+
* Validate parameters for getRegionDistribution
|
|
15501
|
+
*/
|
|
15502
|
+
validateGetRegionDistributionParams(params) {
|
|
15503
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15504
|
+
throw new PolyVValidationError(
|
|
15505
|
+
"channelId is required and must be a non-empty string",
|
|
15506
|
+
"channelId",
|
|
15507
|
+
params.channelId
|
|
15508
|
+
);
|
|
15509
|
+
}
|
|
15510
|
+
if (!isValidTimestamp(params.startTime)) {
|
|
15511
|
+
throw new PolyVValidationError(
|
|
15512
|
+
"startTime is required and must be a valid timestamp",
|
|
15513
|
+
"startTime",
|
|
15514
|
+
params.startTime
|
|
15515
|
+
);
|
|
15516
|
+
}
|
|
15517
|
+
if (!isValidTimestamp(params.endTime)) {
|
|
15518
|
+
throw new PolyVValidationError(
|
|
15519
|
+
"endTime is required and must be a valid timestamp",
|
|
15520
|
+
"endTime",
|
|
15521
|
+
params.endTime
|
|
15522
|
+
);
|
|
15523
|
+
}
|
|
15524
|
+
const rangeValidation = validate90DayTimestampRange(params.startTime, params.endTime);
|
|
15525
|
+
if (!rangeValidation.valid) {
|
|
15526
|
+
throw new PolyVValidationError(
|
|
15527
|
+
rangeValidation.error || "Invalid time range",
|
|
15528
|
+
"timeRange",
|
|
15529
|
+
{ startTime: params.startTime, endTime: params.endTime, daysDiff: rangeValidation.daysDiff }
|
|
15530
|
+
);
|
|
15531
|
+
}
|
|
15532
|
+
if (params.type !== void 0) {
|
|
15533
|
+
const validTypes = ["country", "province", "city"];
|
|
15534
|
+
if (!validTypes.includes(params.type)) {
|
|
15535
|
+
throw new PolyVValidationError(
|
|
15536
|
+
"Type must be one of: country, province, city",
|
|
15537
|
+
"type",
|
|
15538
|
+
params.type
|
|
15539
|
+
);
|
|
15540
|
+
}
|
|
15541
|
+
}
|
|
15542
|
+
}
|
|
15543
|
+
// ============================================
|
|
15544
|
+
// Device Distribution API (Story 10.3)
|
|
15545
|
+
// ============================================
|
|
15546
|
+
/**
|
|
15547
|
+
* Get device distribution
|
|
15548
|
+
*
|
|
15549
|
+
* Query the browser/device distribution of viewers for a channel.
|
|
15550
|
+
* The time range cannot exceed 90 days.
|
|
15551
|
+
*
|
|
15552
|
+
* @param params - Query parameters
|
|
15553
|
+
* @returns Device distribution response
|
|
15554
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15555
|
+
*
|
|
15556
|
+
* @example
|
|
15557
|
+
* ```typescript
|
|
15558
|
+
* const result = await client.statistics.getDeviceDistribution({
|
|
15559
|
+
* channelId: '123456',
|
|
15560
|
+
* startTime: 1651386101000,
|
|
15561
|
+
* endTime: 1652336501462,
|
|
15562
|
+
* });
|
|
15563
|
+
* console.log(result.data);
|
|
15564
|
+
* ```
|
|
15565
|
+
*/
|
|
15566
|
+
async getDeviceDistribution(params) {
|
|
15567
|
+
this.validateGetDeviceDistributionParams(params);
|
|
15568
|
+
const response = await this.client.httpClient.get(
|
|
15569
|
+
"/live/v4/channel/statistics/browser-summary",
|
|
15570
|
+
{ params }
|
|
15571
|
+
);
|
|
15572
|
+
return response;
|
|
15573
|
+
}
|
|
15574
|
+
/**
|
|
15575
|
+
* Validate parameters for getDeviceDistribution
|
|
15576
|
+
*/
|
|
15577
|
+
validateGetDeviceDistributionParams(params) {
|
|
15578
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15579
|
+
throw new PolyVValidationError(
|
|
15580
|
+
"channelId is required and must be a non-empty string",
|
|
15581
|
+
"channelId",
|
|
15582
|
+
params.channelId
|
|
15583
|
+
);
|
|
15584
|
+
}
|
|
15585
|
+
if (!isValidTimestamp(params.startTime)) {
|
|
15586
|
+
throw new PolyVValidationError(
|
|
15587
|
+
"startTime is required and must be a valid timestamp",
|
|
15588
|
+
"startTime",
|
|
15589
|
+
params.startTime
|
|
15590
|
+
);
|
|
15591
|
+
}
|
|
15592
|
+
if (!isValidTimestamp(params.endTime)) {
|
|
15593
|
+
throw new PolyVValidationError(
|
|
15594
|
+
"endTime is required and must be a valid timestamp",
|
|
15595
|
+
"endTime",
|
|
15596
|
+
params.endTime
|
|
15597
|
+
);
|
|
15598
|
+
}
|
|
15599
|
+
const rangeValidation = validate90DayTimestampRange(params.startTime, params.endTime);
|
|
15600
|
+
if (!rangeValidation.valid) {
|
|
15601
|
+
throw new PolyVValidationError(
|
|
15602
|
+
rangeValidation.error || "Invalid time range",
|
|
15603
|
+
"timeRange",
|
|
15604
|
+
{ startTime: params.startTime, endTime: params.endTime, daysDiff: rangeValidation.daysDiff }
|
|
15605
|
+
);
|
|
15606
|
+
}
|
|
15607
|
+
}
|
|
15608
|
+
// ============================================
|
|
15609
|
+
// Viewlog Export API (Story 10.4)
|
|
15610
|
+
// ============================================
|
|
15611
|
+
/**
|
|
15612
|
+
* Get viewlog (viewing log) data
|
|
15613
|
+
*
|
|
15614
|
+
* Query viewing log data for a channel within a date range.
|
|
15615
|
+
* The date range must be within the same month.
|
|
15616
|
+
*
|
|
15617
|
+
* @param params - Query parameters
|
|
15618
|
+
* @returns Viewlog response with pagination
|
|
15619
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15620
|
+
*
|
|
15621
|
+
* @example
|
|
15622
|
+
* ```typescript
|
|
15623
|
+
* const result = await client.statistics.getViewlog({
|
|
15624
|
+
* channelId: '3151318',
|
|
15625
|
+
* startDate: '2024-01-01 00:00:00',
|
|
15626
|
+
* endDate: '2024-01-31 23:59:59',
|
|
15627
|
+
* });
|
|
15628
|
+
* console.log(result.contents);
|
|
15629
|
+
* ```
|
|
15630
|
+
*/
|
|
15631
|
+
async getViewlog(params) {
|
|
15632
|
+
this.validateGetViewlogParams(params);
|
|
15633
|
+
const requestParams = {
|
|
15634
|
+
channelId: params.channelId,
|
|
15635
|
+
startDate: params.startDate,
|
|
15636
|
+
endDate: params.endDate,
|
|
15637
|
+
pageSize: params.pageSize ?? 1e3
|
|
15638
|
+
};
|
|
15639
|
+
if (params.page !== void 0) {
|
|
15640
|
+
requestParams.page = params.page;
|
|
15641
|
+
}
|
|
15642
|
+
if (params.watchType !== void 0) {
|
|
15643
|
+
requestParams.watchType = params.watchType;
|
|
15644
|
+
}
|
|
15645
|
+
const response = await this.client.httpClient.get(
|
|
15646
|
+
"/live/v3/user/statistics/viewlog",
|
|
15647
|
+
{ params: requestParams }
|
|
15648
|
+
);
|
|
15649
|
+
if (response && typeof response === "object" && "data" in response) {
|
|
15650
|
+
const responseData = response;
|
|
15651
|
+
if (responseData.data && typeof responseData.data === "object") {
|
|
15652
|
+
return responseData.data;
|
|
15653
|
+
}
|
|
15654
|
+
}
|
|
15655
|
+
return response;
|
|
15656
|
+
}
|
|
15657
|
+
/**
|
|
15658
|
+
* Validate parameters for getViewlog
|
|
15659
|
+
*/
|
|
15660
|
+
validateGetViewlogParams(params) {
|
|
15661
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15662
|
+
throw new PolyVValidationError(
|
|
15663
|
+
"channelId is required and must be a non-empty string",
|
|
15664
|
+
"channelId",
|
|
15665
|
+
params.channelId
|
|
15666
|
+
);
|
|
15667
|
+
}
|
|
15668
|
+
const dateTimeRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
|
15669
|
+
if (!params.startDate || !dateTimeRegex.test(params.startDate)) {
|
|
15670
|
+
throw new PolyVValidationError(
|
|
15671
|
+
"startDate is required and must be in yyyy-MM-dd HH:mm:ss format",
|
|
15672
|
+
"startDate",
|
|
15673
|
+
params.startDate
|
|
15674
|
+
);
|
|
15675
|
+
}
|
|
15676
|
+
if (!params.endDate || !dateTimeRegex.test(params.endDate)) {
|
|
15677
|
+
throw new PolyVValidationError(
|
|
15678
|
+
"endDate is required and must be in yyyy-MM-dd HH:mm:ss format",
|
|
15679
|
+
"endDate",
|
|
15680
|
+
params.endDate
|
|
15681
|
+
);
|
|
15682
|
+
}
|
|
15683
|
+
const startMonth = params.startDate.substring(0, 7);
|
|
15684
|
+
const endMonth = params.endDate.substring(0, 7);
|
|
15685
|
+
if (startMonth !== endMonth) {
|
|
15686
|
+
throw new PolyVValidationError(
|
|
15687
|
+
"startDate and endDate must be in the same month",
|
|
15688
|
+
"dateRange",
|
|
15689
|
+
{ startDate: params.startDate, endDate: params.endDate }
|
|
15690
|
+
);
|
|
15691
|
+
}
|
|
15692
|
+
if (params.watchType !== void 0) {
|
|
15693
|
+
const validWatchTypes = ["live", "vod"];
|
|
15694
|
+
if (!validWatchTypes.includes(params.watchType)) {
|
|
15695
|
+
throw new PolyVValidationError(
|
|
15696
|
+
'watchType must be either "live" or "vod"',
|
|
15697
|
+
"watchType",
|
|
15698
|
+
params.watchType
|
|
15699
|
+
);
|
|
15700
|
+
}
|
|
15701
|
+
}
|
|
15702
|
+
}
|
|
15703
|
+
// ============================================
|
|
15704
|
+
// Session Stats Export API (Story 10.4)
|
|
15705
|
+
// ============================================
|
|
15706
|
+
/**
|
|
15707
|
+
* Export session statistics report
|
|
15708
|
+
*
|
|
15709
|
+
* Export the session statistics report for a specific session.
|
|
15710
|
+
* Returns a download URL for the report file.
|
|
15711
|
+
*
|
|
15712
|
+
* @param params - Query parameters
|
|
15713
|
+
* @returns Export response with download URL
|
|
15714
|
+
* @throws {PolyVValidationError} When parameters are invalid
|
|
15715
|
+
*
|
|
15716
|
+
* @example
|
|
15717
|
+
* ```typescript
|
|
15718
|
+
* const result = await client.statistics.exportSessionStats({
|
|
15719
|
+
* channelId: '3151318',
|
|
15720
|
+
* sessionId: 'fv3ma84e63',
|
|
15721
|
+
* });
|
|
15722
|
+
* console.log(result.downloadUrl);
|
|
15723
|
+
* ```
|
|
15724
|
+
*/
|
|
15725
|
+
async exportSessionStats(params) {
|
|
15726
|
+
this.validateExportSessionStatsParams(params);
|
|
15727
|
+
const response = await this.client.httpClient.get(
|
|
15728
|
+
"/live/v3/channel/session/stats/export",
|
|
15729
|
+
{ params }
|
|
15730
|
+
);
|
|
15731
|
+
if (response && typeof response === "object" && "data" in response) {
|
|
15732
|
+
const responseData = response;
|
|
15733
|
+
if (responseData.data && typeof responseData.data === "object") {
|
|
15734
|
+
const innerData = responseData.data;
|
|
15735
|
+
if (innerData.code && innerData.code !== 200) {
|
|
15736
|
+
throw new Error(innerData.message || "API Error");
|
|
15737
|
+
}
|
|
15738
|
+
if ("downloadUrl" in innerData) {
|
|
15739
|
+
return innerData;
|
|
15740
|
+
}
|
|
15741
|
+
if (typeof innerData.data === "string" && innerData.data) {
|
|
15742
|
+
return { downloadUrl: innerData.data };
|
|
15743
|
+
}
|
|
15744
|
+
}
|
|
15745
|
+
}
|
|
15746
|
+
if (response && typeof response === "object" && "code" in response) {
|
|
15747
|
+
const apiResponse = response;
|
|
15748
|
+
if (apiResponse.code && apiResponse.code !== 200) {
|
|
15749
|
+
throw new Error(String(apiResponse.message || "API Error"));
|
|
15750
|
+
}
|
|
15751
|
+
if (typeof apiResponse.data === "string" && apiResponse.data) {
|
|
15752
|
+
return { downloadUrl: apiResponse.data };
|
|
15753
|
+
}
|
|
15754
|
+
}
|
|
15755
|
+
return response;
|
|
15756
|
+
}
|
|
15757
|
+
/**
|
|
15758
|
+
* Validate parameters for exportSessionStats
|
|
15759
|
+
*/
|
|
15760
|
+
validateExportSessionStatsParams(params) {
|
|
15761
|
+
if (!params.channelId || typeof params.channelId !== "string" || params.channelId.trim() === "") {
|
|
15762
|
+
throw new PolyVValidationError(
|
|
15763
|
+
"channelId is required and must be a non-empty string",
|
|
15764
|
+
"channelId",
|
|
15765
|
+
params.channelId
|
|
15766
|
+
);
|
|
15767
|
+
}
|
|
15768
|
+
if (!params.sessionId || typeof params.sessionId !== "string" || params.sessionId.trim() === "") {
|
|
15769
|
+
throw new PolyVValidationError(
|
|
15770
|
+
"sessionId is required and must be a non-empty string",
|
|
15771
|
+
"sessionId",
|
|
15772
|
+
params.sessionId
|
|
15773
|
+
);
|
|
15774
|
+
}
|
|
15775
|
+
}
|
|
15776
|
+
};
|
|
15777
|
+
|
|
14842
15778
|
// src/client.ts
|
|
14843
15779
|
var DEFAULT_CONFIG = {
|
|
14844
15780
|
baseUrl: "https://api.polyv.net",
|
|
@@ -14862,6 +15798,10 @@ var PolyVClient = class {
|
|
|
14862
15798
|
* Channel service for managing live channels
|
|
14863
15799
|
*/
|
|
14864
15800
|
channel;
|
|
15801
|
+
/**
|
|
15802
|
+
* Statistics service for managing statistics operations
|
|
15803
|
+
*/
|
|
15804
|
+
statistics;
|
|
14865
15805
|
/**
|
|
14866
15806
|
* Chat service for managing chat messages
|
|
14867
15807
|
*/
|
|
@@ -14961,6 +15901,7 @@ var PolyVClient = class {
|
|
|
14961
15901
|
};
|
|
14962
15902
|
this.httpClient = this.createHttpClient();
|
|
14963
15903
|
this.channel = new ChannelService(this);
|
|
15904
|
+
this.statistics = new StatisticsService(this);
|
|
14964
15905
|
this.chat = new ChatService(this);
|
|
14965
15906
|
this.liveInteraction = new LiveInteractionService(this);
|
|
14966
15907
|
this.account = new AccountService(this);
|
|
@@ -15264,6 +16205,7 @@ exports.ChannelService = ChannelService;
|
|
|
15264
16205
|
exports.ERROR_CATEGORIES = ERROR_CATEGORIES;
|
|
15265
16206
|
exports.ERROR_MESSAGES = ERROR_MESSAGES;
|
|
15266
16207
|
exports.HttpMethod = HttpMethod;
|
|
16208
|
+
exports.MAX_DATE_RANGE_DAYS = MAX_DATE_RANGE_DAYS;
|
|
15267
16209
|
exports.PolyVAPIError = PolyVAPIError;
|
|
15268
16210
|
exports.PolyVClient = PolyVClient;
|
|
15269
16211
|
exports.PolyVError = PolyVError;
|
|
@@ -15288,8 +16230,11 @@ exports.isPolyVAPIError = isPolyVAPIError;
|
|
|
15288
16230
|
exports.isPolyVError = isPolyVError;
|
|
15289
16231
|
exports.isPolyVErrorCode = isPolyVErrorCode;
|
|
15290
16232
|
exports.isPolyVValidationError = isPolyVValidationError;
|
|
16233
|
+
exports.isStartDateBeforeEndDate = isStartDateBeforeEndDate;
|
|
16234
|
+
exports.isValidDateFormat = isValidDateFormat;
|
|
15291
16235
|
exports.isWebWorker = isWebWorker;
|
|
15292
16236
|
exports.paginate = paginate;
|
|
15293
16237
|
exports.sortParams = sortParams;
|
|
16238
|
+
exports.validateDateRange = validateDateRange;
|
|
15294
16239
|
//# sourceMappingURL=index.cjs.map
|
|
15295
16240
|
//# sourceMappingURL=index.cjs.map
|