@dracoonghost/trndup-sdk 1.3.13 → 1.3.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.
package/README.md CHANGED
@@ -8,13 +8,13 @@ Official TypeScript SDK for the TrndUp API with Firebase authentication support.
8
8
  # In your mobile app
9
9
  npm install file:../trndup-service/src/sdk
10
10
  # or when published
11
- npm install @trndup/sdk
11
+ npm install @dracoonghost/trndup-sdk
12
12
  ```
13
13
 
14
14
  ## Quick Start
15
15
 
16
16
  ```typescript
17
- import { TrndUpSDK } from '@trndup/sdk';
17
+ import { TrndUpSDK } from '@dracoonghost/trndup-sdk';
18
18
  import auth from '@react-native-firebase/auth';
19
19
 
20
20
  // Initialize SDK
@@ -132,7 +132,7 @@ const trending = await sdk.insights.getTrending();
132
132
  ## Error Handling
133
133
 
134
134
  ```typescript
135
- import { TrndUpApiError, TrndUpNetworkError } from '@trndup/sdk';
135
+ import { TrndUpApiError, TrndUpNetworkError } from '@dracoonghost/trndup-sdk';
136
136
 
137
137
  try {
138
138
  await sdk.youtube.getVideos();
@@ -191,7 +191,7 @@ interface TrndUpClientConfig {
191
191
  The SDK is fully typed with TypeScript. All request/response types are available:
192
192
 
193
193
  ```typescript
194
- import type { Auth, YouTube, Instagram, Social, Insights } from '@trndup/sdk';
194
+ import type { Auth, YouTube, Instagram, Social, Insights } from '@dracoonghost/trndup-sdk';
195
195
 
196
196
  // Use types in your code
197
197
  const user: Auth.User = await sdk.auth.getCurrentUser();
@@ -216,7 +216,7 @@ npm run type-check
216
216
  npm link
217
217
 
218
218
  # In your mobile app
219
- npm link @trndup/sdk
219
+ npm link @dracoonghost/trndup-sdk
220
220
  ```
221
221
 
222
222
  ## License
package/dist/index.d.mts CHANGED
@@ -10,7 +10,7 @@
10
10
  * @example
11
11
  * ```typescript
12
12
  * import { GoogleSignin } from '@react-native-google-signin/google-signin';
13
- * import { YOUTUBE_SCOPES } from '@trndup/sdk';
13
+ * import { YOUTUBE_SCOPES } from '@dracoonghost/trndup-sdk';
14
14
  *
