@dracoonghost/trndup-sdk 1.3.24 → 1.3.26
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/index.d.mts +257 -0
- package/dist/index.d.ts +257 -0
- package/dist/index.js +56 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1401,6 +1401,259 @@ declare namespace Insights {
|
|
|
1401
1401
|
/** Days per comparison period (14-90, default: 30) */
|
|
1402
1402
|
period?: number;
|
|
1403
1403
|
}
|
|
1404
|
+
interface TopPostData {
|
|
1405
|
+
mediaId: string;
|
|
1406
|
+
caption: string | null;
|
|
1407
|
+
mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM' | 'REELS';
|
|
1408
|
+
thumbnailUrl: string | null;
|
|
1409
|
+
permalink: string;
|
|
1410
|
+
postedAt: string;
|
|
1411
|
+
ageInDays: number;
|
|
1412
|
+
}
|
|
1413
|
+
interface TopPostMetrics {
|
|
1414
|
+
reach: number;
|
|
1415
|
+
views: number;
|
|
1416
|
+
likes: number;
|
|
1417
|
+
comments: number;
|
|
1418
|
+
shares: number;
|
|
1419
|
+
saves: number;
|
|
1420
|
+
engagementRate: number;
|
|
1421
|
+
}
|
|
1422
|
+
interface TopPostComparison {
|
|
1423
|
+
vsAccountAverage: {
|
|
1424
|
+
reach: number;
|
|
1425
|
+
engagement: number;
|
|
1426
|
+
description: string;
|
|
1427
|
+
};
|
|
1428
|
+
standoutReasons: string[];
|
|
1429
|
+
}
|
|
1430
|
+
interface BestPerformingPostData {
|
|
1431
|
+
period: {
|
|
1432
|
+
start: string;
|
|
1433
|
+
end: string;
|
|
1434
|
+
days: number;
|
|
1435
|
+
};
|
|
1436
|
+
topPost: TopPostData;
|
|
1437
|
+
metrics: TopPostMetrics;
|
|
1438
|
+
comparison: TopPostComparison;
|
|
1439
|
+
insight: string;
|
|
1440
|
+
runnersUp: Array<{
|
|
1441
|
+
mediaId: string;
|
|
1442
|
+
caption: string | null;
|
|
1443
|
+
reach: number;
|
|
1444
|
+
thumbnailUrl: string | null;
|
|
1445
|
+
}>;
|
|
1446
|
+
}
|
|
1447
|
+
type BestPerformingPostResponse = InsufficientDataResponse | {
|
|
1448
|
+
hasData: true;
|
|
1449
|
+
data: BestPerformingPostData;
|
|
1450
|
+
_meta: InsightMeta;
|
|
1451
|
+
};
|
|
1452
|
+
type PostingConsistencyStatus = 'excellent' | 'good' | 'needs_improvement' | 'poor' | 'inactive';
|
|
1453
|
+
interface MonthlyPostData {
|
|
1454
|
+
month: string;
|
|
1455
|
+
posts: number;
|
|
1456
|
+
avgGap: number | null;
|
|
1457
|
+
}
|
|
1458
|
+
interface PostingConsistencyData {
|
|
1459
|
+
period: {
|
|
1460
|
+
start: string;
|
|
1461
|
+
end: string;
|
|
1462
|
+
days: number;
|
|
1463
|
+
};
|
|
1464
|
+
consistencyScore: number;
|
|
1465
|
+
status: PostingConsistencyStatus;
|
|
1466
|
+
metrics: {
|
|
1467
|
+
totalPosts: number;
|
|
1468
|
+
avgDaysBetweenPosts: number;
|
|
1469
|
+
postVariance: number;
|
|
1470
|
+
daysSinceLastPost: number;
|
|
1471
|
+
lastPostDate: string | null;
|
|
1472
|
+
};
|
|
1473
|
+
pattern: {
|
|
1474
|
+
isRegular: boolean;
|
|
1475
|
+
typicalGap: string;
|
|
1476
|
+
longestStreak: number;
|
|
1477
|
+
currentStreak: number;
|
|
1478
|
+
trend: 'increasing' | 'stable' | 'decreasing';
|
|
1479
|
+
trendDescription: string;
|
|
1480
|
+
};
|
|
1481
|
+
monthlyBreakdown: MonthlyPostData[];
|
|
1482
|
+
recommendation: {
|
|
1483
|
+
suggested: string;
|
|
1484
|
+
current: string;
|
|
1485
|
+
reason: string;
|
|
1486
|
+
};
|
|
1487
|
+
insight: string;
|
|
1488
|
+
recommendations: string[];
|
|
1489
|
+
}
|
|
1490
|
+
type PostingConsistencyResponse = InsufficientDataResponse | {
|
|
1491
|
+
hasData: true;
|
|
1492
|
+
data: PostingConsistencyData;
|
|
1493
|
+
_meta: InsightMeta;
|
|
1494
|
+
};
|
|
1495
|
+
type FollowerQualityLabel = 'excellent' | 'good' | 'fair' | 'needs_attention' | 'concerning';
|
|
1496
|
+
interface FollowerQualityData {
|
|
1497
|
+
period: {
|
|
1498
|
+
start: string;
|
|
1499
|
+
end: string;
|
|
1500
|
+
days: number;
|
|
1501
|
+
};
|
|
1502
|
+
qualityScore: number;
|
|
1503
|
+
scoreLabel: FollowerQualityLabel;
|
|
1504
|
+
metrics: {
|
|
1505
|
+
followsGained: number;
|
|
1506
|
+
unfollows: number;
|
|
1507
|
+
netFollowers: number;
|
|
1508
|
+
retentionRate: number;
|
|
1509
|
+
engagementPerFollower: number;
|
|
1510
|
+
reachPerFollower: number;
|
|
1511
|
+
accountsEngaged: number;
|
|
1512
|
+
};
|
|
1513
|
+
trend: {
|
|
1514
|
+
scoreChange: number;
|
|
1515
|
+
direction: 'improving' | 'stable' | 'declining';
|
|
1516
|
+
description: string;
|
|
1517
|
+
};
|
|
1518
|
+
insight: string;
|
|
1519
|
+
recommendations: string[];
|
|
1520
|
+
}
|
|
1521
|
+
type FollowerQualityResponse = InsufficientDataResponse | {
|
|
1522
|
+
hasData: true;
|
|
1523
|
+
data: FollowerQualityData;
|
|
1524
|
+
_meta: InsightMeta;
|
|
1525
|
+
};
|
|
1526
|
+
type InstagramMomentumStatus = 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping';
|
|
1527
|
+
type InstagramMomentumTrend = 'accelerating' | 'stable' | 'decelerating';
|
|
1528
|
+
interface InstagramMetricChange {
|
|
1529
|
+
current: number;
|
|
1530
|
+
previous: number;
|
|
1531
|
+
change: number;
|
|
1532
|
+
}
|
|
1533
|
+
interface InstagramMomentumData {
|
|
1534
|
+
score: number;
|
|
1535
|
+
rawChange: number;
|
|
1536
|
+
status: InstagramMomentumStatus;
|
|
1537
|
+
trend: InstagramMomentumTrend;
|
|
1538
|
+
previousScore: number | null;
|
|
1539
|
+
period: {
|
|
1540
|
+
current: {
|
|
1541
|
+
start: string;
|
|
1542
|
+
end: string;
|
|
1543
|
+
};
|
|
1544
|
+
previous: {
|
|
1545
|
+
start: string;
|
|
1546
|
+
end: string;
|
|
1547
|
+
};
|
|
1548
|
+
};
|
|
1549
|
+
breakdown: {
|
|
1550
|
+
reach: InstagramMetricChange;
|
|
1551
|
+
engagement: InstagramMetricChange;
|
|
1552
|
+
followers: InstagramMetricChange;
|
|
1553
|
+
profileViews: InstagramMetricChange;
|
|
1554
|
+
};
|
|
1555
|
+
insight: string;
|
|
1556
|
+
topDrivers: string[];
|
|
1557
|
+
}
|
|
1558
|
+
type InstagramMomentumResponse = InsufficientDataResponse | {
|
|
1559
|
+
hasData: true;
|
|
1560
|
+
data: InstagramMomentumData;
|
|
1561
|
+
_meta: InsightMeta;
|
|
1562
|
+
};
|
|
1563
|
+
type EngagementStyle = 'passive' | 'active' | 'viral' | 'valuable';
|
|
1564
|
+
interface EngagementMetricBreakdown {
|
|
1565
|
+
count: number;
|
|
1566
|
+
percent: number;
|
|
1567
|
+
trend: number;
|
|
1568
|
+
}
|
|
1569
|
+
interface EngagementBreakdownData {
|
|
1570
|
+
period: {
|
|
1571
|
+
start: string;
|
|
1572
|
+
end: string;
|
|
1573
|
+
days: number;
|
|
1574
|
+
};
|
|
1575
|
+
totalEngagement: number;
|
|
1576
|
+
breakdown: {
|
|
1577
|
+
likes: EngagementMetricBreakdown;
|
|
1578
|
+
comments: EngagementMetricBreakdown;
|
|
1579
|
+
shares: EngagementMetricBreakdown;
|
|
1580
|
+
saves: EngagementMetricBreakdown;
|
|
1581
|
+
};
|
|
1582
|
+
engagementStyle: EngagementStyle;
|
|
1583
|
+
analysis: {
|
|
1584
|
+
strongestType: string;
|
|
1585
|
+
weakestType: string;
|
|
1586
|
+
opportunity: string;
|
|
1587
|
+
};
|
|
1588
|
+
insight: string;
|
|
1589
|
+
recommendations: string[];
|
|
1590
|
+
}
|
|
1591
|
+
type EngagementBreakdownResponse = InsufficientDataResponse | {
|
|
1592
|
+
hasData: true;
|
|
1593
|
+
data: EngagementBreakdownData;
|
|
1594
|
+
_meta: InsightMeta;
|
|
1595
|
+
};
|
|
1596
|
+
type InstagramHealthLabel = 'excellent' | 'good' | 'fair' | 'needs_attention' | 'poor';
|
|
1597
|
+
interface HealthScoreComponent {
|
|
1598
|
+
score: number;
|
|
1599
|
+
label: string;
|
|
1600
|
+
trend: number;
|
|
1601
|
+
}
|
|
1602
|
+
interface InstagramHealthScoreData {
|
|
1603
|
+
period: {
|
|
1604
|
+
start: string;
|
|
1605
|
+
end: string;
|
|
1606
|
+
days: number;
|
|
1607
|
+
};
|
|
1608
|
+
overall: number;
|
|
1609
|
+
label: InstagramHealthLabel;
|
|
1610
|
+
components: {
|
|
1611
|
+
consistency: HealthScoreComponent;
|
|
1612
|
+
engagement: HealthScoreComponent;
|
|
1613
|
+
growth: HealthScoreComponent;
|
|
1614
|
+
reach: HealthScoreComponent;
|
|
1615
|
+
};
|
|
1616
|
+
metrics: {
|
|
1617
|
+
postsPerWeek: number;
|
|
1618
|
+
avgEngagementRate: number;
|
|
1619
|
+
followerGrowthRate: number;
|
|
1620
|
+
avgReachPerPost: number;
|
|
1621
|
+
};
|
|
1622
|
+
percentageChanges: {
|
|
1623
|
+
overall: number;
|
|
1624
|
+
components: {
|
|
1625
|
+
consistency: number;
|
|
1626
|
+
engagement: number;
|
|
1627
|
+
growth: number;
|
|
1628
|
+
reach: number;
|
|
1629
|
+
};
|
|
1630
|
+
};
|
|
1631
|
+
insight: string;
|
|
1632
|
+
recommendations: string[];
|
|
1633
|
+
}
|
|
1634
|
+
type InstagramHealthScoreResponse = InsufficientDataResponse | {
|
|
1635
|
+
hasData: true;
|
|
1636
|
+
data: InstagramHealthScoreData;
|
|
1637
|
+
_meta: InsightMeta;
|
|
1638
|
+
};
|
|
1639
|
+
interface InstagramAllInsightsData {
|
|
1640
|
+
bestPost: BestPerformingPostResponse;
|
|
1641
|
+
consistency: PostingConsistencyResponse;
|
|
1642
|
+
followerQuality: FollowerQualityResponse;
|
|
1643
|
+
momentum: InstagramMomentumResponse;
|
|
1644
|
+
engagement: EngagementBreakdownResponse;
|
|
1645
|
+
health: InstagramHealthScoreResponse;
|
|
1646
|
+
}
|
|
1647
|
+
interface InstagramAllInsightsResponse {
|
|
1648
|
+
data: InstagramAllInsightsData;
|
|
1649
|
+
meta: {
|
|
1650
|
+
available: string[];
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
interface GetInstagramInsightParams {
|
|
1654
|
+
/** Time range (e.g., "30d") */
|
|
1655
|
+
range?: string;
|
|
1656
|
+
}
|
|
1404
1657
|
}
|
|
1405
1658
|
declare namespace Activity {
|
|
1406
1659
|
/**
|
|
@@ -1566,6 +1819,10 @@ declare class TrndUpClient {
|
|
|
1566
1819
|
patch<T = unknown>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
1567
1820
|
delete<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
1568
1821
|
private request;
|
|
1822
|
+
private logRequest;
|
|
1823
|
+
private logResponse;
|
|
1824
|
+
private logError;
|
|
1825
|
+
private truncateObject;
|
|
1569
1826
|
private buildUrl;
|
|
1570
1827
|
private buildHeaders;
|
|
1571
1828
|
private handleResponse;
|
package/dist/index.d.ts
CHANGED
|
@@ -1401,6 +1401,259 @@ declare namespace Insights {
|
|
|
1401
1401
|
/** Days per comparison period (14-90, default: 30) */
|
|
1402
1402
|
period?: number;
|
|
1403
1403
|
}
|
|
1404
|
+
interface TopPostData {
|
|
1405
|
+
mediaId: string;
|
|
1406
|
+
caption: string | null;
|
|
1407
|
+
mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM' | 'REELS';
|
|
1408
|
+
thumbnailUrl: string | null;
|
|
1409
|
+
permalink: string;
|
|
1410
|
+
postedAt: string;
|
|
1411
|
+
ageInDays: number;
|
|
1412
|
+
}
|
|
1413
|
+
interface TopPostMetrics {
|
|
1414
|
+
reach: number;
|
|
1415
|
+
views: number;
|
|
1416
|
+
likes: number;
|
|
1417
|
+
comments: number;
|
|
1418
|
+
shares: number;
|
|
1419
|
+
saves: number;
|
|
1420
|
+
engagementRate: number;
|
|
1421
|
+
}
|
|
1422
|
+
interface TopPostComparison {
|
|
1423
|
+
vsAccountAverage: {
|
|
1424
|
+
reach: number;
|
|
1425
|
+
engagement: number;
|
|
1426
|
+
description: string;
|
|
1427
|
+
};
|
|
1428
|
+
standoutReasons: string[];
|
|
1429
|
+
}
|
|
1430
|
+
interface BestPerformingPostData {
|
|
1431
|
+
period: {
|
|
1432
|
+
start: string;
|
|
1433
|
+
end: string;
|
|
1434
|
+
days: number;
|
|
1435
|
+
};
|
|
1436
|
+
topPost: TopPostData;
|
|
1437
|
+
metrics: TopPostMetrics;
|
|
1438
|
+
comparison: TopPostComparison;
|
|
1439
|
+
insight: string;
|
|
1440
|
+
runnersUp: Array<{
|
|
1441
|
+
mediaId: string;
|
|
1442
|
+
caption: string | null;
|
|
1443
|
+
reach: number;
|
|
1444
|
+
thumbnailUrl: string | null;
|
|
1445
|
+
}>;
|
|
1446
|
+
}
|
|
1447
|
+
type BestPerformingPostResponse = InsufficientDataResponse | {
|
|
1448
|
+
hasData: true;
|
|
1449
|
+
data: BestPerformingPostData;
|
|
1450
|
+
_meta: InsightMeta;
|
|
1451
|
+
};
|
|
1452
|
+
type PostingConsistencyStatus = 'excellent' | 'good' | 'needs_improvement' | 'poor' | 'inactive';
|
|
1453
|
+
interface MonthlyPostData {
|
|
1454
|
+
month: string;
|
|
1455
|
+
posts: number;
|
|
1456
|
+
avgGap: number | null;
|
|
1457
|
+
}
|
|
1458
|
+
interface PostingConsistencyData {
|
|
1459
|
+
period: {
|
|
1460
|
+
start: string;
|
|
1461
|
+
end: string;
|
|
1462
|
+
days: number;
|
|
1463
|
+
};
|
|
1464
|
+
consistencyScore: number;
|
|
1465
|
+
status: PostingConsistencyStatus;
|
|
1466
|
+
metrics: {
|
|
1467
|
+
totalPosts: number;
|
|
1468
|
+
avgDaysBetweenPosts: number;
|
|
1469
|
+
postVariance: number;
|
|
1470
|
+
daysSinceLastPost: number;
|
|
1471
|
+
lastPostDate: string | null;
|
|
1472
|
+
};
|
|
1473
|
+
pattern: {
|
|
1474
|
+
isRegular: boolean;
|
|
1475
|
+
typicalGap: string;
|
|
1476
|
+
longestStreak: number;
|
|
1477
|
+
currentStreak: number;
|
|
1478
|
+
trend: 'increasing' | 'stable' | 'decreasing';
|
|
1479
|
+
trendDescription: string;
|
|
1480
|
+
};
|
|
1481
|
+
monthlyBreakdown: MonthlyPostData[];
|
|
1482
|
+
recommendation: {
|
|
1483
|
+
suggested: string;
|
|
1484
|
+
current: string;
|
|
1485
|
+
reason: string;
|
|
1486
|
+
};
|
|
1487
|
+
insight: string;
|
|
1488
|
+
recommendations: string[];
|
|
1489
|
+
}
|
|
1490
|
+
type PostingConsistencyResponse = InsufficientDataResponse | {
|
|
1491
|
+
hasData: true;
|
|
1492
|
+
data: PostingConsistencyData;
|
|
1493
|
+
_meta: InsightMeta;
|
|
1494
|
+
};
|
|
1495
|
+
type FollowerQualityLabel = 'excellent' | 'good' | 'fair' | 'needs_attention' | 'concerning';
|
|
1496
|
+
interface FollowerQualityData {
|
|
1497
|
+
period: {
|
|
1498
|
+
start: string;
|
|
1499
|
+
end: string;
|
|
1500
|
+
days: number;
|
|
1501
|
+
};
|
|
1502
|
+
qualityScore: number;
|
|
1503
|
+
scoreLabel: FollowerQualityLabel;
|
|
1504
|
+
metrics: {
|
|
1505
|
+
followsGained: number;
|
|
1506
|
+
unfollows: number;
|
|
1507
|
+
netFollowers: number;
|
|
1508
|
+
retentionRate: number;
|
|
1509
|
+
engagementPerFollower: number;
|
|
1510
|
+
reachPerFollower: number;
|
|
1511
|
+
accountsEngaged: number;
|
|
1512
|
+
};
|
|
1513
|
+
trend: {
|
|
1514
|
+
scoreChange: number;
|
|
1515
|
+
direction: 'improving' | 'stable' | 'declining';
|
|
1516
|
+
description: string;
|
|
1517
|
+
};
|
|
1518
|
+
insight: string;
|
|
1519
|
+
recommendations: string[];
|
|
1520
|
+
}
|
|
1521
|
+
type FollowerQualityResponse = InsufficientDataResponse | {
|
|
1522
|
+
hasData: true;
|
|
1523
|
+
data: FollowerQualityData;
|
|
1524
|
+
_meta: InsightMeta;
|
|
1525
|
+
};
|
|
1526
|
+
type InstagramMomentumStatus = 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping';
|
|
1527
|
+
type InstagramMomentumTrend = 'accelerating' | 'stable' | 'decelerating';
|
|
1528
|
+
interface InstagramMetricChange {
|
|
1529
|
+
current: number;
|
|
1530
|
+
previous: number;
|
|
1531
|
+
change: number;
|
|
1532
|
+
}
|
|
1533
|
+
interface InstagramMomentumData {
|
|
1534
|
+
score: number;
|
|
1535
|
+
rawChange: number;
|
|
1536
|
+
status: InstagramMomentumStatus;
|
|
1537
|
+
trend: InstagramMomentumTrend;
|
|
1538
|
+
previousScore: number | null;
|
|
1539
|
+
period: {
|
|
1540
|
+
current: {
|
|
1541
|
+
start: string;
|
|
1542
|
+
end: string;
|
|
1543
|
+
};
|
|
1544
|
+
previous: {
|
|
1545
|
+
start: string;
|
|
1546
|
+
end: string;
|
|
1547
|
+
};
|
|
1548
|
+
};
|
|
1549
|
+
breakdown: {
|
|
1550
|
+
reach: InstagramMetricChange;
|
|
1551
|
+
engagement: InstagramMetricChange;
|
|
1552
|
+
followers: InstagramMetricChange;
|
|
1553
|
+
profileViews: InstagramMetricChange;
|
|
1554
|
+
};
|
|
1555
|
+
insight: string;
|
|
1556
|
+
topDrivers: string[];
|
|
1557
|
+
}
|
|
1558
|
+
type InstagramMomentumResponse = InsufficientDataResponse | {
|
|
1559
|
+
hasData: true;
|
|
1560
|
+
data: InstagramMomentumData;
|
|
1561
|
+
_meta: InsightMeta;
|
|
1562
|
+
};
|
|
1563
|
+
type EngagementStyle = 'passive' | 'active' | 'viral' | 'valuable';
|
|
1564
|
+
interface EngagementMetricBreakdown {
|
|
1565
|
+
count: number;
|
|
1566
|
+
percent: number;
|
|
1567
|
+
trend: number;
|
|
1568
|
+
}
|
|
1569
|
+
interface EngagementBreakdownData {
|
|
1570
|
+
period: {
|
|
1571
|
+
start: string;
|
|
1572
|
+
end: string;
|
|
1573
|
+
days: number;
|
|
1574
|
+
};
|
|
1575
|
+
totalEngagement: number;
|
|
1576
|
+
breakdown: {
|
|
1577
|
+
likes: EngagementMetricBreakdown;
|
|
1578
|
+
comments: EngagementMetricBreakdown;
|
|
1579
|
+
shares: EngagementMetricBreakdown;
|
|
1580
|
+
saves: EngagementMetricBreakdown;
|
|
1581
|
+
};
|
|
1582
|
+
engagementStyle: EngagementStyle;
|
|
1583
|
+
analysis: {
|
|
1584
|
+
strongestType: string;
|
|
1585
|
+
weakestType: string;
|
|
1586
|
+
opportunity: string;
|
|
1587
|
+
};
|
|
1588
|
+
insight: string;
|
|
1589
|
+
recommendations: string[];
|
|
1590
|
+
}
|
|
1591
|
+
type EngagementBreakdownResponse = InsufficientDataResponse | {
|
|
1592
|
+
hasData: true;
|
|
1593
|
+
data: EngagementBreakdownData;
|
|
1594
|
+
_meta: InsightMeta;
|
|
1595
|
+
};
|
|
1596
|
+
type InstagramHealthLabel = 'excellent' | 'good' | 'fair' | 'needs_attention' | 'poor';
|
|
1597
|
+
interface HealthScoreComponent {
|
|
1598
|
+
score: number;
|
|
1599
|
+
label: string;
|
|
1600
|
+
trend: number;
|
|
1601
|
+
}
|
|
1602
|
+
interface InstagramHealthScoreData {
|
|
1603
|
+
period: {
|
|
1604
|
+
start: string;
|
|
1605
|
+
end: string;
|
|
1606
|
+
days: number;
|
|
1607
|
+
};
|
|
1608
|
+
overall: number;
|
|
1609
|
+
label: InstagramHealthLabel;
|
|
1610
|
+
components: {
|
|
1611
|
+
consistency: HealthScoreComponent;
|
|
1612
|
+
engagement: HealthScoreComponent;
|
|
1613
|
+
growth: HealthScoreComponent;
|
|
1614
|
+
reach: HealthScoreComponent;
|
|
1615
|
+
};
|
|
1616
|
+
metrics: {
|
|
1617
|
+
postsPerWeek: number;
|
|
1618
|
+
avgEngagementRate: number;
|
|
1619
|
+
followerGrowthRate: number;
|
|
1620
|
+
avgReachPerPost: number;
|
|
1621
|
+
};
|
|
1622
|
+
percentageChanges: {
|
|
1623
|
+
overall: number;
|
|
1624
|
+
components: {
|
|
1625
|
+
consistency: number;
|
|
1626
|
+
engagement: number;
|
|
1627
|
+
growth: number;
|
|
1628
|
+
reach: number;
|
|
1629
|
+
};
|
|
1630
|
+
};
|
|
1631
|
+
insight: string;
|
|
1632
|
+
recommendations: string[];
|
|
1633
|
+
}
|
|
1634
|
+
type InstagramHealthScoreResponse = InsufficientDataResponse | {
|
|
1635
|
+
hasData: true;
|
|
1636
|
+
data: InstagramHealthScoreData;
|
|
1637
|
+
_meta: InsightMeta;
|
|
1638
|
+
};
|
|
1639
|
+
interface InstagramAllInsightsData {
|
|
1640
|
+
bestPost: BestPerformingPostResponse;
|
|
1641
|
+
consistency: PostingConsistencyResponse;
|
|
1642
|
+
followerQuality: FollowerQualityResponse;
|
|
1643
|
+
momentum: InstagramMomentumResponse;
|
|
1644
|
+
engagement: EngagementBreakdownResponse;
|
|
1645
|
+
health: InstagramHealthScoreResponse;
|
|
1646
|
+
}
|
|
1647
|
+
interface InstagramAllInsightsResponse {
|
|
1648
|
+
data: InstagramAllInsightsData;
|
|
1649
|
+
meta: {
|
|
1650
|
+
available: string[];
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
interface GetInstagramInsightParams {
|
|
1654
|
+
/** Time range (e.g., "30d") */
|
|
1655
|
+
range?: string;
|
|
1656
|
+
}
|
|
1404
1657
|
}
|
|
1405
1658
|
declare namespace Activity {
|
|
1406
1659
|
/**
|
|
@@ -1566,6 +1819,10 @@ declare class TrndUpClient {
|
|
|
1566
1819
|
patch<T = unknown>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
1567
1820
|
delete<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
1568
1821
|
private request;
|
|
1822
|
+
private logRequest;
|
|
1823
|
+
private logResponse;
|
|
1824
|
+
private logError;
|
|
1825
|
+
private truncateObject;
|
|
1569
1826
|
private buildUrl;
|
|
1570
1827
|
private buildHeaders;
|
|
1571
1828
|
private handleResponse;
|
package/dist/index.js
CHANGED
|
@@ -83,19 +83,27 @@ var TrndUpClient = class {
|
|
|
83
83
|
() => controller.abort(),
|
|
84
84
|
timeout ?? this.config.timeout
|
|
85
85
|
);
|
|
86
|
+
const startTime = Date.now();
|
|
86
87
|
try {
|
|
87
88
|
if (this.config.debug) {
|
|
88
|
-
|
|
89
|
+
this.logRequest(method, url, body);
|
|
89
90
|
}
|
|
90
91
|
const response = await fetch(url, {
|
|
91
92
|
...init,
|
|
92
93
|
signal: signal ?? controller.signal
|
|
93
94
|
});
|
|
94
95
|
clearTimeout(timeoutId);
|
|
95
|
-
|
|
96
|
+
const result = await this.handleResponse(response, path);
|
|
97
|
+
if (this.config.debug) {
|
|
98
|
+
this.logResponse(method, path, response.status, result, startTime);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
96
101
|
} catch (error) {
|
|
97
102
|
clearTimeout(timeoutId);
|
|
98
103
|
if (error instanceof TrndUpApiError) {
|
|
104
|
+
if (this.config.debug) {
|
|
105
|
+
this.logError(method, path, error, startTime);
|
|
106
|
+
}
|
|
99
107
|
throw error;
|
|
100
108
|
}
|
|
101
109
|
const networkError = new TrndUpNetworkError(
|
|
@@ -103,11 +111,56 @@ var TrndUpClient = class {
|
|
|
103
111
|
path
|
|
104
112
|
);
|
|
105
113
|
if (this.config.debug) {
|
|
106
|
-
|
|
114
|
+
this.logError(method, path, networkError, startTime);
|
|
107
115
|
}
|
|
108
116
|
throw networkError;
|
|
109
117
|
}
|
|
110
118
|
}
|
|
119
|
+
// =============================================================================
|
|
120
|
+
// LOGGING HELPERS
|
|
121
|
+
// =============================================================================
|
|
122
|
+
logRequest(method, url, body) {
|
|
123
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[1].slice(0, 12);
|
|
124
|
+
const bodyPreview = body ? this.truncateObject(body, 200) : void 0;
|
|
125
|
+
console.log(
|
|
126
|
+
`\x1B[36m[${timestamp}]\x1B[0m \x1B[33m\u2192 ${method}\x1B[0m ${url}` + (bodyPreview ? `
|
|
127
|
+
\x1B[90mbody:\x1B[0m ${bodyPreview}` : "")
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
logResponse(method, path, status, data, startTime) {
|
|
131
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[1].slice(0, 12);
|
|
132
|
+
const duration = Date.now() - startTime;
|
|
133
|
+
const statusColor = status >= 200 && status < 300 ? "\x1B[32m" : "\x1B[31m";
|
|
134
|
+
const dataPreview = this.truncateObject(data, 300);
|
|
135
|
+
console.log(
|
|
136
|
+
`\x1B[36m[${timestamp}]\x1B[0m ${statusColor}\u2190 ${status}\x1B[0m ${method} ${path} \x1B[90m(${duration}ms)\x1B[0m
|
|
137
|
+
\x1B[90mdata:\x1B[0m ${dataPreview}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
logError(method, path, error, startTime) {
|
|
141
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[1].slice(0, 12);
|
|
142
|
+
const duration = Date.now() - startTime;
|
|
143
|
+
if (error instanceof TrndUpApiError) {
|
|
144
|
+
console.log(
|
|
145
|
+
`\x1B[36m[${timestamp}]\x1B[0m \x1B[31m\u2715 ${error.status}\x1B[0m ${method} ${path} \x1B[90m(${duration}ms)\x1B[0m
|
|
146
|
+
\x1B[31merror:\x1B[0m ${error.code || "UNKNOWN"} - ${error.message}`
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
console.log(
|
|
150
|
+
`\x1B[36m[${timestamp}]\x1B[0m \x1B[31m\u2715 NETWORK\x1B[0m ${method} ${path} \x1B[90m(${duration}ms)\x1B[0m
|
|
151
|
+
\x1B[31merror:\x1B[0m ${error.message}`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
truncateObject(obj, maxLength) {
|
|
156
|
+
try {
|
|
157
|
+
const str = JSON.stringify(obj);
|
|
158
|
+
if (str.length <= maxLength) return str;
|
|
159
|
+
return str.slice(0, maxLength) + "...";
|
|
160
|
+
} catch {
|
|
161
|
+
return "[Unable to serialize]";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
111
164
|
buildUrl(path, params) {
|
|
112
165
|
const url = new URL(`${this.config.baseUrl}${path}`);
|
|
113
166
|
if (params) {
|
|
@@ -164,9 +217,6 @@ var TrndUpClient = class {
|
|
|
164
217
|
if (apiError.isAuthError() && this.config.onAuthFailure) {
|
|
165
218
|
await this.config.onAuthFailure();
|
|
166
219
|
}
|
|
167
|
-
if (this.config.debug) {
|
|
168
|
-
console.error("[TrndUp SDK] API error:", apiError);
|
|
169
|
-
}
|
|
170
220
|
throw apiError;
|
|
171
221
|
}
|
|
172
222
|
if (isJson) {
|