15
15
  * GoogleSignin.configure({
16
16
  * webClientId: 'YOUR_WEB_CLIENT_ID',
@@ -297,11 +297,6 @@ declare namespace YouTube {
297
297
  * const videos = await client.youtube.getVideos();
298
298
  * localStorage.set('videosLastSync', status.data.syncs.videos.lastSyncAt);
299
299
  * }
300
- *
301
- * // Show user that refresh is happening
302
- * if (status.data.summary.anyInProgress) {
303
- * showRefreshIndicator();
304
- * }
305
300
  * ```
306
301
  */
307
302
  interface UnifiedSyncStatusResponse {
@@ -324,17 +319,6 @@ declare namespace YouTube {
324
319
  /** Video analytics (per-video metrics) */
325
320
  videoAnalytics: SyncTypeStatus;
326
321
  };
327
- /** Summary flags for quick checks */
328
- summary: {
329
- /** All sync types completed at least once with data */
330
- allSynced: boolean;
331
- /** At least one sync type is older than its refresh interval */
332
- anyStale: boolean;
333
- /** At least one sync type failed */
334
- anyFailed: boolean;
335
- /** At least one sync is currently in progress */
336
- anyInProgress: boolean;
337
- };
338
322
  }
339
323
  /**
340
324
  * Response from GET /v1/platforms/youtube/analytics/channel/sync/status
@@ -503,6 +487,109 @@ declare namespace Insights {
503
487
  youtube?: YouTube.Video[];
504
488
  instagram?: Instagram.Post[];
505
489
  }
490
+ /** Momentum status labels */
491
+ type MomentumStatusLabel = 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping';
492
+ /** Momentum trend direction */
493
+ type MomentumTrend = 'accelerating' | 'holding' | 'decelerating';
494
+ /**
495
+ * Metric breakdown showing current vs previous period
496
+ */
497
+ interface MetricComparison {
498
+ /** Current period value */
499
+ current: number;
500
+ /** Previous period value */
501
+ previous: number;
502
+ /** Percentage change (-100 to +100+) */
503
+ change: number;
504
+ }
505
+ /**
506
+ * Momentum Status Response
507
+ *
508
+ * Provides a 0-100 score indicating channel momentum:
509
+ * - 50 = Steady (no change week over week)
510
+ * - 0 = Severe decline (-100% or worse)
511
+ * - 100 = Explosive growth (+100% or better)
512
+ *
513
+ * Status labels:
514
+ * - 80-100: Surging 🚀
515
+ * - 60-79: Rising 📈
516
+ * - 40-59: Steady ➡️
517
+ * - 20-39: Cooling 📉
518
+ * - 0-19: Dropping 🔻
519
+ */
520
+ interface MomentumStatusResponse {
521
+ /** Normalized score 0-100 (50 = no change) */
522
+ score: number;
523
+ /** Raw weighted average change before normalization */
524
+ rawChange: number;
525
+ /** Human-friendly status label */
526
+ status: MomentumStatusLabel;
527
+ /** Trend direction compared to previous period */
528
+ trend: MomentumTrend;
529
+ /** Previous period's score (null if first calculation) */
530
+ previousScore: number | null;
531
+ /** Time periods being compared */
532
+ period: {
533
+ current: {
534
+ start: string;
535
+ end: string;
536
+ };
537
+ previous: {
538
+ start: string;
539
+ end: string;
540
+ };
541
+ };
542
+ /** Breakdown of individual metrics */
543
+ breakdown: {
544
+ views: MetricComparison;
545
+ engagement: MetricComparison;
546
+ watchTime: MetricComparison;
547
+ subscribers: MetricComparison;
548
+ };
549
+ /** Weights used in calculation */
550
+ weights: {
551
+ views: number;
552
+ engagement: number;
553
+ watchTime: number;
554
+ subscribers: number;
555
+ };
556
+ /** Human-readable insight summary */
557
+ insight: string;
558
+ /** Cache metadata */
559
+ _meta?: {
560
+ fromCache: boolean;
561
+ refreshed?: boolean;
562
+ cacheValidFor: string;
563
+ algorithmVersion: string;
564
+ };
565
+ }
566
+ /**
567
+ * Single history point for momentum graphing
568
+ */
569
+ interface MomentumHistoryPoint {
570
+ /** Date (YYYY-MM-DD) */
571
+ date: string;
572
+ /** Momentum score at that time */
573
+ score: number;
574
+ /** Status label at that time */
575
+ status: MomentumStatusLabel;
576
+ }
577
+ /**
578
+ * Momentum history response for graphing
579
+ */
580
+ interface MomentumHistoryResponse {
581
+ /** Historical data points (oldest first) */
582
+ history: MomentumHistoryPoint[];
583
+ /** Number of points returned */
584
+ count: number;
585
+ }
586
+ /**
587
+ * Parameters for momentum history request
588
+ */
589
+ interface GetMomentumHistoryParams {
590
+ /** Max number of data points (default: 30, max: 90) */
591
+ limit?: number;
592
+ }
506
593
  }
507
594
 
508
595
  /**
@@ -851,6 +938,73 @@ declare class InsightsModule {
851
938
  * GET /v1/insights/trending
852
939
  */
853
940
  getTrending(): Promise<Insights.TrendingContent>;
941
+ /**
942
+ * Get YouTube channel momentum status
943
+ *
944
+ * Returns a 0-100 score indicating channel momentum:
945
+ * - 50 = Steady (no change week over week)
946
+ * - 0 = Severe decline
947
+ * - 100 = Explosive growth
948
+ *
949
+ * Results are cached for 12 hours. Use `refreshYouTubeMomentum()` to force recalculation.
950
+ *
951
+ * @example
952
+ * ```typescript
953
+ * const momentum = await client.insights.getYouTubeMomentum();
954
+ *
955
+ * console.log(`Score: ${momentum.score}/100`);
956
+ * console.log(`Status: ${momentum.status}`); // 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping'
957
+ * console.log(`Trend: ${momentum.trend}`); // 'accelerating' | 'holding' | 'decelerating'
958
+ * console.log(momentum.insight); // Human-readable summary
959
+ *
960
+ * // Show breakdown
961
+ * console.log(`Views: ${momentum.breakdown.views.change}%`);
962
+ * console.log(`Engagement: ${momentum.breakdown.engagement.change}%`);
963
+ * ```
964
+ *
965
+ * GET /v1/insights/youtube/momentum
966
+ */
967
+ getYouTubeMomentum(): Promise<Insights.MomentumStatusResponse>;
968
+ /**
969
+ * Get YouTube momentum history for graphing
970
+ *
971
+ * Returns historical momentum scores, oldest first.
972
+ * Use this to plot momentum trends over time.
973
+ *
974
+ * @param params - Query parameters
975
+ * @param params.limit - Max data points (default: 30, max: 90)
976
+ *
977
+ * @example
978
+ * ```typescript
979
+ * const { history } = await client.insights.getYouTubeMomentumHistory({ limit: 30 });
980
+ *
981
+ * // Plot on a chart
982
+ * const chartData = history.map(point => ({
983
+ * x: new Date(point.date),
984
+ * y: point.score,
985
+ * label: point.status
986
+ * }));
987
+ * ```
988
+ *
989
+ * GET /v1/insights/youtube/momentum/history
990
+ */
991
+ getYouTubeMomentumHistory(params?: Insights.GetMomentumHistoryParams): Promise<Insights.MomentumHistoryResponse>;
992
+ /**
993
+ * Force refresh YouTube momentum status (bypass cache)
994
+ *
995
+ * Use this after a sync completes to get the latest momentum score.
996
+ * Results are recalculated and cached for 12 hours.
997
+ *
998
+ * @example
999
+ * ```typescript
1000
+ * // After videos sync completes
1001
+ * const freshMomentum = await client.insights.refreshYouTubeMomentum();
1002
+ * console.log('Updated score:', freshMomentum.score);
1003
+ * ```
1004
+ *
1005
+ * POST /v1/insights/youtube/momentum/refresh
1006
+ */
1007
+ refreshYouTubeMomentum(): Promise<Insights.MomentumStatusResponse>;
854
1008
  }
855
1009
 
856
1010
  /**
@@ -861,7 +1015,7 @@ declare class InsightsModule {
861
1015
  *
862
1016
  * @example
863
1017
  * ```typescript
864
- * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';
1018
+ * import { TrndUpSDK, YOUTUBE_SCOPES } from '@dracoonghost/trndup-sdk';
865
1019
  * import auth from '@react-native-firebase/auth';
866
1020
  * import { GoogleSignin } from '@react-native-google-signin/google-signin';
867
1021
  *
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * @example
11
11
  * ```typescript
12
12
  * import { GoogleSignin } from '@react-native-google-signin/google-signin';
13
- * import { YOUTUBE_SCOPES } from '@trndup/sdk';
13
+ * import { YOUTUBE_SCOPES } from '@dracoonghost/trndup-sdk';
14
14
  *
15
15
  * GoogleSignin.configure({
16
16
  * webClientId: 'YOUR_WEB_CLIENT_ID',
@@ -297,11 +297,6 @@ declare namespace YouTube {
297
297
  * const videos = await client.youtube.getVideos();
298
298
  * localStorage.set('videosLastSync', status.data.syncs.videos.lastSyncAt);
299
299
  * }
300
- *
301
- * // Show user that refresh is happening
302
- * if (status.data.summary.anyInProgress) {
303
- * showRefreshIndicator();
304
- * }
305
300
  * ```
306
301
  */
307
302
  interface UnifiedSyncStatusResponse {
@@ -324,17 +319,6 @@ declare namespace YouTube {
324
319
  /** Video analytics (per-video metrics) */
325
320
  videoAnalytics: SyncTypeStatus;
326
321
  };
327
- /** Summary flags for quick checks */
328
- summary: {
329
- /** All sync types completed at least once with data */
330
- allSynced: boolean;
331
- /** At least one sync type is older than its refresh interval */
332
- anyStale: boolean;
333
- /** At least one sync type failed */
334
- anyFailed: boolean;
335
- /** At least one sync is currently in progress */
336
- anyInProgress: boolean;
337
- };
338
322
  }
339
323
  /**
340
324
  * Response from GET /v1/platforms/youtube/analytics/channel/sync/status
@@ -503,6 +487,109 @@ declare namespace Insights {
503
487
  youtube?: YouTube.Video[];
504
488
  instagram?: Instagram.Post[];
505
489
  }
490
+ /** Momentum status labels */
491
+ type MomentumStatusLabel = 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping';
492
+ /** Momentum trend direction */
493
+ type MomentumTrend = 'accelerating' | 'holding' | 'decelerating';
494
+ /**
495
+ * Metric breakdown showing current vs previous period
496
+ */
497
+ interface MetricComparison {
498
+ /** Current period value */
499
+ current: number;
500
+ /** Previous period value */
501
+ previous: number;
502
+ /** Percentage change (-100 to +100+) */
503
+ change: number;
504
+ }
505
+ /**
506
+ * Momentum Status Response
507
+ *
508
+ * Provides a 0-100 score indicating channel momentum:
509
+ * - 50 = Steady (no change week over week)
510
+ * - 0 = Severe decline (-100% or worse)
511
+ * - 100 = Explosive growth (+100% or better)
512
+ *
513
+ * Status labels:
514
+ * - 80-100: Surging 🚀
515
+ * - 60-79: Rising 📈
516
+ * - 40-59: Steady ➡️
517
+ * - 20-39: Cooling 📉
518
+ * - 0-19: Dropping 🔻
519
+ */
520
+ interface MomentumStatusResponse {
521
+ /** Normalized score 0-100 (50 = no change) */
522
+ score: number;
523
+ /** Raw weighted average change before normalization */
524
+ rawChange: number;
525
+ /** Human-friendly status label */
526
+ status: MomentumStatusLabel;
527
+ /** Trend direction compared to previous period */
528
+ trend: MomentumTrend;
529
+ /** Previous period's score (null if first calculation) */
530
+ previousScore: number | null;
531
+ /** Time periods being compared */
532
+ period: {
533
+ current: {
534
+ start: string;
535
+ end: string;
536
+ };
537
+ previous: {
538
+ start: string;
539
+ end: string;
540
+ };
541
+ };
542
+ /** Breakdown of individual metrics */
543
+ breakdown: {
544
+ views: MetricComparison;
545
+ engagement: MetricComparison;
546
+ watchTime: MetricComparison;
547
+ subscribers: MetricComparison;
548
+ };
549
+ /** Weights used in calculation */
550
+ weights: {
551
+ views: number;
552
+ engagement: number;
553
+ watchTime: number;
554
+ subscribers: number;
555
+ };
556
+ /** Human-readable insight summary */
557
+ insight: string;
558
+ /** Cache metadata */
559
+ _meta?: {
560
+ fromCache: boolean;
561
+ refreshed?: boolean;
562
+ cacheValidFor: string;
563
+ algorithmVersion: string;
564
+ };
565
+ }
566
+ /**
567
+ * Single history point for momentum graphing
568
+ */
569
+ interface MomentumHistoryPoint {
570
+ /** Date (YYYY-MM-DD) */
571
+ date: string;
572
+ /** Momentum score at that time */
573
+ score: number;
574
+ /** Status label at that time */
575
+ status: MomentumStatusLabel;
576
+ }
577
+ /**
578
+ * Momentum history response for graphing
579
+ */
580
+ interface MomentumHistoryResponse {
581
+ /** Historical data points (oldest first) */
582
+ history: MomentumHistoryPoint[];
583
+ /** Number of points returned */
584
+ count: number;
585
+ }
586
+ /**
587
+ * Parameters for momentum history request
588
+ */
589
+ interface GetMomentumHistoryParams {
590
+ /** Max number of data points (default: 30, max: 90) */
591
+ limit?: number;
592
+ }
506
593
  }
507
594
 
508
595
  /**
@@ -851,6 +938,73 @@ declare class InsightsModule {
851
938
  * GET /v1/insights/trending
852
939
  */
853
940
  getTrending(): Promise<Insights.TrendingContent>;
941
+ /**
942
+ * Get YouTube channel momentum status
943
+ *
944
+ * Returns a 0-100 score indicating channel momentum:
945
+ * - 50 = Steady (no change week over week)
946
+ * - 0 = Severe decline
947
+ * - 100 = Explosive growth
948
+ *
949
+ * Results are cached for 12 hours. Use `refreshYouTubeMomentum()` to force recalculation.
950
+ *
951
+ * @example
952
+ * ```typescript
953
+ * const momentum = await client.insights.getYouTubeMomentum();
954
+ *
955
+ * console.log(`Score: ${momentum.score}/100`);
956
+ * console.log(`Status: ${momentum.status}`); // 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping'
957
+ * console.log(`Trend: ${momentum.trend}`); // 'accelerating' | 'holding' | 'decelerating'
958
+ * console.log(momentum.insight); // Human-readable summary
959
+ *
960
+ * // Show breakdown
961
+ * console.log(`Views: ${momentum.breakdown.views.change}%`);
962
+ * console.log(`Engagement: ${momentum.breakdown.engagement.change}%`);
963
+ * ```
964
+ *
965
+ * GET /v1/insights/youtube/momentum
966
+ */
967
+ getYouTubeMomentum(): Promise<Insights.MomentumStatusResponse>;
968
+ /**
969
+ * Get YouTube momentum history for graphing
970
+ *
971
+ * Returns historical momentum scores, oldest first.
972
+ * Use this to plot momentum trends over time.
973
+ *
974
+ * @param params - Query parameters
975
+ * @param params.limit - Max data points (default: 30, max: 90)
976
+ *
977
+ * @example
978
+ * ```typescript
979
+ * const { history } = await client.insights.getYouTubeMomentumHistory({ limit: 30 });
980
+ *
981
+ * // Plot on a chart
982
+ * const chartData = history.map(point => ({
983
+ * x: new Date(point.date),
984
+ * y: point.score,
985
+ * label: point.status
986
+ * }));
987
+ * ```
988
+ *
989
+ * GET /v1/insights/youtube/momentum/history
990
+ */
991
+ getYouTubeMomentumHistory(params?: Insights.GetMomentumHistoryParams): Promise<Insights.MomentumHistoryResponse>;
992
+ /**
993
+ * Force refresh YouTube momentum status (bypass cache)
994
+ *
995
+ * Use this after a sync completes to get the latest momentum score.
996
+ * Results are recalculated and cached for 12 hours.
997
+ *
998
+ * @example
999
+ * ```typescript
1000
+ * // After videos sync completes
1001
+ * const freshMomentum = await client.insights.refreshYouTubeMomentum();
1002
+ * console.log('Updated score:', freshMomentum.score);
1003
+ * ```
1004
+ *
1005
+ * POST /v1/insights/youtube/momentum/refresh
1006
+ */
1007
+ refreshYouTubeMomentum(): Promise<Insights.MomentumStatusResponse>;
854
1008
  }
855
1009
 
856
1010
  /**
@@ -861,7 +1015,7 @@ declare class InsightsModule {
861
1015
  *
862
1016
  * @example
863
1017
  * ```typescript
864
- * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';
1018
+ * import { TrndUpSDK, YOUTUBE_SCOPES } from '@dracoonghost/trndup-sdk';
865
1019
  * import auth from '@react-native-firebase/auth';
866
1020
  * import { GoogleSignin } from '@react-native-google-signin/google-signin';
867
1021
  *
package/dist/index.js CHANGED
@@ -534,6 +534,88 @@ var InsightsModule = class {
534
534
  async getTrending() {
535
535
  return this.client.get("/v1/insights/trending");
536
536
  }
537
+ // =========================================================================
538
+ // YOUTUBE MOMENTUM
539
+ // =========================================================================
540
+ /**
541
+ * Get YouTube channel momentum status
542
+ *
543
+ * Returns a 0-100 score indicating channel momentum:
544
+ * - 50 = Steady (no change week over week)
545
+ * - 0 = Severe decline
546
+ * - 100 = Explosive growth
547
+ *
548
+ * Results are cached for 12 hours. Use `refreshYouTubeMomentum()` to force recalculation.
549
+ *
550
+ * @example
551
+ * ```typescript
552
+ * const momentum = await client.insights.getYouTubeMomentum();
553
+ *
554
+ * console.log(`Score: ${momentum.score}/100`);
555
+ * console.log(`Status: ${momentum.status}`); // 'surging' | 'rising' | 'steady' | 'cooling' | 'dropping'
556
+ * console.log(`Trend: ${momentum.trend}`); // 'accelerating' | 'holding' | 'decelerating'
557
+ * console.log(momentum.insight); // Human-readable summary
558
+ *
559
+ * // Show breakdown
560
+ * console.log(`Views: ${momentum.breakdown.views.change}%`);
561
+ * console.log(`Engagement: ${momentum.breakdown.engagement.change}%`);
562
+ * ```
563
+ *
564
+ * GET /v1/insights/youtube/momentum
565
+ */
566
+ async getYouTubeMomentum() {
567
+ return this.client.get("/v1/insights/youtube/momentum");
568
+ }
569
+ /**
570
+ * Get YouTube momentum history for graphing
571
+ *
572
+ * Returns historical momentum scores, oldest first.
573
+ * Use this to plot momentum trends over time.
574
+ *
575
+ * @param params - Query parameters
576
+ * @param params.limit - Max data points (default: 30, max: 90)
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * const { history } = await client.insights.getYouTubeMomentumHistory({ limit: 30 });
581
+ *
582
+ * // Plot on a chart
583
+ * const chartData = history.map(point => ({
584
+ * x: new Date(point.date),
585
+ * y: point.score,
586
+ * label: point.status
587
+ * }));
588
+ * ```
589
+ *
590
+ * GET /v1/insights/youtube/momentum/history
591
+ */
592
+ async getYouTubeMomentumHistory(params) {
593
+ const query = params?.limit ? `?limit=${params.limit}` : "";
594
+ return this.client.get(
595
+ `/v1/insights/youtube/momentum/history${query}`
596
+ );
597
+ }
598
+ /**
599
+ * Force refresh YouTube momentum status (bypass cache)
600
+ *
601
+ * Use this after a sync completes to get the latest momentum score.
602
+ * Results are recalculated and cached for 12 hours.
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * // After videos sync completes
607
+ * const freshMomentum = await client.insights.refreshYouTubeMomentum();
608
+ * console.log('Updated score:', freshMomentum.score);
609
+ * ```
610
+ *
611
+ * POST /v1/insights/youtube/momentum/refresh
612
+ */
613
+ async refreshYouTubeMomentum() {
614
+ return this.client.post(
615
+ "/v1/insights/youtube/momentum/refresh",
616
+ {}
617
+ );
618
+ }
537
619
  };
538
620
 
539
621
  // types.ts