@dracoonghost/trndup-sdk 1.3.2 → 1.3.4
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 +46 -10
- package/dist/index.d.ts +46 -10
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -92,9 +92,17 @@ declare namespace Auth {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
declare namespace Social {
|
|
95
|
+
/**
|
|
96
|
+
* Link YouTube account request
|
|
97
|
+
*
|
|
98
|
+
* Two options:
|
|
99
|
+
* 1. serverAuthCode (recommended): Backend exchanges for tokens with proper expiry
|
|
100
|
+
* 2. Direct tokens: Frontend provides accessToken (expiresAt defaults to 1 hour)
|
|
101
|
+
*/
|
|
95
102
|
interface LinkYouTubeRequest {
|
|
96
103
|
idToken: string;
|
|
97
|
-
|
|
104
|
+
serverAuthCode?: string;
|
|
105
|
+
accessToken?: string;
|
|
98
106
|
refreshToken?: string;
|
|
99
107
|
expiresAt?: number;
|
|
100
108
|
grantedScopes?: string;
|
|
@@ -119,20 +127,46 @@ declare namespace Social {
|
|
|
119
127
|
}
|
|
120
128
|
}
|
|
121
129
|
declare namespace YouTube {
|
|
130
|
+
/**
|
|
131
|
+
* Response from GET /v1/platforms/youtube/init/status
|
|
132
|
+
*/
|
|
122
133
|
interface InitStatusResponse {
|
|
123
134
|
needsInit: boolean;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
status: 'NEVER_SYNCED' | 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
|
|
136
|
+
lastSyncAt: string | null;
|
|
137
|
+
videoCount: number;
|
|
138
|
+
oldestVideoDate: string | null;
|
|
139
|
+
analyticsStartDate: string | null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Response from POST /v1/platforms/youtube/init
|
|
143
|
+
*/
|
|
144
|
+
interface InitResponse {
|
|
145
|
+
channel: {
|
|
146
|
+
channelId: string;
|
|
147
|
+
channelTitle: string;
|
|
148
|
+
subscriberCount: number;
|
|
149
|
+
videoCount: number;
|
|
150
|
+
viewCount: number;
|
|
151
|
+
};
|
|
152
|
+
videos: {
|
|
153
|
+
total: number;
|
|
154
|
+
synced: number;
|
|
155
|
+
oldestVideoDate: string | null;
|
|
156
|
+
};
|
|
157
|
+
syncStatus: {
|
|
158
|
+
isFirstSync: boolean;
|
|
159
|
+
lastSyncAt: string | null;
|
|
160
|
+
};
|
|
128
161
|
}
|
|
129
162
|
interface Video {
|
|
130
163
|
id: string;
|
|
164
|
+
videoId: string;
|
|
131
165
|
title: string;
|
|
132
166
|
description?: string;
|
|
133
167
|
thumbnailUrl?: string;
|
|
134
168
|
publishedAt: string;
|
|
135
|
-
duration?:
|
|
169
|
+
duration?: number;
|
|
136
170
|
viewCount?: number;
|
|
137
171
|
likeCount?: number;
|
|
138
172
|
commentCount?: number;
|
|
@@ -372,17 +406,19 @@ declare class YouTubeModule {
|
|
|
372
406
|
constructor(client: TrndUpClient);
|
|
373
407
|
/**
|
|
374
408
|
* Get YouTube initialization status
|
|
409
|
+
* Check if user needs to init or has already synced
|
|
410
|
+
*
|
|
375
411
|
* GET /v1/platforms/youtube/init/status
|
|
376
412
|
*/
|
|
377
413
|
getInitStatus(): Promise<YouTube.InitStatusResponse>;
|
|
378
414
|
/**
|
|
379
415
|
* Initialize YouTube data sync
|
|
416
|
+
* Fetches all channel info and videos, stores in database
|
|
417
|
+
* Returns channel info, video counts, and oldest video date for analytics
|
|
418
|
+
*
|
|
380
419
|
* POST /v1/platforms/youtube/init
|
|
381
420
|
*/
|
|
382
|
-
initialize(): Promise<
|
|
383
|
-
message: string;
|
|
384
|
-
jobId?: string;
|
|
385
|
-
}>;
|
|
421
|
+
initialize(): Promise<YouTube.InitResponse>;
|
|
386
422
|
/**
|
|
387
423
|
* Get YouTube videos
|
|
388
424
|
* GET /v1/platforms/youtube/videos
|
package/dist/index.d.ts
CHANGED
|
@@ -92,9 +92,17 @@ declare namespace Auth {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
declare namespace Social {
|
|
95
|
+
/**
|
|
96
|
+
* Link YouTube account request
|
|
97
|
+
*
|
|
98
|
+
* Two options:
|
|
99
|
+
* 1. serverAuthCode (recommended): Backend exchanges for tokens with proper expiry
|
|
100
|
+
* 2. Direct tokens: Frontend provides accessToken (expiresAt defaults to 1 hour)
|
|
101
|
+
*/
|
|
95
102
|
interface LinkYouTubeRequest {
|
|
96
103
|
idToken: string;
|
|
97
|
-
|
|
104
|
+
serverAuthCode?: string;
|
|
105
|
+
accessToken?: string;
|
|
98
106
|
refreshToken?: string;
|
|
99
107
|
expiresAt?: number;
|
|
100
108
|
grantedScopes?: string;
|
|
@@ -119,20 +127,46 @@ declare namespace Social {
|
|
|
119
127
|
}
|
|
120
128
|
}
|
|
121
129
|
declare namespace YouTube {
|
|
130
|
+
/**
|
|
131
|
+
* Response from GET /v1/platforms/youtube/init/status
|
|
132
|
+
*/
|
|
122
133
|
interface InitStatusResponse {
|
|
123
134
|
needsInit: boolean;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
status: 'NEVER_SYNCED' | 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
|
|
136
|
+
lastSyncAt: string | null;
|
|
137
|
+
videoCount: number;
|
|
138
|
+
oldestVideoDate: string | null;
|
|
139
|
+
analyticsStartDate: string | null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Response from POST /v1/platforms/youtube/init
|
|
143
|
+
*/
|
|
144
|
+
interface InitResponse {
|
|
145
|
+
channel: {
|
|
146
|
+
channelId: string;
|
|
147
|
+
channelTitle: string;
|
|
148
|
+
subscriberCount: number;
|
|
149
|
+
videoCount: number;
|
|
150
|
+
viewCount: number;
|
|
151
|
+
};
|
|
152
|
+
videos: {
|
|
153
|
+
total: number;
|
|
154
|
+
synced: number;
|
|
155
|
+
oldestVideoDate: string | null;
|
|
156
|
+
};
|
|
157
|
+
syncStatus: {
|
|
158
|
+
isFirstSync: boolean;
|
|
159
|
+
lastSyncAt: string | null;
|
|
160
|
+
};
|
|
128
161
|
}
|
|
129
162
|
interface Video {
|
|
130
163
|
id: string;
|
|
164
|
+
videoId: string;
|
|
131
165
|
title: string;
|
|
132
166
|
description?: string;
|
|
133
167
|
thumbnailUrl?: string;
|
|
134
168
|
publishedAt: string;
|
|
135
|
-
duration?:
|
|
169
|
+
duration?: number;
|
|
136
170
|
viewCount?: number;
|
|
137
171
|
likeCount?: number;
|
|
138
172
|
commentCount?: number;
|
|
@@ -372,17 +406,19 @@ declare class YouTubeModule {
|
|
|
372
406
|
constructor(client: TrndUpClient);
|
|
373
407
|
/**
|
|
374
408
|
* Get YouTube initialization status
|
|
409
|
+
* Check if user needs to init or has already synced
|
|
410
|
+
*
|
|
375
411
|
* GET /v1/platforms/youtube/init/status
|
|
376
412
|
*/
|
|
377
413
|
getInitStatus(): Promise<YouTube.InitStatusResponse>;
|
|
378
414
|
/**
|
|
379
415
|
* Initialize YouTube data sync
|
|
416
|
+
* Fetches all channel info and videos, stores in database
|
|
417
|
+
* Returns channel info, video counts, and oldest video date for analytics
|
|
418
|
+
*
|
|
380
419
|
* POST /v1/platforms/youtube/init
|
|
381
420
|
*/
|
|
382
|
-
initialize(): Promise<
|
|
383
|
-
message: string;
|
|
384
|
-
jobId?: string;
|
|
385
|
-
}>;
|
|
421
|
+
initialize(): Promise<YouTube.InitResponse>;
|
|
386
422
|
/**
|
|
387
423
|
* Get YouTube videos
|
|
388
424
|
* GET /v1/platforms/youtube/videos
|
package/dist/index.js
CHANGED
|
@@ -273,6 +273,8 @@ var YouTubeModule = class {
|
|
|
273
273
|
}
|
|
274
274
|
/**
|
|
275
275
|
* Get YouTube initialization status
|
|
276
|
+
* Check if user needs to init or has already synced
|
|
277
|
+
*
|
|
276
278
|
* GET /v1/platforms/youtube/init/status
|
|
277
279
|
*/
|
|
278
280
|
async getInitStatus() {
|
|
@@ -280,6 +282,9 @@ var YouTubeModule = class {
|
|
|
280
282
|
}
|
|
281
283
|
/**
|
|
282
284
|
* Initialize YouTube data sync
|
|
285
|
+
* Fetches all channel info and videos, stores in database
|
|
286
|
+
* Returns channel info, video counts, and oldest video date for analytics
|
|
287
|
+
*
|
|
283
288
|
* POST /v1/platforms/youtube/init
|
|
284
289
|
*/
|
|
285
290
|
async initialize() {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../client.ts","../modules/auth.ts","../modules/youtube.ts","../modules/instagram.ts","../modules/social.ts","../modules/insights.ts","../types.ts","../index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TrndUp SDK - Base Client\n * \n * Core HTTP client with Firebase authentication support,\n * error handling, and automatic retries.\n */\n\nimport type { ApiResponse, ApiErrorResponse, ApiSuccessResponse } from './types';\n\n// =============================================================================\n// CONFIGURATION\n// =============================================================================\n\nexport interface TrndUpClientConfig {\n /** Base URL for the API (e.g., 'https://api.trndup.app' or 'http://localhost:3000') */\n baseUrl: string;\n \n /** Function to get the current Firebase ID token */\n getToken: () => string | null | Promise<string | null>;\n \n /** Called when auth completely fails (user needs to re-login) */\n onAuthFailure?: () => void | Promise<void>;\n \n /** Called on any API error */\n onError?: (error: ApiErrorResponse, endpoint: string) => void;\n \n /** Custom headers to include in all requests */\n defaultHeaders?: Record<string, string>;\n \n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n \n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport interface RequestOptions {\n /** Skip authentication for this request */\n skipAuth?: boolean;\n \n /** Additional headers for this request */\n headers?: Record<string, string>;\n \n /** AbortController signal for cancellation */\n signal?: AbortSignal;\n \n /** Custom timeout for this request */\n timeout?: number;\n}\n\ninterface RequestConfig extends RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\nexport class TrndUpApiError extends Error {\n constructor(\n public readonly response: ApiErrorResponse,\n public readonly status: number,\n public readonly endpoint: string\n ) {\n super(response.error);\n this.name = 'TrndUpApiError';\n }\n \n get code(): string | undefined {\n return this.response.code;\n }\n\n get metadata(): Record<string, unknown> | undefined {\n return this.response.metadata;\n }\n\n /** Check if error is due to authentication failure */\n isAuthError(): boolean {\n return this.status === 401 || this.code === 'AUTH_EXPIRED' || this.code === 'AUTH_INVALID';\n }\n\n /** Check if error is due to rate limiting */\n isRateLimitError(): boolean {\n return this.status === 429 || this.code === 'RATE_LIMITED';\n }\n}\n\nexport class TrndUpNetworkError extends Error {\n constructor(\n public readonly originalError: Error,\n public readonly endpoint: string\n ) {\n super(`Network error calling ${endpoint}: ${originalError.message}`);\n this.name = 'TrndUpNetworkError';\n }\n}\n\n// =============================================================================\n// BASE CLIENT\n// =============================================================================\n\nexport class TrndUpClient {\n private config: Required<Omit<TrndUpClientConfig, 'onAuthFailure' | 'onError' | 'defaultHeaders' | 'debug'>> & {\n onAuthFailure?: TrndUpClientConfig['onAuthFailure'];\n onError?: TrndUpClientConfig['onError'];\n defaultHeaders?: Record<string, string>;\n debug?: boolean;\n };\n\n // Module instances (imported by subclasses or external modules)\n public auth!: any;\n public youtube!: any;\n public instagram!: any;\n public social!: any;\n public insights!: any;\n\n constructor(config: TrndUpClientConfig) {\n this.config = {\n baseUrl: config.baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n getToken: config.getToken,\n timeout: config.timeout ?? 30000,\n onAuthFailure: config.onAuthFailure,\n onError: config.onError,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug ?? false,\n };\n }\n\n // =============================================================================\n // PUBLIC REQUEST METHODS\n // =============================================================================\n\n async get<T = unknown>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'GET', path, params, ...options });\n }\n\n async post<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'POST', path, body, ...options });\n }\n\n async put<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body, ...options });\n }\n\n async patch<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PATCH', path, body, ...options });\n }\n\n async delete<T = unknown>(\n path: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'DELETE', path, ...options });\n }\n\n // =============================================================================\n // CORE REQUEST LOGIC\n // =============================================================================\n\n private async request<T>(config: RequestConfig): Promise<T> {\n const { method, path, params, body, skipAuth, headers, signal, timeout } = config;\n\n // Build URL\n const url = this.buildUrl(path, params);\n\n // Build headers\n const requestHeaders = await this.buildHeaders(skipAuth, headers);\n\n // Build request init\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n signal,\n };\n\n if (body && method !== 'GET') {\n init.body = JSON.stringify(body);\n }\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout ?? this.config.timeout\n );\n\n try {\n if (this.config.debug) {\n console.log(`[TrndUp SDK] ${method} ${url}`, { body, headers: requestHeaders });\n }\n\n const response = await fetch(url, {\n ...init,\n signal: signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n return await this.handleResponse<T>(response, path);\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof TrndUpApiError) {\n throw error;\n }\n\n // Network error\n const networkError = new TrndUpNetworkError(\n error as Error,\n path\n );\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] Network error:', networkError);\n }\n\n throw networkError;\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private async buildHeaders(\n skipAuth?: boolean,\n additionalHeaders?: Record<string, string>\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.config.defaultHeaders,\n ...additionalHeaders,\n };\n\n // Add Firebase ID token for authentication\n if (!skipAuth) {\n const token = await this.config.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n\n return headers;\n }\n\n private async handleResponse<T>(response: Response, endpoint: string): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n // Try to parse error response\n let errorResponse: ApiErrorResponse;\n\n if (isJson) {\n try {\n const parsed = await response.json();\n errorResponse = parsed as ApiErrorResponse;\n } catch {\n errorResponse = {\n success: false,\n error: response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n } else {\n const text = await response.text();\n errorResponse = {\n success: false,\n error: text || response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n\n const apiError = new TrndUpApiError(errorResponse, response.status, endpoint);\n\n // Call error handler\n if (this.config.onError) {\n this.config.onError(errorResponse, endpoint);\n }\n\n // Call auth failure handler for 401 errors\n if (apiError.isAuthError() && this.config.onAuthFailure) {\n await this.config.onAuthFailure();\n }\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] API error:', apiError);\n }\n\n throw apiError;\n }\n\n // Parse success response\n if (isJson) {\n const parsed = await response.json();\n const jsonResponse = parsed as ApiResponse<T>;\n\n if (jsonResponse.success === false) {\n // This shouldn't happen with 2xx status, but handle it\n throw new TrndUpApiError(jsonResponse, response.status, endpoint);\n }\n\n return (jsonResponse as ApiSuccessResponse<T>).data;\n }\n\n // Non-JSON response\n return (await response.text()) as unknown as T;\n }\n}\n","/**\n * TrndUp SDK - Auth Module\n * \n * Firebase authentication methods with Twilio phone OTP\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Auth } from '../types';\n\nexport class AuthModule {\n constructor(private client: TrndUpClient) {}\n\n // =========================================================================\n // PHONE OTP AUTHENTICATION (via Twilio - no reCAPTCHA needed)\n // =========================================================================\n\n /**\n * Send OTP verification code to phone number\n * POST /auth/phone/send-otp\n * \n * @param phoneNumber - Phone number (E.164 format recommended, e.g., +14155551234)\n */\n async sendOTP(phoneNumber: string): Promise<Auth.SendOTPResponse> {\n return this.client.post<Auth.SendOTPResponse>(\n '/auth/phone/send-otp', \n { phoneNumber }, \n { skipAuth: true }\n );\n }\n\n /**\n * Verify OTP and get Firebase custom token\n * POST /auth/phone/verify-otp\n * \n * After calling this, use Firebase signInWithCustomToken(customToken)\n * to complete authentication on the client.\n * \n * @param phoneNumber - Phone number that received the OTP\n * @param code - 6-digit verification code\n */\n async verifyOTP(phoneNumber: string, code: string): Promise<Auth.VerifyOTPResponse> {\n return this.client.post<Auth.VerifyOTPResponse>(\n '/auth/phone/verify-otp',\n { phoneNumber, code },\n { skipAuth: true }\n );\n }\n\n // =========================================================================\n // FIREBASE ID TOKEN AUTHENTICATION\n // =========================================================================\n\n /**\n * Login with Firebase ID token (for Google, Apple, Email/Password)\n * POST /auth/login\n */\n async login(idToken: string): Promise<Auth.LoginResponse> {\n return this.client.post<Auth.LoginResponse>('/auth/login', { idToken }, { skipAuth: true });\n }\n\n /**\n * Get current authenticated user's profile\n * GET /auth/me\n */\n async getCurrentUser(): Promise<Auth.CurrentUserResponse> {\n return this.client.get<Auth.CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Update user profile\n * PATCH /auth/me\n */\n async updateProfile(data: Auth.UpdateProfileRequest): Promise<Auth.UpdateProfileResponse> {\n return this.client.patch<Auth.UpdateProfileResponse>('/auth/me', data);\n }\n\n /**\n * Logout (acknowledge logout on backend)\n * POST /auth/logout\n */\n async logout(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/auth/logout');\n }\n\n /**\n * Check auth service status\n * GET /auth/status\n */\n async getStatus(): Promise<{ success: boolean; message: string }> {\n return this.client.get('/auth/status', undefined, { skipAuth: true });\n }\n\n /**\n * Get user's platform connection status\n * GET /user/platforms/status\n */\n async getPlatformStatus(): Promise<Auth.PlatformStatus> {\n return this.client.get<Auth.PlatformStatus>('/user/platforms/status');\n }\n}\n","/**\n * TrndUp SDK - YouTube Module\n * \n * YouTube analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { YouTube } from '../types';\n\nexport class YouTubeModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get YouTube initialization status\n * GET /v1/platforms/youtube/init/status\n */\n async getInitStatus(): Promise<YouTube.InitStatusResponse> {\n return this.client.get<YouTube.InitStatusResponse>('/v1/platforms/youtube/init/status');\n }\n\n /**\n * Initialize YouTube data sync\n * POST /v1/platforms/youtube/init\n */\n async initialize(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/init');\n }\n\n /**\n * Get YouTube videos\n * GET /v1/platforms/youtube/videos\n */\n async getVideos(params?: YouTube.GetVideosParams): Promise<YouTube.GetVideosResponse> {\n return this.client.get<YouTube.GetVideosResponse>(\n '/v1/platforms/youtube/videos', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific video by ID\n * GET /v1/platforms/youtube/videos/:videoId\n */\n async getVideo(videoId: string): Promise<YouTube.Video> {\n return this.client.get<YouTube.Video>(`/v1/platforms/youtube/videos/${videoId}`);\n }\n\n /**\n * Get channel metrics\n * GET /v1/platforms/youtube/channel/metrics\n */\n async getChannelMetrics(): Promise<YouTube.ChannelMetrics> {\n return this.client.get<YouTube.ChannelMetrics>('/v1/platforms/youtube/channel/metrics');\n }\n\n /**\n * Get channel health score\n * GET /v1/platforms/youtube/health\n */\n async getHealthScore(params?: YouTube.GetHealthScoreParams): Promise<YouTube.HealthScore> {\n return this.client.get<YouTube.HealthScore>(\n '/v1/platforms/youtube/health', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Refresh YouTube data\n * POST /v1/platforms/youtube/refresh\n */\n async refresh(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/refresh');\n }\n}\n","/**\n * TrndUp SDK - Instagram Module\n * \n * Instagram analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Instagram } from '../types';\n\nexport class InstagramModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get Instagram initialization status\n * GET /v1/platforms/instagram/init/status\n */\n async getInitStatus(): Promise<Instagram.InitStatusResponse> {\n return this.client.get<Instagram.InitStatusResponse>('/v1/platforms/instagram/init/status');\n }\n\n /**\n * Initialize Instagram data sync\n * POST /v1/platforms/instagram/init\n */\n async initialize(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/init');\n }\n\n /**\n * Get Instagram posts\n * GET /v1/platforms/instagram/posts\n */\n async getPosts(params?: Instagram.GetPostsParams): Promise<Instagram.GetPostsResponse> {\n return this.client.get<Instagram.GetPostsResponse>(\n '/v1/platforms/instagram/posts', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific post by ID\n * GET /v1/platforms/instagram/posts/:postId\n */\n async getPost(postId: string): Promise<Instagram.Post> {\n return this.client.get<Instagram.Post>(`/v1/platforms/instagram/posts/${postId}`);\n }\n\n /**\n * Get account metrics\n * GET /v1/platforms/instagram/account/metrics\n */\n async getAccountMetrics(): Promise<Instagram.AccountMetrics> {\n return this.client.get<Instagram.AccountMetrics>('/v1/platforms/instagram/account/metrics');\n }\n\n /**\n * Refresh Instagram data\n * POST /v1/platforms/instagram/refresh\n */\n async refresh(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/refresh');\n }\n}\n","/**\n * TrndUp SDK - Social Module\n * \n * Social account linking methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Social } from '../types';\n\nexport class SocialModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Link YouTube account\n * POST /social/link/youtube\n */\n async linkYouTube(data: Social.LinkYouTubeRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/youtube', data);\n }\n\n /**\n * Link Instagram account\n * POST /social/link/instagram\n */\n async linkInstagram(data: Social.LinkInstagramRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/instagram', data);\n }\n\n /**\n * Get all connected social accounts\n * GET /social/accounts\n */\n async getConnectedAccounts(): Promise<Social.ConnectedAccount[]> {\n return this.client.get<Social.ConnectedAccount[]>('/social/accounts');\n }\n\n /**\n * Unlink a social account\n * DELETE /social/unlink/:provider\n */\n async unlinkAccount(provider: string): Promise<{ message: string }> {\n return this.client.delete<{ message: string }>(`/social/unlink/${provider}`);\n }\n}\n","/**\n * TrndUp SDK - Insights Module\n * \n * Cross-platform insights and analytics\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Insights } from '../types';\n\nexport class InsightsModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get cross-platform metrics\n * GET /v1/insights/overview\n */\n async getOverview(): Promise<Insights.CrossPlatformMetrics> {\n return this.client.get<Insights.CrossPlatformMetrics>('/v1/insights/overview');\n }\n\n /**\n * Get trending content across all platforms\n * GET /v1/insights/trending\n */\n async getTrending(): Promise<Insights.TrendingContent> {\n return this.client.get<Insights.TrendingContent>('/v1/insights/trending');\n }\n}\n","/**\n * TrndUp SDK Types\n * \n * Type definitions for the TrndUp API SDK\n */\n\n// =============================================================================\n// OAUTH SCOPES\n// =============================================================================\n\n/**\n * Required OAuth scopes for YouTube account linking\n * Use these when configuring Google Sign-In in your mobile app\n * \n * @example\n * ```typescript\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * import { YOUTUBE_SCOPES } from '@trndup/sdk';\n * \n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * ```\n */\nexport const YOUTUBE_SCOPES = [\n 'openid',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/youtube.readonly',\n 'https://www.googleapis.com/auth/yt-analytics.readonly',\n 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',\n 'https://www.googleapis.com/auth/youtube.force-ssl',\n 'https://www.googleapis.com/auth/youtubepartner'\n];\n\n/**\n * Required OAuth scopes for Instagram account linking\n */\nexport const INSTAGRAM_SCOPES = [\n 'instagram_business_basic',\n 'instagram_business_manage_insights',\n 'instagram_business_manage_comments'\n];\n\n// =============================================================================\n// API RESPONSE WRAPPER\n// =============================================================================\n\nexport interface ApiSuccessResponse<T = unknown> {\n success: true;\n data: T;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: string;\n code?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// =============================================================================\n// AUTH TYPES\n// =============================================================================\n\nexport namespace Auth {\n export interface User {\n id: string;\n firebaseUid?: string;\n email?: string;\n phoneNumber?: string;\n username: string;\n picture?: string;\n emailVerified?: boolean;\n signInProvider?: string; // 'phone', 'google.com', 'password', 'apple.com'\n createdAt: string;\n updatedAt: string;\n }\n\n export interface SocialAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n }\n\n // Phone OTP Authentication (Twilio)\n export interface SendOTPRequest {\n phoneNumber: string;\n }\n\n export interface SendOTPResponse {\n message: string;\n expiresIn: number;\n }\n\n export interface VerifyOTPRequest {\n phoneNumber: string;\n code: string;\n }\n\n export interface VerifyOTPResponse {\n customToken: string;\n isNewUser: boolean;\n user: User;\n platformStatus: PlatformStatus;\n }\n\n // Firebase ID Token Login\n export interface LoginRequest {\n idToken: string;\n }\n\n export interface LoginResponse {\n user: User;\n platformStatus: PlatformStatus;\n idToken: string;\n }\n\n export interface CurrentUserResponse {\n user: User;\n socialAccounts: SocialAccount[];\n }\n\n export interface UpdateProfileRequest {\n username?: string;\n picture?: string;\n }\n\n export interface UpdateProfileResponse {\n user: User;\n }\n\n export interface PlatformStatus {\n hasConnectedPlatforms: boolean;\n connectedPlatforms: Array<'youtube' | 'instagram'>;\n }\n}\n\n// =============================================================================\n// SOCIAL TYPES\n// =============================================================================\n\nexport namespace Social {\n export interface LinkYouTubeRequest {\n idToken: string; // Google ID token for verification\n accessToken: string; // Google access token for API calls\n refreshToken?: string; // Google refresh token (recommended)\n expiresAt?: number; // Token expiry timestamp (ms since epoch)\n grantedScopes?: string; // Actual scopes user granted (space-separated)\n platform?: string; // 'ios' | 'android' | 'web'\n environment?: string; // 'development' | 'production'\n }\n\n export interface LinkInstagramRequest {\n accessToken: string;\n }\n\n export interface LinkAccountResponse {\n message: string;\n provider: string;\n accountName?: string;\n }\n\n export interface ConnectedAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n lastSyncAt?: string;\n }\n}\n\n// =============================================================================\n// YOUTUBE TYPES\n// =============================================================================\n\nexport namespace YouTube {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n videoCount?: number;\n channelId?: string;\n channelTitle?: string;\n }\n\n export interface Video {\n id: string;\n title: string;\n description?: string;\n thumbnailUrl?: string;\n publishedAt: string;\n duration?: string;\n viewCount?: number;\n likeCount?: number;\n commentCount?: number;\n engagementRate?: number;\n }\n\n export interface GetVideosParams {\n limit?: number;\n offset?: number;\n sortBy?: 'recent' | 'views' | 'engagement';\n }\n\n export interface GetVideosResponse {\n videos: Video[];\n total: number;\n hasMore: boolean;\n }\n\n export interface ChannelMetrics {\n subscriberCount: number;\n totalViews: number;\n totalVideos: number;\n averageViews: number;\n engagementRate: number;\n }\n\n export interface HealthScore {\n score: number;\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n metrics: {\n consistency: number;\n engagement: number;\n growth: number;\n quality: number;\n };\n }\n\n export interface GetHealthScoreParams {\n range?: string; // e.g., '7d', '30d', '90d'\n }\n}\n\n// =============================================================================\n// INSTAGRAM TYPES\n// =============================================================================\n\nexport namespace Instagram {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n postCount?: number;\n accountId?: string;\n username?: string;\n }\n\n export interface Post {\n id: string;\n caption?: string;\n mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM';\n mediaUrl: string;\n permalink: string;\n timestamp: string;\n likeCount?: number;\n commentsCount?: number;\n engagementRate?: number;\n }\n\n export interface GetPostsParams {\n limit?: number;\n offset?: number;\n }\n\n export interface GetPostsResponse {\n posts: Post[];\n total: number;\n hasMore: boolean;\n }\n\n export interface AccountMetrics {\n followersCount: number;\n followsCount: number;\n mediaCount: number;\n averageLikes: number;\n engagementRate: number;\n }\n}\n\n// =============================================================================\n// INSIGHTS TYPES\n// =============================================================================\n\nexport namespace Insights {\n export interface CrossPlatformMetrics {\n totalFollowers: number;\n totalEngagement: number;\n platforms: {\n youtube?: {\n subscribers: number;\n views: number;\n videos: number;\n };\n instagram?: {\n followers: number;\n posts: number;\n avgEngagement: number;\n };\n };\n }\n\n export interface TrendingContent {\n youtube?: YouTube.Video[];\n instagram?: Instagram.Post[];\n }\n}\n","/**\n * TrndUp API SDK\n * \n * Official TypeScript SDK for the TrndUp API.\n * Provides type-safe methods for all API endpoints with Firebase authentication.\n * \n * @example\n * ```typescript\n * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';\n * import auth from '@react-native-firebase/auth';\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * \n * // Configure Google Sign-In with YouTube scopes\n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * \n * const sdk = new TrndUpSDK({\n * baseUrl: 'https://api.trndup.app',\n * getToken: async () => {\n * const user = auth().currentUser;\n * return user ? await user.getIdToken() : null;\n * },\n * onAuthFailure: () => {\n * // Handle auth failure - navigate to login\n * navigation.navigate('Login');\n * },\n * });\n * \n * // Type-safe API calls\n * const user = await sdk.auth.getCurrentUser();\n * const videos = await sdk.youtube.getVideos({ limit: 10 });\n * const healthScore = await sdk.youtube.getHealthScore({ range: '30d' });\n * ```\n */\n\nimport { TrndUpClient, TrndUpClientConfig } from './client';\nimport { AuthModule } from './modules/auth';\nimport { YouTubeModule } from './modules/youtube';\nimport { InstagramModule } from './modules/instagram';\nimport { SocialModule } from './modules/social';\nimport { InsightsModule } from './modules/insights';\n\nexport class TrndUpSDK extends TrndUpClient {\n public auth: AuthModule;\n public youtube: YouTubeModule;\n public instagram: InstagramModule;\n public social: SocialModule;\n public insights: InsightsModule;\n\n constructor(config: TrndUpClientConfig) {\n super(config);\n\n // Initialize all modules\n this.auth = new AuthModule(this);\n this.youtube = new YouTubeModule(this);\n this.instagram = new InstagramModule(this);\n this.social = new SocialModule(this);\n this.insights = new InsightsModule(this);\n }\n}\n\n// Re-export types and classes\nexport type { TrndUpClientConfig, RequestOptions } from './client';\nexport { TrndUpApiError, TrndUpNetworkError } from './client';\n\n// Re-export all type namespaces\nexport type { Auth, Social, YouTube, Instagram, Insights } from './types';\n\n// Re-export OAuth scopes for configuring Google Sign-In\nexport { YOUTUBE_SCOPES, INSTAGRAM_SCOPES } from './types';\n\n// Version\nexport const SDK_VERSION = '1.0.0';\n"]}
|
|
1
|
+
{"version":3,"sources":["../client.ts","../modules/auth.ts","../modules/youtube.ts","../modules/instagram.ts","../modules/social.ts","../modules/insights.ts","../types.ts","../index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TrndUp SDK - Base Client\n * \n * Core HTTP client with Firebase authentication support,\n * error handling, and automatic retries.\n */\n\nimport type { ApiResponse, ApiErrorResponse, ApiSuccessResponse } from './types';\n\n// =============================================================================\n// CONFIGURATION\n// =============================================================================\n\nexport interface TrndUpClientConfig {\n /** Base URL for the API (e.g., 'https://api.trndup.app' or 'http://localhost:3000') */\n baseUrl: string;\n \n /** Function to get the current Firebase ID token */\n getToken: () => string | null | Promise<string | null>;\n \n /** Called when auth completely fails (user needs to re-login) */\n onAuthFailure?: () => void | Promise<void>;\n \n /** Called on any API error */\n onError?: (error: ApiErrorResponse, endpoint: string) => void;\n \n /** Custom headers to include in all requests */\n defaultHeaders?: Record<string, string>;\n \n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n \n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport interface RequestOptions {\n /** Skip authentication for this request */\n skipAuth?: boolean;\n \n /** Additional headers for this request */\n headers?: Record<string, string>;\n \n /** AbortController signal for cancellation */\n signal?: AbortSignal;\n \n /** Custom timeout for this request */\n timeout?: number;\n}\n\ninterface RequestConfig extends RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\nexport class TrndUpApiError extends Error {\n constructor(\n public readonly response: ApiErrorResponse,\n public readonly status: number,\n public readonly endpoint: string\n ) {\n super(response.error);\n this.name = 'TrndUpApiError';\n }\n \n get code(): string | undefined {\n return this.response.code;\n }\n\n get metadata(): Record<string, unknown> | undefined {\n return this.response.metadata;\n }\n\n /** Check if error is due to authentication failure */\n isAuthError(): boolean {\n return this.status === 401 || this.code === 'AUTH_EXPIRED' || this.code === 'AUTH_INVALID';\n }\n\n /** Check if error is due to rate limiting */\n isRateLimitError(): boolean {\n return this.status === 429 || this.code === 'RATE_LIMITED';\n }\n}\n\nexport class TrndUpNetworkError extends Error {\n constructor(\n public readonly originalError: Error,\n public readonly endpoint: string\n ) {\n super(`Network error calling ${endpoint}: ${originalError.message}`);\n this.name = 'TrndUpNetworkError';\n }\n}\n\n// =============================================================================\n// BASE CLIENT\n// =============================================================================\n\nexport class TrndUpClient {\n private config: Required<Omit<TrndUpClientConfig, 'onAuthFailure' | 'onError' | 'defaultHeaders' | 'debug'>> & {\n onAuthFailure?: TrndUpClientConfig['onAuthFailure'];\n onError?: TrndUpClientConfig['onError'];\n defaultHeaders?: Record<string, string>;\n debug?: boolean;\n };\n\n // Module instances (imported by subclasses or external modules)\n public auth!: any;\n public youtube!: any;\n public instagram!: any;\n public social!: any;\n public insights!: any;\n\n constructor(config: TrndUpClientConfig) {\n this.config = {\n baseUrl: config.baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n getToken: config.getToken,\n timeout: config.timeout ?? 30000,\n onAuthFailure: config.onAuthFailure,\n onError: config.onError,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug ?? false,\n };\n }\n\n // =============================================================================\n // PUBLIC REQUEST METHODS\n // =============================================================================\n\n async get<T = unknown>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'GET', path, params, ...options });\n }\n\n async post<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'POST', path, body, ...options });\n }\n\n async put<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body, ...options });\n }\n\n async patch<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PATCH', path, body, ...options });\n }\n\n async delete<T = unknown>(\n path: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'DELETE', path, ...options });\n }\n\n // =============================================================================\n // CORE REQUEST LOGIC\n // =============================================================================\n\n private async request<T>(config: RequestConfig): Promise<T> {\n const { method, path, params, body, skipAuth, headers, signal, timeout } = config;\n\n // Build URL\n const url = this.buildUrl(path, params);\n\n // Build headers\n const requestHeaders = await this.buildHeaders(skipAuth, headers);\n\n // Build request init\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n signal,\n };\n\n if (body && method !== 'GET') {\n init.body = JSON.stringify(body);\n }\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout ?? this.config.timeout\n );\n\n try {\n if (this.config.debug) {\n console.log(`[TrndUp SDK] ${method} ${url}`, { body, headers: requestHeaders });\n }\n\n const response = await fetch(url, {\n ...init,\n signal: signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n return await this.handleResponse<T>(response, path);\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof TrndUpApiError) {\n throw error;\n }\n\n // Network error\n const networkError = new TrndUpNetworkError(\n error as Error,\n path\n );\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] Network error:', networkError);\n }\n\n throw networkError;\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private async buildHeaders(\n skipAuth?: boolean,\n additionalHeaders?: Record<string, string>\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.config.defaultHeaders,\n ...additionalHeaders,\n };\n\n // Add Firebase ID token for authentication\n if (!skipAuth) {\n const token = await this.config.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n\n return headers;\n }\n\n private async handleResponse<T>(response: Response, endpoint: string): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n // Try to parse error response\n let errorResponse: ApiErrorResponse;\n\n if (isJson) {\n try {\n const parsed = await response.json();\n errorResponse = parsed as ApiErrorResponse;\n } catch {\n errorResponse = {\n success: false,\n error: response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n } else {\n const text = await response.text();\n errorResponse = {\n success: false,\n error: text || response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n\n const apiError = new TrndUpApiError(errorResponse, response.status, endpoint);\n\n // Call error handler\n if (this.config.onError) {\n this.config.onError(errorResponse, endpoint);\n }\n\n // Call auth failure handler for 401 errors\n if (apiError.isAuthError() && this.config.onAuthFailure) {\n await this.config.onAuthFailure();\n }\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] API error:', apiError);\n }\n\n throw apiError;\n }\n\n // Parse success response\n if (isJson) {\n const parsed = await response.json();\n const jsonResponse = parsed as ApiResponse<T>;\n\n if (jsonResponse.success === false) {\n // This shouldn't happen with 2xx status, but handle it\n throw new TrndUpApiError(jsonResponse, response.status, endpoint);\n }\n\n return (jsonResponse as ApiSuccessResponse<T>).data;\n }\n\n // Non-JSON response\n return (await response.text()) as unknown as T;\n }\n}\n","/**\n * TrndUp SDK - Auth Module\n * \n * Firebase authentication methods with Twilio phone OTP\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Auth } from '../types';\n\nexport class AuthModule {\n constructor(private client: TrndUpClient) {}\n\n // =========================================================================\n // PHONE OTP AUTHENTICATION (via Twilio - no reCAPTCHA needed)\n // =========================================================================\n\n /**\n * Send OTP verification code to phone number\n * POST /auth/phone/send-otp\n * \n * @param phoneNumber - Phone number (E.164 format recommended, e.g., +14155551234)\n */\n async sendOTP(phoneNumber: string): Promise<Auth.SendOTPResponse> {\n return this.client.post<Auth.SendOTPResponse>(\n '/auth/phone/send-otp', \n { phoneNumber }, \n { skipAuth: true }\n );\n }\n\n /**\n * Verify OTP and get Firebase custom token\n * POST /auth/phone/verify-otp\n * \n * After calling this, use Firebase signInWithCustomToken(customToken)\n * to complete authentication on the client.\n * \n * @param phoneNumber - Phone number that received the OTP\n * @param code - 6-digit verification code\n */\n async verifyOTP(phoneNumber: string, code: string): Promise<Auth.VerifyOTPResponse> {\n return this.client.post<Auth.VerifyOTPResponse>(\n '/auth/phone/verify-otp',\n { phoneNumber, code },\n { skipAuth: true }\n );\n }\n\n // =========================================================================\n // FIREBASE ID TOKEN AUTHENTICATION\n // =========================================================================\n\n /**\n * Login with Firebase ID token (for Google, Apple, Email/Password)\n * POST /auth/login\n */\n async login(idToken: string): Promise<Auth.LoginResponse> {\n return this.client.post<Auth.LoginResponse>('/auth/login', { idToken }, { skipAuth: true });\n }\n\n /**\n * Get current authenticated user's profile\n * GET /auth/me\n */\n async getCurrentUser(): Promise<Auth.CurrentUserResponse> {\n return this.client.get<Auth.CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Update user profile\n * PATCH /auth/me\n */\n async updateProfile(data: Auth.UpdateProfileRequest): Promise<Auth.UpdateProfileResponse> {\n return this.client.patch<Auth.UpdateProfileResponse>('/auth/me', data);\n }\n\n /**\n * Logout (acknowledge logout on backend)\n * POST /auth/logout\n */\n async logout(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/auth/logout');\n }\n\n /**\n * Check auth service status\n * GET /auth/status\n */\n async getStatus(): Promise<{ success: boolean; message: string }> {\n return this.client.get('/auth/status', undefined, { skipAuth: true });\n }\n\n /**\n * Get user's platform connection status\n * GET /user/platforms/status\n */\n async getPlatformStatus(): Promise<Auth.PlatformStatus> {\n return this.client.get<Auth.PlatformStatus>('/user/platforms/status');\n }\n}\n","/**\n * TrndUp SDK - YouTube Module\n * \n * YouTube analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { YouTube } from '../types';\n\nexport class YouTubeModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get YouTube initialization status\n * Check if user needs to init or has already synced\n * \n * GET /v1/platforms/youtube/init/status\n */\n async getInitStatus(): Promise<YouTube.InitStatusResponse> {\n return this.client.get<YouTube.InitStatusResponse>('/v1/platforms/youtube/init/status');\n }\n\n /**\n * Initialize YouTube data sync\n * Fetches all channel info and videos, stores in database\n * Returns channel info, video counts, and oldest video date for analytics\n * \n * POST /v1/platforms/youtube/init\n */\n async initialize(): Promise<YouTube.InitResponse> {\n return this.client.post<YouTube.InitResponse>('/v1/platforms/youtube/init');\n }\n\n /**\n * Get YouTube videos\n * GET /v1/platforms/youtube/videos\n */\n async getVideos(params?: YouTube.GetVideosParams): Promise<YouTube.GetVideosResponse> {\n return this.client.get<YouTube.GetVideosResponse>(\n '/v1/platforms/youtube/videos', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific video by ID\n * GET /v1/platforms/youtube/videos/:videoId\n */\n async getVideo(videoId: string): Promise<YouTube.Video> {\n return this.client.get<YouTube.Video>(`/v1/platforms/youtube/videos/${videoId}`);\n }\n\n /**\n * Get channel metrics\n * GET /v1/platforms/youtube/channel/metrics\n */\n async getChannelMetrics(): Promise<YouTube.ChannelMetrics> {\n return this.client.get<YouTube.ChannelMetrics>('/v1/platforms/youtube/channel/metrics');\n }\n\n /**\n * Get channel health score\n * GET /v1/platforms/youtube/health\n */\n async getHealthScore(params?: YouTube.GetHealthScoreParams): Promise<YouTube.HealthScore> {\n return this.client.get<YouTube.HealthScore>(\n '/v1/platforms/youtube/health', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Refresh YouTube data\n * POST /v1/platforms/youtube/refresh\n */\n async refresh(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/refresh');\n }\n}\n","/**\n * TrndUp SDK - Instagram Module\n * \n * Instagram analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Instagram } from '../types';\n\nexport class InstagramModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get Instagram initialization status\n * GET /v1/platforms/instagram/init/status\n */\n async getInitStatus(): Promise<Instagram.InitStatusResponse> {\n return this.client.get<Instagram.InitStatusResponse>('/v1/platforms/instagram/init/status');\n }\n\n /**\n * Initialize Instagram data sync\n * POST /v1/platforms/instagram/init\n */\n async initialize(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/init');\n }\n\n /**\n * Get Instagram posts\n * GET /v1/platforms/instagram/posts\n */\n async getPosts(params?: Instagram.GetPostsParams): Promise<Instagram.GetPostsResponse> {\n return this.client.get<Instagram.GetPostsResponse>(\n '/v1/platforms/instagram/posts', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific post by ID\n * GET /v1/platforms/instagram/posts/:postId\n */\n async getPost(postId: string): Promise<Instagram.Post> {\n return this.client.get<Instagram.Post>(`/v1/platforms/instagram/posts/${postId}`);\n }\n\n /**\n * Get account metrics\n * GET /v1/platforms/instagram/account/metrics\n */\n async getAccountMetrics(): Promise<Instagram.AccountMetrics> {\n return this.client.get<Instagram.AccountMetrics>('/v1/platforms/instagram/account/metrics');\n }\n\n /**\n * Refresh Instagram data\n * POST /v1/platforms/instagram/refresh\n */\n async refresh(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/refresh');\n }\n}\n","/**\n * TrndUp SDK - Social Module\n * \n * Social account linking methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Social } from '../types';\n\nexport class SocialModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Link YouTube account\n * POST /social/link/youtube\n */\n async linkYouTube(data: Social.LinkYouTubeRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/youtube', data);\n }\n\n /**\n * Link Instagram account\n * POST /social/link/instagram\n */\n async linkInstagram(data: Social.LinkInstagramRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/instagram', data);\n }\n\n /**\n * Get all connected social accounts\n * GET /social/accounts\n */\n async getConnectedAccounts(): Promise<Social.ConnectedAccount[]> {\n return this.client.get<Social.ConnectedAccount[]>('/social/accounts');\n }\n\n /**\n * Unlink a social account\n * DELETE /social/unlink/:provider\n */\n async unlinkAccount(provider: string): Promise<{ message: string }> {\n return this.client.delete<{ message: string }>(`/social/unlink/${provider}`);\n }\n}\n","/**\n * TrndUp SDK - Insights Module\n * \n * Cross-platform insights and analytics\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Insights } from '../types';\n\nexport class InsightsModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get cross-platform metrics\n * GET /v1/insights/overview\n */\n async getOverview(): Promise<Insights.CrossPlatformMetrics> {\n return this.client.get<Insights.CrossPlatformMetrics>('/v1/insights/overview');\n }\n\n /**\n * Get trending content across all platforms\n * GET /v1/insights/trending\n */\n async getTrending(): Promise<Insights.TrendingContent> {\n return this.client.get<Insights.TrendingContent>('/v1/insights/trending');\n }\n}\n","/**\n * TrndUp SDK Types\n * \n * Type definitions for the TrndUp API SDK\n */\n\n// =============================================================================\n// OAUTH SCOPES\n// =============================================================================\n\n/**\n * Required OAuth scopes for YouTube account linking\n * Use these when configuring Google Sign-In in your mobile app\n * \n * @example\n * ```typescript\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * import { YOUTUBE_SCOPES } from '@trndup/sdk';\n * \n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * ```\n */\nexport const YOUTUBE_SCOPES = [\n 'openid',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/youtube.readonly',\n 'https://www.googleapis.com/auth/yt-analytics.readonly',\n 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',\n 'https://www.googleapis.com/auth/youtube.force-ssl',\n 'https://www.googleapis.com/auth/youtubepartner'\n];\n\n/**\n * Required OAuth scopes for Instagram account linking\n */\nexport const INSTAGRAM_SCOPES = [\n 'instagram_business_basic',\n 'instagram_business_manage_insights',\n 'instagram_business_manage_comments'\n];\n\n// =============================================================================\n// API RESPONSE WRAPPER\n// =============================================================================\n\nexport interface ApiSuccessResponse<T = unknown> {\n success: true;\n data: T;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: string;\n code?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// =============================================================================\n// AUTH TYPES\n// =============================================================================\n\nexport namespace Auth {\n export interface User {\n id: string;\n firebaseUid?: string;\n email?: string;\n phoneNumber?: string;\n username: string;\n picture?: string;\n emailVerified?: boolean;\n signInProvider?: string; // 'phone', 'google.com', 'password', 'apple.com'\n createdAt: string;\n updatedAt: string;\n }\n\n export interface SocialAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n }\n\n // Phone OTP Authentication (Twilio)\n export interface SendOTPRequest {\n phoneNumber: string;\n }\n\n export interface SendOTPResponse {\n message: string;\n expiresIn: number;\n }\n\n export interface VerifyOTPRequest {\n phoneNumber: string;\n code: string;\n }\n\n export interface VerifyOTPResponse {\n customToken: string;\n isNewUser: boolean;\n user: User;\n platformStatus: PlatformStatus;\n }\n\n // Firebase ID Token Login\n export interface LoginRequest {\n idToken: string;\n }\n\n export interface LoginResponse {\n user: User;\n platformStatus: PlatformStatus;\n idToken: string;\n }\n\n export interface CurrentUserResponse {\n user: User;\n socialAccounts: SocialAccount[];\n }\n\n export interface UpdateProfileRequest {\n username?: string;\n picture?: string;\n }\n\n export interface UpdateProfileResponse {\n user: User;\n }\n\n export interface PlatformStatus {\n hasConnectedPlatforms: boolean;\n connectedPlatforms: Array<'youtube' | 'instagram'>;\n }\n}\n\n// =============================================================================\n// SOCIAL TYPES\n// =============================================================================\n\nexport namespace Social {\n /**\n * Link YouTube account request\n * \n * Two options:\n * 1. serverAuthCode (recommended): Backend exchanges for tokens with proper expiry\n * 2. Direct tokens: Frontend provides accessToken (expiresAt defaults to 1 hour)\n */\n export interface LinkYouTubeRequest {\n idToken: string; // Google ID token for verification (always required)\n serverAuthCode?: string; // Google server auth code - backend exchanges for tokens (recommended)\n accessToken?: string; // Google access token (alternative to serverAuthCode)\n refreshToken?: string; // Google refresh token (only with accessToken flow)\n expiresAt?: number; // Token expiry timestamp in ms (only with accessToken flow)\n grantedScopes?: string; // Actual scopes user granted (space-separated)\n platform?: string; // 'ios' | 'android' | 'web'\n environment?: string; // 'development' | 'production'\n }\n\n export interface LinkInstagramRequest {\n accessToken: string;\n }\n\n export interface LinkAccountResponse {\n message: string;\n provider: string;\n accountName?: string;\n }\n\n export interface ConnectedAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n lastSyncAt?: string;\n }\n}\n\n// =============================================================================\n// YOUTUBE TYPES\n// =============================================================================\n\nexport namespace YouTube {\n /**\n * Response from GET /v1/platforms/youtube/init/status\n */\n export interface InitStatusResponse {\n needsInit: boolean;\n status: 'NEVER_SYNCED' | 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';\n lastSyncAt: string | null;\n videoCount: number;\n oldestVideoDate: string | null;\n analyticsStartDate: string | null;\n }\n\n /**\n * Response from POST /v1/platforms/youtube/init\n */\n export interface InitResponse {\n channel: {\n channelId: string;\n channelTitle: string;\n subscriberCount: number;\n videoCount: number;\n viewCount: number;\n };\n videos: {\n total: number;\n synced: number;\n oldestVideoDate: string | null;\n };\n syncStatus: {\n isFirstSync: boolean;\n lastSyncAt: string | null;\n };\n }\n\n export interface Video {\n id: string;\n videoId: string;\n title: string;\n description?: string;\n thumbnailUrl?: string;\n publishedAt: string;\n duration?: number;\n viewCount?: number;\n likeCount?: number;\n commentCount?: number;\n engagementRate?: number;\n }\n\n export interface GetVideosParams {\n limit?: number;\n offset?: number;\n sortBy?: 'recent' | 'views' | 'engagement';\n }\n\n export interface GetVideosResponse {\n videos: Video[];\n total: number;\n hasMore: boolean;\n }\n\n export interface ChannelMetrics {\n subscriberCount: number;\n totalViews: number;\n totalVideos: number;\n averageViews: number;\n engagementRate: number;\n }\n\n export interface HealthScore {\n score: number;\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n metrics: {\n consistency: number;\n engagement: number;\n growth: number;\n quality: number;\n };\n }\n\n export interface GetHealthScoreParams {\n range?: string; // e.g., '7d', '30d', '90d'\n }\n}\n\n// =============================================================================\n// INSTAGRAM TYPES\n// =============================================================================\n\nexport namespace Instagram {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n postCount?: number;\n accountId?: string;\n username?: string;\n }\n\n export interface Post {\n id: string;\n caption?: string;\n mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM';\n mediaUrl: string;\n permalink: string;\n timestamp: string;\n likeCount?: number;\n commentsCount?: number;\n engagementRate?: number;\n }\n\n export interface GetPostsParams {\n limit?: number;\n offset?: number;\n }\n\n export interface GetPostsResponse {\n posts: Post[];\n total: number;\n hasMore: boolean;\n }\n\n export interface AccountMetrics {\n followersCount: number;\n followsCount: number;\n mediaCount: number;\n averageLikes: number;\n engagementRate: number;\n }\n}\n\n// =============================================================================\n// INSIGHTS TYPES\n// =============================================================================\n\nexport namespace Insights {\n export interface CrossPlatformMetrics {\n totalFollowers: number;\n totalEngagement: number;\n platforms: {\n youtube?: {\n subscribers: number;\n views: number;\n videos: number;\n };\n instagram?: {\n followers: number;\n posts: number;\n avgEngagement: number;\n };\n };\n }\n\n export interface TrendingContent {\n youtube?: YouTube.Video[];\n instagram?: Instagram.Post[];\n }\n}\n","/**\n * TrndUp API SDK\n * \n * Official TypeScript SDK for the TrndUp API.\n * Provides type-safe methods for all API endpoints with Firebase authentication.\n * \n * @example\n * ```typescript\n * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';\n * import auth from '@react-native-firebase/auth';\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * \n * // Configure Google Sign-In with YouTube scopes\n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * \n * const sdk = new TrndUpSDK({\n * baseUrl: 'https://api.trndup.app',\n * getToken: async () => {\n * const user = auth().currentUser;\n * return user ? await user.getIdToken() : null;\n * },\n * onAuthFailure: () => {\n * // Handle auth failure - navigate to login\n * navigation.navigate('Login');\n * },\n * });\n * \n * // Type-safe API calls\n * const user = await sdk.auth.getCurrentUser();\n * const videos = await sdk.youtube.getVideos({ limit: 10 });\n * const healthScore = await sdk.youtube.getHealthScore({ range: '30d' });\n * ```\n */\n\nimport { TrndUpClient, TrndUpClientConfig } from './client';\nimport { AuthModule } from './modules/auth';\nimport { YouTubeModule } from './modules/youtube';\nimport { InstagramModule } from './modules/instagram';\nimport { SocialModule } from './modules/social';\nimport { InsightsModule } from './modules/insights';\n\nexport class TrndUpSDK extends TrndUpClient {\n public auth: AuthModule;\n public youtube: YouTubeModule;\n public instagram: InstagramModule;\n public social: SocialModule;\n public insights: InsightsModule;\n\n constructor(config: TrndUpClientConfig) {\n super(config);\n\n // Initialize all modules\n this.auth = new AuthModule(this);\n this.youtube = new YouTubeModule(this);\n this.instagram = new InstagramModule(this);\n this.social = new SocialModule(this);\n this.insights = new InsightsModule(this);\n }\n}\n\n// Re-export types and classes\nexport type { TrndUpClientConfig, RequestOptions } from './client';\nexport { TrndUpApiError, TrndUpNetworkError } from './client';\n\n// Re-export all type namespaces\nexport type { Auth, Social, YouTube, Instagram, Insights } from './types';\n\n// Re-export OAuth scopes for configuring Google Sign-In\nexport { YOUTUBE_SCOPES, INSTAGRAM_SCOPES } from './types';\n\n// Version\nexport const SDK_VERSION = '1.0.0';\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -271,6 +271,8 @@ var YouTubeModule = class {
|
|
|
271
271
|
}
|
|
272
272
|
/**
|
|
273
273
|
* Get YouTube initialization status
|
|
274
|
+
* Check if user needs to init or has already synced
|
|
275
|
+
*
|
|
274
276
|
* GET /v1/platforms/youtube/init/status
|
|
275
277
|
*/
|
|
276
278
|
async getInitStatus() {
|
|
@@ -278,6 +280,9 @@ var YouTubeModule = class {
|
|
|
278
280
|
}
|
|
279
281
|
/**
|
|
280
282
|
* Initialize YouTube data sync
|
|
283
|
+
* Fetches all channel info and videos, stores in database
|
|
284
|
+
* Returns channel info, video counts, and oldest video date for analytics
|
|
285
|
+
*
|
|
281
286
|
* POST /v1/platforms/youtube/init
|
|
282
287
|
*/
|
|
283
288
|
async initialize() {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../client.ts","../modules/auth.ts","../modules/youtube.ts","../modules/instagram.ts","../modules/social.ts","../modules/insights.ts","../types.ts","../index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TrndUp SDK - Base Client\n * \n * Core HTTP client with Firebase authentication support,\n * error handling, and automatic retries.\n */\n\nimport type { ApiResponse, ApiErrorResponse, ApiSuccessResponse } from './types';\n\n// =============================================================================\n// CONFIGURATION\n// =============================================================================\n\nexport interface TrndUpClientConfig {\n /** Base URL for the API (e.g., 'https://api.trndup.app' or 'http://localhost:3000') */\n baseUrl: string;\n \n /** Function to get the current Firebase ID token */\n getToken: () => string | null | Promise<string | null>;\n \n /** Called when auth completely fails (user needs to re-login) */\n onAuthFailure?: () => void | Promise<void>;\n \n /** Called on any API error */\n onError?: (error: ApiErrorResponse, endpoint: string) => void;\n \n /** Custom headers to include in all requests */\n defaultHeaders?: Record<string, string>;\n \n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n \n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport interface RequestOptions {\n /** Skip authentication for this request */\n skipAuth?: boolean;\n \n /** Additional headers for this request */\n headers?: Record<string, string>;\n \n /** AbortController signal for cancellation */\n signal?: AbortSignal;\n \n /** Custom timeout for this request */\n timeout?: number;\n}\n\ninterface RequestConfig extends RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\nexport class TrndUpApiError extends Error {\n constructor(\n public readonly response: ApiErrorResponse,\n public readonly status: number,\n public readonly endpoint: string\n ) {\n super(response.error);\n this.name = 'TrndUpApiError';\n }\n \n get code(): string | undefined {\n return this.response.code;\n }\n\n get metadata(): Record<string, unknown> | undefined {\n return this.response.metadata;\n }\n\n /** Check if error is due to authentication failure */\n isAuthError(): boolean {\n return this.status === 401 || this.code === 'AUTH_EXPIRED' || this.code === 'AUTH_INVALID';\n }\n\n /** Check if error is due to rate limiting */\n isRateLimitError(): boolean {\n return this.status === 429 || this.code === 'RATE_LIMITED';\n }\n}\n\nexport class TrndUpNetworkError extends Error {\n constructor(\n public readonly originalError: Error,\n public readonly endpoint: string\n ) {\n super(`Network error calling ${endpoint}: ${originalError.message}`);\n this.name = 'TrndUpNetworkError';\n }\n}\n\n// =============================================================================\n// BASE CLIENT\n// =============================================================================\n\nexport class TrndUpClient {\n private config: Required<Omit<TrndUpClientConfig, 'onAuthFailure' | 'onError' | 'defaultHeaders' | 'debug'>> & {\n onAuthFailure?: TrndUpClientConfig['onAuthFailure'];\n onError?: TrndUpClientConfig['onError'];\n defaultHeaders?: Record<string, string>;\n debug?: boolean;\n };\n\n // Module instances (imported by subclasses or external modules)\n public auth!: any;\n public youtube!: any;\n public instagram!: any;\n public social!: any;\n public insights!: any;\n\n constructor(config: TrndUpClientConfig) {\n this.config = {\n baseUrl: config.baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n getToken: config.getToken,\n timeout: config.timeout ?? 30000,\n onAuthFailure: config.onAuthFailure,\n onError: config.onError,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug ?? false,\n };\n }\n\n // =============================================================================\n // PUBLIC REQUEST METHODS\n // =============================================================================\n\n async get<T = unknown>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'GET', path, params, ...options });\n }\n\n async post<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'POST', path, body, ...options });\n }\n\n async put<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body, ...options });\n }\n\n async patch<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PATCH', path, body, ...options });\n }\n\n async delete<T = unknown>(\n path: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'DELETE', path, ...options });\n }\n\n // =============================================================================\n // CORE REQUEST LOGIC\n // =============================================================================\n\n private async request<T>(config: RequestConfig): Promise<T> {\n const { method, path, params, body, skipAuth, headers, signal, timeout } = config;\n\n // Build URL\n const url = this.buildUrl(path, params);\n\n // Build headers\n const requestHeaders = await this.buildHeaders(skipAuth, headers);\n\n // Build request init\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n signal,\n };\n\n if (body && method !== 'GET') {\n init.body = JSON.stringify(body);\n }\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout ?? this.config.timeout\n );\n\n try {\n if (this.config.debug) {\n console.log(`[TrndUp SDK] ${method} ${url}`, { body, headers: requestHeaders });\n }\n\n const response = await fetch(url, {\n ...init,\n signal: signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n return await this.handleResponse<T>(response, path);\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof TrndUpApiError) {\n throw error;\n }\n\n // Network error\n const networkError = new TrndUpNetworkError(\n error as Error,\n path\n );\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] Network error:', networkError);\n }\n\n throw networkError;\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private async buildHeaders(\n skipAuth?: boolean,\n additionalHeaders?: Record<string, string>\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.config.defaultHeaders,\n ...additionalHeaders,\n };\n\n // Add Firebase ID token for authentication\n if (!skipAuth) {\n const token = await this.config.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n\n return headers;\n }\n\n private async handleResponse<T>(response: Response, endpoint: string): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n // Try to parse error response\n let errorResponse: ApiErrorResponse;\n\n if (isJson) {\n try {\n const parsed = await response.json();\n errorResponse = parsed as ApiErrorResponse;\n } catch {\n errorResponse = {\n success: false,\n error: response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n } else {\n const text = await response.text();\n errorResponse = {\n success: false,\n error: text || response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n\n const apiError = new TrndUpApiError(errorResponse, response.status, endpoint);\n\n // Call error handler\n if (this.config.onError) {\n this.config.onError(errorResponse, endpoint);\n }\n\n // Call auth failure handler for 401 errors\n if (apiError.isAuthError() && this.config.onAuthFailure) {\n await this.config.onAuthFailure();\n }\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] API error:', apiError);\n }\n\n throw apiError;\n }\n\n // Parse success response\n if (isJson) {\n const parsed = await response.json();\n const jsonResponse = parsed as ApiResponse<T>;\n\n if (jsonResponse.success === false) {\n // This shouldn't happen with 2xx status, but handle it\n throw new TrndUpApiError(jsonResponse, response.status, endpoint);\n }\n\n return (jsonResponse as ApiSuccessResponse<T>).data;\n }\n\n // Non-JSON response\n return (await response.text()) as unknown as T;\n }\n}\n","/**\n * TrndUp SDK - Auth Module\n * \n * Firebase authentication methods with Twilio phone OTP\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Auth } from '../types';\n\nexport class AuthModule {\n constructor(private client: TrndUpClient) {}\n\n // =========================================================================\n // PHONE OTP AUTHENTICATION (via Twilio - no reCAPTCHA needed)\n // =========================================================================\n\n /**\n * Send OTP verification code to phone number\n * POST /auth/phone/send-otp\n * \n * @param phoneNumber - Phone number (E.164 format recommended, e.g., +14155551234)\n */\n async sendOTP(phoneNumber: string): Promise<Auth.SendOTPResponse> {\n return this.client.post<Auth.SendOTPResponse>(\n '/auth/phone/send-otp', \n { phoneNumber }, \n { skipAuth: true }\n );\n }\n\n /**\n * Verify OTP and get Firebase custom token\n * POST /auth/phone/verify-otp\n * \n * After calling this, use Firebase signInWithCustomToken(customToken)\n * to complete authentication on the client.\n * \n * @param phoneNumber - Phone number that received the OTP\n * @param code - 6-digit verification code\n */\n async verifyOTP(phoneNumber: string, code: string): Promise<Auth.VerifyOTPResponse> {\n return this.client.post<Auth.VerifyOTPResponse>(\n '/auth/phone/verify-otp',\n { phoneNumber, code },\n { skipAuth: true }\n );\n }\n\n // =========================================================================\n // FIREBASE ID TOKEN AUTHENTICATION\n // =========================================================================\n\n /**\n * Login with Firebase ID token (for Google, Apple, Email/Password)\n * POST /auth/login\n */\n async login(idToken: string): Promise<Auth.LoginResponse> {\n return this.client.post<Auth.LoginResponse>('/auth/login', { idToken }, { skipAuth: true });\n }\n\n /**\n * Get current authenticated user's profile\n * GET /auth/me\n */\n async getCurrentUser(): Promise<Auth.CurrentUserResponse> {\n return this.client.get<Auth.CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Update user profile\n * PATCH /auth/me\n */\n async updateProfile(data: Auth.UpdateProfileRequest): Promise<Auth.UpdateProfileResponse> {\n return this.client.patch<Auth.UpdateProfileResponse>('/auth/me', data);\n }\n\n /**\n * Logout (acknowledge logout on backend)\n * POST /auth/logout\n */\n async logout(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/auth/logout');\n }\n\n /**\n * Check auth service status\n * GET /auth/status\n */\n async getStatus(): Promise<{ success: boolean; message: string }> {\n return this.client.get('/auth/status', undefined, { skipAuth: true });\n }\n\n /**\n * Get user's platform connection status\n * GET /user/platforms/status\n */\n async getPlatformStatus(): Promise<Auth.PlatformStatus> {\n return this.client.get<Auth.PlatformStatus>('/user/platforms/status');\n }\n}\n","/**\n * TrndUp SDK - YouTube Module\n * \n * YouTube analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { YouTube } from '../types';\n\nexport class YouTubeModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get YouTube initialization status\n * GET /v1/platforms/youtube/init/status\n */\n async getInitStatus(): Promise<YouTube.InitStatusResponse> {\n return this.client.get<YouTube.InitStatusResponse>('/v1/platforms/youtube/init/status');\n }\n\n /**\n * Initialize YouTube data sync\n * POST /v1/platforms/youtube/init\n */\n async initialize(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/init');\n }\n\n /**\n * Get YouTube videos\n * GET /v1/platforms/youtube/videos\n */\n async getVideos(params?: YouTube.GetVideosParams): Promise<YouTube.GetVideosResponse> {\n return this.client.get<YouTube.GetVideosResponse>(\n '/v1/platforms/youtube/videos', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific video by ID\n * GET /v1/platforms/youtube/videos/:videoId\n */\n async getVideo(videoId: string): Promise<YouTube.Video> {\n return this.client.get<YouTube.Video>(`/v1/platforms/youtube/videos/${videoId}`);\n }\n\n /**\n * Get channel metrics\n * GET /v1/platforms/youtube/channel/metrics\n */\n async getChannelMetrics(): Promise<YouTube.ChannelMetrics> {\n return this.client.get<YouTube.ChannelMetrics>('/v1/platforms/youtube/channel/metrics');\n }\n\n /**\n * Get channel health score\n * GET /v1/platforms/youtube/health\n */\n async getHealthScore(params?: YouTube.GetHealthScoreParams): Promise<YouTube.HealthScore> {\n return this.client.get<YouTube.HealthScore>(\n '/v1/platforms/youtube/health', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Refresh YouTube data\n * POST /v1/platforms/youtube/refresh\n */\n async refresh(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/refresh');\n }\n}\n","/**\n * TrndUp SDK - Instagram Module\n * \n * Instagram analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Instagram } from '../types';\n\nexport class InstagramModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get Instagram initialization status\n * GET /v1/platforms/instagram/init/status\n */\n async getInitStatus(): Promise<Instagram.InitStatusResponse> {\n return this.client.get<Instagram.InitStatusResponse>('/v1/platforms/instagram/init/status');\n }\n\n /**\n * Initialize Instagram data sync\n * POST /v1/platforms/instagram/init\n */\n async initialize(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/init');\n }\n\n /**\n * Get Instagram posts\n * GET /v1/platforms/instagram/posts\n */\n async getPosts(params?: Instagram.GetPostsParams): Promise<Instagram.GetPostsResponse> {\n return this.client.get<Instagram.GetPostsResponse>(\n '/v1/platforms/instagram/posts', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific post by ID\n * GET /v1/platforms/instagram/posts/:postId\n */\n async getPost(postId: string): Promise<Instagram.Post> {\n return this.client.get<Instagram.Post>(`/v1/platforms/instagram/posts/${postId}`);\n }\n\n /**\n * Get account metrics\n * GET /v1/platforms/instagram/account/metrics\n */\n async getAccountMetrics(): Promise<Instagram.AccountMetrics> {\n return this.client.get<Instagram.AccountMetrics>('/v1/platforms/instagram/account/metrics');\n }\n\n /**\n * Refresh Instagram data\n * POST /v1/platforms/instagram/refresh\n */\n async refresh(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/refresh');\n }\n}\n","/**\n * TrndUp SDK - Social Module\n * \n * Social account linking methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Social } from '../types';\n\nexport class SocialModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Link YouTube account\n * POST /social/link/youtube\n */\n async linkYouTube(data: Social.LinkYouTubeRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/youtube', data);\n }\n\n /**\n * Link Instagram account\n * POST /social/link/instagram\n */\n async linkInstagram(data: Social.LinkInstagramRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/instagram', data);\n }\n\n /**\n * Get all connected social accounts\n * GET /social/accounts\n */\n async getConnectedAccounts(): Promise<Social.ConnectedAccount[]> {\n return this.client.get<Social.ConnectedAccount[]>('/social/accounts');\n }\n\n /**\n * Unlink a social account\n * DELETE /social/unlink/:provider\n */\n async unlinkAccount(provider: string): Promise<{ message: string }> {\n return this.client.delete<{ message: string }>(`/social/unlink/${provider}`);\n }\n}\n","/**\n * TrndUp SDK - Insights Module\n * \n * Cross-platform insights and analytics\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Insights } from '../types';\n\nexport class InsightsModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get cross-platform metrics\n * GET /v1/insights/overview\n */\n async getOverview(): Promise<Insights.CrossPlatformMetrics> {\n return this.client.get<Insights.CrossPlatformMetrics>('/v1/insights/overview');\n }\n\n /**\n * Get trending content across all platforms\n * GET /v1/insights/trending\n */\n async getTrending(): Promise<Insights.TrendingContent> {\n return this.client.get<Insights.TrendingContent>('/v1/insights/trending');\n }\n}\n","/**\n * TrndUp SDK Types\n * \n * Type definitions for the TrndUp API SDK\n */\n\n// =============================================================================\n// OAUTH SCOPES\n// =============================================================================\n\n/**\n * Required OAuth scopes for YouTube account linking\n * Use these when configuring Google Sign-In in your mobile app\n * \n * @example\n * ```typescript\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * import { YOUTUBE_SCOPES } from '@trndup/sdk';\n * \n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * ```\n */\nexport const YOUTUBE_SCOPES = [\n 'openid',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/youtube.readonly',\n 'https://www.googleapis.com/auth/yt-analytics.readonly',\n 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',\n 'https://www.googleapis.com/auth/youtube.force-ssl',\n 'https://www.googleapis.com/auth/youtubepartner'\n];\n\n/**\n * Required OAuth scopes for Instagram account linking\n */\nexport const INSTAGRAM_SCOPES = [\n 'instagram_business_basic',\n 'instagram_business_manage_insights',\n 'instagram_business_manage_comments'\n];\n\n// =============================================================================\n// API RESPONSE WRAPPER\n// =============================================================================\n\nexport interface ApiSuccessResponse<T = unknown> {\n success: true;\n data: T;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: string;\n code?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// =============================================================================\n// AUTH TYPES\n// =============================================================================\n\nexport namespace Auth {\n export interface User {\n id: string;\n firebaseUid?: string;\n email?: string;\n phoneNumber?: string;\n username: string;\n picture?: string;\n emailVerified?: boolean;\n signInProvider?: string; // 'phone', 'google.com', 'password', 'apple.com'\n createdAt: string;\n updatedAt: string;\n }\n\n export interface SocialAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n }\n\n // Phone OTP Authentication (Twilio)\n export interface SendOTPRequest {\n phoneNumber: string;\n }\n\n export interface SendOTPResponse {\n message: string;\n expiresIn: number;\n }\n\n export interface VerifyOTPRequest {\n phoneNumber: string;\n code: string;\n }\n\n export interface VerifyOTPResponse {\n customToken: string;\n isNewUser: boolean;\n user: User;\n platformStatus: PlatformStatus;\n }\n\n // Firebase ID Token Login\n export interface LoginRequest {\n idToken: string;\n }\n\n export interface LoginResponse {\n user: User;\n platformStatus: PlatformStatus;\n idToken: string;\n }\n\n export interface CurrentUserResponse {\n user: User;\n socialAccounts: SocialAccount[];\n }\n\n export interface UpdateProfileRequest {\n username?: string;\n picture?: string;\n }\n\n export interface UpdateProfileResponse {\n user: User;\n }\n\n export interface PlatformStatus {\n hasConnectedPlatforms: boolean;\n connectedPlatforms: Array<'youtube' | 'instagram'>;\n }\n}\n\n// =============================================================================\n// SOCIAL TYPES\n// =============================================================================\n\nexport namespace Social {\n export interface LinkYouTubeRequest {\n idToken: string; // Google ID token for verification\n accessToken: string; // Google access token for API calls\n refreshToken?: string; // Google refresh token (recommended)\n expiresAt?: number; // Token expiry timestamp (ms since epoch)\n grantedScopes?: string; // Actual scopes user granted (space-separated)\n platform?: string; // 'ios' | 'android' | 'web'\n environment?: string; // 'development' | 'production'\n }\n\n export interface LinkInstagramRequest {\n accessToken: string;\n }\n\n export interface LinkAccountResponse {\n message: string;\n provider: string;\n accountName?: string;\n }\n\n export interface ConnectedAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n lastSyncAt?: string;\n }\n}\n\n// =============================================================================\n// YOUTUBE TYPES\n// =============================================================================\n\nexport namespace YouTube {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n videoCount?: number;\n channelId?: string;\n channelTitle?: string;\n }\n\n export interface Video {\n id: string;\n title: string;\n description?: string;\n thumbnailUrl?: string;\n publishedAt: string;\n duration?: string;\n viewCount?: number;\n likeCount?: number;\n commentCount?: number;\n engagementRate?: number;\n }\n\n export interface GetVideosParams {\n limit?: number;\n offset?: number;\n sortBy?: 'recent' | 'views' | 'engagement';\n }\n\n export interface GetVideosResponse {\n videos: Video[];\n total: number;\n hasMore: boolean;\n }\n\n export interface ChannelMetrics {\n subscriberCount: number;\n totalViews: number;\n totalVideos: number;\n averageViews: number;\n engagementRate: number;\n }\n\n export interface HealthScore {\n score: number;\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n metrics: {\n consistency: number;\n engagement: number;\n growth: number;\n quality: number;\n };\n }\n\n export interface GetHealthScoreParams {\n range?: string; // e.g., '7d', '30d', '90d'\n }\n}\n\n// =============================================================================\n// INSTAGRAM TYPES\n// =============================================================================\n\nexport namespace Instagram {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n postCount?: number;\n accountId?: string;\n username?: string;\n }\n\n export interface Post {\n id: string;\n caption?: string;\n mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM';\n mediaUrl: string;\n permalink: string;\n timestamp: string;\n likeCount?: number;\n commentsCount?: number;\n engagementRate?: number;\n }\n\n export interface GetPostsParams {\n limit?: number;\n offset?: number;\n }\n\n export interface GetPostsResponse {\n posts: Post[];\n total: number;\n hasMore: boolean;\n }\n\n export interface AccountMetrics {\n followersCount: number;\n followsCount: number;\n mediaCount: number;\n averageLikes: number;\n engagementRate: number;\n }\n}\n\n// =============================================================================\n// INSIGHTS TYPES\n// =============================================================================\n\nexport namespace Insights {\n export interface CrossPlatformMetrics {\n totalFollowers: number;\n totalEngagement: number;\n platforms: {\n youtube?: {\n subscribers: number;\n views: number;\n videos: number;\n };\n instagram?: {\n followers: number;\n posts: number;\n avgEngagement: number;\n };\n };\n }\n\n export interface TrendingContent {\n youtube?: YouTube.Video[];\n instagram?: Instagram.Post[];\n }\n}\n","/**\n * TrndUp API SDK\n * \n * Official TypeScript SDK for the TrndUp API.\n * Provides type-safe methods for all API endpoints with Firebase authentication.\n * \n * @example\n * ```typescript\n * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';\n * import auth from '@react-native-firebase/auth';\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * \n * // Configure Google Sign-In with YouTube scopes\n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * \n * const sdk = new TrndUpSDK({\n * baseUrl: 'https://api.trndup.app',\n * getToken: async () => {\n * const user = auth().currentUser;\n * return user ? await user.getIdToken() : null;\n * },\n * onAuthFailure: () => {\n * // Handle auth failure - navigate to login\n * navigation.navigate('Login');\n * },\n * });\n * \n * // Type-safe API calls\n * const user = await sdk.auth.getCurrentUser();\n * const videos = await sdk.youtube.getVideos({ limit: 10 });\n * const healthScore = await sdk.youtube.getHealthScore({ range: '30d' });\n * ```\n */\n\nimport { TrndUpClient, TrndUpClientConfig } from './client';\nimport { AuthModule } from './modules/auth';\nimport { YouTubeModule } from './modules/youtube';\nimport { InstagramModule } from './modules/instagram';\nimport { SocialModule } from './modules/social';\nimport { InsightsModule } from './modules/insights';\n\nexport class TrndUpSDK extends TrndUpClient {\n public auth: AuthModule;\n public youtube: YouTubeModule;\n public instagram: InstagramModule;\n public social: SocialModule;\n public insights: InsightsModule;\n\n constructor(config: TrndUpClientConfig) {\n super(config);\n\n // Initialize all modules\n this.auth = new AuthModule(this);\n this.youtube = new YouTubeModule(this);\n this.instagram = new InstagramModule(this);\n this.social = new SocialModule(this);\n this.insights = new InsightsModule(this);\n }\n}\n\n// Re-export types and classes\nexport type { TrndUpClientConfig, RequestOptions } from './client';\nexport { TrndUpApiError, TrndUpNetworkError } from './client';\n\n// Re-export all type namespaces\nexport type { Auth, Social, YouTube, Instagram, Insights } from './types';\n\n// Re-export OAuth scopes for configuring Google Sign-In\nexport { YOUTUBE_SCOPES, INSTAGRAM_SCOPES } from './types';\n\n// Version\nexport const SDK_VERSION = '1.0.0';\n"]}
|
|
1
|
+
{"version":3,"sources":["../client.ts","../modules/auth.ts","../modules/youtube.ts","../modules/instagram.ts","../modules/social.ts","../modules/insights.ts","../types.ts","../index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TrndUp SDK - Base Client\n * \n * Core HTTP client with Firebase authentication support,\n * error handling, and automatic retries.\n */\n\nimport type { ApiResponse, ApiErrorResponse, ApiSuccessResponse } from './types';\n\n// =============================================================================\n// CONFIGURATION\n// =============================================================================\n\nexport interface TrndUpClientConfig {\n /** Base URL for the API (e.g., 'https://api.trndup.app' or 'http://localhost:3000') */\n baseUrl: string;\n \n /** Function to get the current Firebase ID token */\n getToken: () => string | null | Promise<string | null>;\n \n /** Called when auth completely fails (user needs to re-login) */\n onAuthFailure?: () => void | Promise<void>;\n \n /** Called on any API error */\n onError?: (error: ApiErrorResponse, endpoint: string) => void;\n \n /** Custom headers to include in all requests */\n defaultHeaders?: Record<string, string>;\n \n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n \n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport interface RequestOptions {\n /** Skip authentication for this request */\n skipAuth?: boolean;\n \n /** Additional headers for this request */\n headers?: Record<string, string>;\n \n /** AbortController signal for cancellation */\n signal?: AbortSignal;\n \n /** Custom timeout for this request */\n timeout?: number;\n}\n\ninterface RequestConfig extends RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\nexport class TrndUpApiError extends Error {\n constructor(\n public readonly response: ApiErrorResponse,\n public readonly status: number,\n public readonly endpoint: string\n ) {\n super(response.error);\n this.name = 'TrndUpApiError';\n }\n \n get code(): string | undefined {\n return this.response.code;\n }\n\n get metadata(): Record<string, unknown> | undefined {\n return this.response.metadata;\n }\n\n /** Check if error is due to authentication failure */\n isAuthError(): boolean {\n return this.status === 401 || this.code === 'AUTH_EXPIRED' || this.code === 'AUTH_INVALID';\n }\n\n /** Check if error is due to rate limiting */\n isRateLimitError(): boolean {\n return this.status === 429 || this.code === 'RATE_LIMITED';\n }\n}\n\nexport class TrndUpNetworkError extends Error {\n constructor(\n public readonly originalError: Error,\n public readonly endpoint: string\n ) {\n super(`Network error calling ${endpoint}: ${originalError.message}`);\n this.name = 'TrndUpNetworkError';\n }\n}\n\n// =============================================================================\n// BASE CLIENT\n// =============================================================================\n\nexport class TrndUpClient {\n private config: Required<Omit<TrndUpClientConfig, 'onAuthFailure' | 'onError' | 'defaultHeaders' | 'debug'>> & {\n onAuthFailure?: TrndUpClientConfig['onAuthFailure'];\n onError?: TrndUpClientConfig['onError'];\n defaultHeaders?: Record<string, string>;\n debug?: boolean;\n };\n\n // Module instances (imported by subclasses or external modules)\n public auth!: any;\n public youtube!: any;\n public instagram!: any;\n public social!: any;\n public insights!: any;\n\n constructor(config: TrndUpClientConfig) {\n this.config = {\n baseUrl: config.baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n getToken: config.getToken,\n timeout: config.timeout ?? 30000,\n onAuthFailure: config.onAuthFailure,\n onError: config.onError,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug ?? false,\n };\n }\n\n // =============================================================================\n // PUBLIC REQUEST METHODS\n // =============================================================================\n\n async get<T = unknown>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'GET', path, params, ...options });\n }\n\n async post<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'POST', path, body, ...options });\n }\n\n async put<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body, ...options });\n }\n\n async patch<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'PATCH', path, body, ...options });\n }\n\n async delete<T = unknown>(\n path: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>({ method: 'DELETE', path, ...options });\n }\n\n // =============================================================================\n // CORE REQUEST LOGIC\n // =============================================================================\n\n private async request<T>(config: RequestConfig): Promise<T> {\n const { method, path, params, body, skipAuth, headers, signal, timeout } = config;\n\n // Build URL\n const url = this.buildUrl(path, params);\n\n // Build headers\n const requestHeaders = await this.buildHeaders(skipAuth, headers);\n\n // Build request init\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n signal,\n };\n\n if (body && method !== 'GET') {\n init.body = JSON.stringify(body);\n }\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n timeout ?? this.config.timeout\n );\n\n try {\n if (this.config.debug) {\n console.log(`[TrndUp SDK] ${method} ${url}`, { body, headers: requestHeaders });\n }\n\n const response = await fetch(url, {\n ...init,\n signal: signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n return await this.handleResponse<T>(response, path);\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof TrndUpApiError) {\n throw error;\n }\n\n // Network error\n const networkError = new TrndUpNetworkError(\n error as Error,\n path\n );\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] Network error:', networkError);\n }\n\n throw networkError;\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private async buildHeaders(\n skipAuth?: boolean,\n additionalHeaders?: Record<string, string>\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.config.defaultHeaders,\n ...additionalHeaders,\n };\n\n // Add Firebase ID token for authentication\n if (!skipAuth) {\n const token = await this.config.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n\n return headers;\n }\n\n private async handleResponse<T>(response: Response, endpoint: string): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n // Try to parse error response\n let errorResponse: ApiErrorResponse;\n\n if (isJson) {\n try {\n const parsed = await response.json();\n errorResponse = parsed as ApiErrorResponse;\n } catch {\n errorResponse = {\n success: false,\n error: response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n } else {\n const text = await response.text();\n errorResponse = {\n success: false,\n error: text || response.statusText || 'Unknown error',\n code: `HTTP_${response.status}`,\n };\n }\n\n const apiError = new TrndUpApiError(errorResponse, response.status, endpoint);\n\n // Call error handler\n if (this.config.onError) {\n this.config.onError(errorResponse, endpoint);\n }\n\n // Call auth failure handler for 401 errors\n if (apiError.isAuthError() && this.config.onAuthFailure) {\n await this.config.onAuthFailure();\n }\n\n if (this.config.debug) {\n console.error('[TrndUp SDK] API error:', apiError);\n }\n\n throw apiError;\n }\n\n // Parse success response\n if (isJson) {\n const parsed = await response.json();\n const jsonResponse = parsed as ApiResponse<T>;\n\n if (jsonResponse.success === false) {\n // This shouldn't happen with 2xx status, but handle it\n throw new TrndUpApiError(jsonResponse, response.status, endpoint);\n }\n\n return (jsonResponse as ApiSuccessResponse<T>).data;\n }\n\n // Non-JSON response\n return (await response.text()) as unknown as T;\n }\n}\n","/**\n * TrndUp SDK - Auth Module\n * \n * Firebase authentication methods with Twilio phone OTP\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Auth } from '../types';\n\nexport class AuthModule {\n constructor(private client: TrndUpClient) {}\n\n // =========================================================================\n // PHONE OTP AUTHENTICATION (via Twilio - no reCAPTCHA needed)\n // =========================================================================\n\n /**\n * Send OTP verification code to phone number\n * POST /auth/phone/send-otp\n * \n * @param phoneNumber - Phone number (E.164 format recommended, e.g., +14155551234)\n */\n async sendOTP(phoneNumber: string): Promise<Auth.SendOTPResponse> {\n return this.client.post<Auth.SendOTPResponse>(\n '/auth/phone/send-otp', \n { phoneNumber }, \n { skipAuth: true }\n );\n }\n\n /**\n * Verify OTP and get Firebase custom token\n * POST /auth/phone/verify-otp\n * \n * After calling this, use Firebase signInWithCustomToken(customToken)\n * to complete authentication on the client.\n * \n * @param phoneNumber - Phone number that received the OTP\n * @param code - 6-digit verification code\n */\n async verifyOTP(phoneNumber: string, code: string): Promise<Auth.VerifyOTPResponse> {\n return this.client.post<Auth.VerifyOTPResponse>(\n '/auth/phone/verify-otp',\n { phoneNumber, code },\n { skipAuth: true }\n );\n }\n\n // =========================================================================\n // FIREBASE ID TOKEN AUTHENTICATION\n // =========================================================================\n\n /**\n * Login with Firebase ID token (for Google, Apple, Email/Password)\n * POST /auth/login\n */\n async login(idToken: string): Promise<Auth.LoginResponse> {\n return this.client.post<Auth.LoginResponse>('/auth/login', { idToken }, { skipAuth: true });\n }\n\n /**\n * Get current authenticated user's profile\n * GET /auth/me\n */\n async getCurrentUser(): Promise<Auth.CurrentUserResponse> {\n return this.client.get<Auth.CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Update user profile\n * PATCH /auth/me\n */\n async updateProfile(data: Auth.UpdateProfileRequest): Promise<Auth.UpdateProfileResponse> {\n return this.client.patch<Auth.UpdateProfileResponse>('/auth/me', data);\n }\n\n /**\n * Logout (acknowledge logout on backend)\n * POST /auth/logout\n */\n async logout(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/auth/logout');\n }\n\n /**\n * Check auth service status\n * GET /auth/status\n */\n async getStatus(): Promise<{ success: boolean; message: string }> {\n return this.client.get('/auth/status', undefined, { skipAuth: true });\n }\n\n /**\n * Get user's platform connection status\n * GET /user/platforms/status\n */\n async getPlatformStatus(): Promise<Auth.PlatformStatus> {\n return this.client.get<Auth.PlatformStatus>('/user/platforms/status');\n }\n}\n","/**\n * TrndUp SDK - YouTube Module\n * \n * YouTube analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { YouTube } from '../types';\n\nexport class YouTubeModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get YouTube initialization status\n * Check if user needs to init or has already synced\n * \n * GET /v1/platforms/youtube/init/status\n */\n async getInitStatus(): Promise<YouTube.InitStatusResponse> {\n return this.client.get<YouTube.InitStatusResponse>('/v1/platforms/youtube/init/status');\n }\n\n /**\n * Initialize YouTube data sync\n * Fetches all channel info and videos, stores in database\n * Returns channel info, video counts, and oldest video date for analytics\n * \n * POST /v1/platforms/youtube/init\n */\n async initialize(): Promise<YouTube.InitResponse> {\n return this.client.post<YouTube.InitResponse>('/v1/platforms/youtube/init');\n }\n\n /**\n * Get YouTube videos\n * GET /v1/platforms/youtube/videos\n */\n async getVideos(params?: YouTube.GetVideosParams): Promise<YouTube.GetVideosResponse> {\n return this.client.get<YouTube.GetVideosResponse>(\n '/v1/platforms/youtube/videos', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific video by ID\n * GET /v1/platforms/youtube/videos/:videoId\n */\n async getVideo(videoId: string): Promise<YouTube.Video> {\n return this.client.get<YouTube.Video>(`/v1/platforms/youtube/videos/${videoId}`);\n }\n\n /**\n * Get channel metrics\n * GET /v1/platforms/youtube/channel/metrics\n */\n async getChannelMetrics(): Promise<YouTube.ChannelMetrics> {\n return this.client.get<YouTube.ChannelMetrics>('/v1/platforms/youtube/channel/metrics');\n }\n\n /**\n * Get channel health score\n * GET /v1/platforms/youtube/health\n */\n async getHealthScore(params?: YouTube.GetHealthScoreParams): Promise<YouTube.HealthScore> {\n return this.client.get<YouTube.HealthScore>(\n '/v1/platforms/youtube/health', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Refresh YouTube data\n * POST /v1/platforms/youtube/refresh\n */\n async refresh(): Promise<{ message: string; jobId?: string }> {\n return this.client.post<{ message: string; jobId?: string }>('/v1/platforms/youtube/refresh');\n }\n}\n","/**\n * TrndUp SDK - Instagram Module\n * \n * Instagram analytics and data methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Instagram } from '../types';\n\nexport class InstagramModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get Instagram initialization status\n * GET /v1/platforms/instagram/init/status\n */\n async getInitStatus(): Promise<Instagram.InitStatusResponse> {\n return this.client.get<Instagram.InitStatusResponse>('/v1/platforms/instagram/init/status');\n }\n\n /**\n * Initialize Instagram data sync\n * POST /v1/platforms/instagram/init\n */\n async initialize(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/init');\n }\n\n /**\n * Get Instagram posts\n * GET /v1/platforms/instagram/posts\n */\n async getPosts(params?: Instagram.GetPostsParams): Promise<Instagram.GetPostsResponse> {\n return this.client.get<Instagram.GetPostsResponse>(\n '/v1/platforms/instagram/posts', \n params as Record<string, string | number | boolean | undefined>\n );\n }\n\n /**\n * Get specific post by ID\n * GET /v1/platforms/instagram/posts/:postId\n */\n async getPost(postId: string): Promise<Instagram.Post> {\n return this.client.get<Instagram.Post>(`/v1/platforms/instagram/posts/${postId}`);\n }\n\n /**\n * Get account metrics\n * GET /v1/platforms/instagram/account/metrics\n */\n async getAccountMetrics(): Promise<Instagram.AccountMetrics> {\n return this.client.get<Instagram.AccountMetrics>('/v1/platforms/instagram/account/metrics');\n }\n\n /**\n * Refresh Instagram data\n * POST /v1/platforms/instagram/refresh\n */\n async refresh(): Promise<{ message: string }> {\n return this.client.post<{ message: string }>('/v1/platforms/instagram/refresh');\n }\n}\n","/**\n * TrndUp SDK - Social Module\n * \n * Social account linking methods\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Social } from '../types';\n\nexport class SocialModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Link YouTube account\n * POST /social/link/youtube\n */\n async linkYouTube(data: Social.LinkYouTubeRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/youtube', data);\n }\n\n /**\n * Link Instagram account\n * POST /social/link/instagram\n */\n async linkInstagram(data: Social.LinkInstagramRequest): Promise<Social.LinkAccountResponse> {\n return this.client.post<Social.LinkAccountResponse>('/social/link/instagram', data);\n }\n\n /**\n * Get all connected social accounts\n * GET /social/accounts\n */\n async getConnectedAccounts(): Promise<Social.ConnectedAccount[]> {\n return this.client.get<Social.ConnectedAccount[]>('/social/accounts');\n }\n\n /**\n * Unlink a social account\n * DELETE /social/unlink/:provider\n */\n async unlinkAccount(provider: string): Promise<{ message: string }> {\n return this.client.delete<{ message: string }>(`/social/unlink/${provider}`);\n }\n}\n","/**\n * TrndUp SDK - Insights Module\n * \n * Cross-platform insights and analytics\n */\n\nimport type { TrndUpClient } from '../client';\nimport type { Insights } from '../types';\n\nexport class InsightsModule {\n constructor(private client: TrndUpClient) {}\n\n /**\n * Get cross-platform metrics\n * GET /v1/insights/overview\n */\n async getOverview(): Promise<Insights.CrossPlatformMetrics> {\n return this.client.get<Insights.CrossPlatformMetrics>('/v1/insights/overview');\n }\n\n /**\n * Get trending content across all platforms\n * GET /v1/insights/trending\n */\n async getTrending(): Promise<Insights.TrendingContent> {\n return this.client.get<Insights.TrendingContent>('/v1/insights/trending');\n }\n}\n","/**\n * TrndUp SDK Types\n * \n * Type definitions for the TrndUp API SDK\n */\n\n// =============================================================================\n// OAUTH SCOPES\n// =============================================================================\n\n/**\n * Required OAuth scopes for YouTube account linking\n * Use these when configuring Google Sign-In in your mobile app\n * \n * @example\n * ```typescript\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * import { YOUTUBE_SCOPES } from '@trndup/sdk';\n * \n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * ```\n */\nexport const YOUTUBE_SCOPES = [\n 'openid',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/youtube.readonly',\n 'https://www.googleapis.com/auth/yt-analytics.readonly',\n 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',\n 'https://www.googleapis.com/auth/youtube.force-ssl',\n 'https://www.googleapis.com/auth/youtubepartner'\n];\n\n/**\n * Required OAuth scopes for Instagram account linking\n */\nexport const INSTAGRAM_SCOPES = [\n 'instagram_business_basic',\n 'instagram_business_manage_insights',\n 'instagram_business_manage_comments'\n];\n\n// =============================================================================\n// API RESPONSE WRAPPER\n// =============================================================================\n\nexport interface ApiSuccessResponse<T = unknown> {\n success: true;\n data: T;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: string;\n code?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// =============================================================================\n// AUTH TYPES\n// =============================================================================\n\nexport namespace Auth {\n export interface User {\n id: string;\n firebaseUid?: string;\n email?: string;\n phoneNumber?: string;\n username: string;\n picture?: string;\n emailVerified?: boolean;\n signInProvider?: string; // 'phone', 'google.com', 'password', 'apple.com'\n createdAt: string;\n updatedAt: string;\n }\n\n export interface SocialAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n }\n\n // Phone OTP Authentication (Twilio)\n export interface SendOTPRequest {\n phoneNumber: string;\n }\n\n export interface SendOTPResponse {\n message: string;\n expiresIn: number;\n }\n\n export interface VerifyOTPRequest {\n phoneNumber: string;\n code: string;\n }\n\n export interface VerifyOTPResponse {\n customToken: string;\n isNewUser: boolean;\n user: User;\n platformStatus: PlatformStatus;\n }\n\n // Firebase ID Token Login\n export interface LoginRequest {\n idToken: string;\n }\n\n export interface LoginResponse {\n user: User;\n platformStatus: PlatformStatus;\n idToken: string;\n }\n\n export interface CurrentUserResponse {\n user: User;\n socialAccounts: SocialAccount[];\n }\n\n export interface UpdateProfileRequest {\n username?: string;\n picture?: string;\n }\n\n export interface UpdateProfileResponse {\n user: User;\n }\n\n export interface PlatformStatus {\n hasConnectedPlatforms: boolean;\n connectedPlatforms: Array<'youtube' | 'instagram'>;\n }\n}\n\n// =============================================================================\n// SOCIAL TYPES\n// =============================================================================\n\nexport namespace Social {\n /**\n * Link YouTube account request\n * \n * Two options:\n * 1. serverAuthCode (recommended): Backend exchanges for tokens with proper expiry\n * 2. Direct tokens: Frontend provides accessToken (expiresAt defaults to 1 hour)\n */\n export interface LinkYouTubeRequest {\n idToken: string; // Google ID token for verification (always required)\n serverAuthCode?: string; // Google server auth code - backend exchanges for tokens (recommended)\n accessToken?: string; // Google access token (alternative to serverAuthCode)\n refreshToken?: string; // Google refresh token (only with accessToken flow)\n expiresAt?: number; // Token expiry timestamp in ms (only with accessToken flow)\n grantedScopes?: string; // Actual scopes user granted (space-separated)\n platform?: string; // 'ios' | 'android' | 'web'\n environment?: string; // 'development' | 'production'\n }\n\n export interface LinkInstagramRequest {\n accessToken: string;\n }\n\n export interface LinkAccountResponse {\n message: string;\n provider: string;\n accountName?: string;\n }\n\n export interface ConnectedAccount {\n provider: string;\n accountName?: string;\n username?: string;\n profilePictureUrl?: string;\n connectedAt: string;\n lastSyncAt?: string;\n }\n}\n\n// =============================================================================\n// YOUTUBE TYPES\n// =============================================================================\n\nexport namespace YouTube {\n /**\n * Response from GET /v1/platforms/youtube/init/status\n */\n export interface InitStatusResponse {\n needsInit: boolean;\n status: 'NEVER_SYNCED' | 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';\n lastSyncAt: string | null;\n videoCount: number;\n oldestVideoDate: string | null;\n analyticsStartDate: string | null;\n }\n\n /**\n * Response from POST /v1/platforms/youtube/init\n */\n export interface InitResponse {\n channel: {\n channelId: string;\n channelTitle: string;\n subscriberCount: number;\n videoCount: number;\n viewCount: number;\n };\n videos: {\n total: number;\n synced: number;\n oldestVideoDate: string | null;\n };\n syncStatus: {\n isFirstSync: boolean;\n lastSyncAt: string | null;\n };\n }\n\n export interface Video {\n id: string;\n videoId: string;\n title: string;\n description?: string;\n thumbnailUrl?: string;\n publishedAt: string;\n duration?: number;\n viewCount?: number;\n likeCount?: number;\n commentCount?: number;\n engagementRate?: number;\n }\n\n export interface GetVideosParams {\n limit?: number;\n offset?: number;\n sortBy?: 'recent' | 'views' | 'engagement';\n }\n\n export interface GetVideosResponse {\n videos: Video[];\n total: number;\n hasMore: boolean;\n }\n\n export interface ChannelMetrics {\n subscriberCount: number;\n totalViews: number;\n totalVideos: number;\n averageViews: number;\n engagementRate: number;\n }\n\n export interface HealthScore {\n score: number;\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n metrics: {\n consistency: number;\n engagement: number;\n growth: number;\n quality: number;\n };\n }\n\n export interface GetHealthScoreParams {\n range?: string; // e.g., '7d', '30d', '90d'\n }\n}\n\n// =============================================================================\n// INSTAGRAM TYPES\n// =============================================================================\n\nexport namespace Instagram {\n export interface InitStatusResponse {\n needsInit: boolean;\n message: string;\n postCount?: number;\n accountId?: string;\n username?: string;\n }\n\n export interface Post {\n id: string;\n caption?: string;\n mediaType: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM';\n mediaUrl: string;\n permalink: string;\n timestamp: string;\n likeCount?: number;\n commentsCount?: number;\n engagementRate?: number;\n }\n\n export interface GetPostsParams {\n limit?: number;\n offset?: number;\n }\n\n export interface GetPostsResponse {\n posts: Post[];\n total: number;\n hasMore: boolean;\n }\n\n export interface AccountMetrics {\n followersCount: number;\n followsCount: number;\n mediaCount: number;\n averageLikes: number;\n engagementRate: number;\n }\n}\n\n// =============================================================================\n// INSIGHTS TYPES\n// =============================================================================\n\nexport namespace Insights {\n export interface CrossPlatformMetrics {\n totalFollowers: number;\n totalEngagement: number;\n platforms: {\n youtube?: {\n subscribers: number;\n views: number;\n videos: number;\n };\n instagram?: {\n followers: number;\n posts: number;\n avgEngagement: number;\n };\n };\n }\n\n export interface TrendingContent {\n youtube?: YouTube.Video[];\n instagram?: Instagram.Post[];\n }\n}\n","/**\n * TrndUp API SDK\n * \n * Official TypeScript SDK for the TrndUp API.\n * Provides type-safe methods for all API endpoints with Firebase authentication.\n * \n * @example\n * ```typescript\n * import { TrndUpSDK, YOUTUBE_SCOPES } from '@trndup/sdk';\n * import auth from '@react-native-firebase/auth';\n * import { GoogleSignin } from '@react-native-google-signin/google-signin';\n * \n * // Configure Google Sign-In with YouTube scopes\n * GoogleSignin.configure({\n * webClientId: 'YOUR_WEB_CLIENT_ID',\n * offlineAccess: true,\n * scopes: YOUTUBE_SCOPES\n * });\n * \n * const sdk = new TrndUpSDK({\n * baseUrl: 'https://api.trndup.app',\n * getToken: async () => {\n * const user = auth().currentUser;\n * return user ? await user.getIdToken() : null;\n * },\n * onAuthFailure: () => {\n * // Handle auth failure - navigate to login\n * navigation.navigate('Login');\n * },\n * });\n * \n * // Type-safe API calls\n * const user = await sdk.auth.getCurrentUser();\n * const videos = await sdk.youtube.getVideos({ limit: 10 });\n * const healthScore = await sdk.youtube.getHealthScore({ range: '30d' });\n * ```\n */\n\nimport { TrndUpClient, TrndUpClientConfig } from './client';\nimport { AuthModule } from './modules/auth';\nimport { YouTubeModule } from './modules/youtube';\nimport { InstagramModule } from './modules/instagram';\nimport { SocialModule } from './modules/social';\nimport { InsightsModule } from './modules/insights';\n\nexport class TrndUpSDK extends TrndUpClient {\n public auth: AuthModule;\n public youtube: YouTubeModule;\n public instagram: InstagramModule;\n public social: SocialModule;\n public insights: InsightsModule;\n\n constructor(config: TrndUpClientConfig) {\n super(config);\n\n // Initialize all modules\n this.auth = new AuthModule(this);\n this.youtube = new YouTubeModule(this);\n this.instagram = new InstagramModule(this);\n this.social = new SocialModule(this);\n this.insights = new InsightsModule(this);\n }\n}\n\n// Re-export types and classes\nexport type { TrndUpClientConfig, RequestOptions } from './client';\nexport { TrndUpApiError, TrndUpNetworkError } from './client';\n\n// Re-export all type namespaces\nexport type { Auth, Social, YouTube, Instagram, Insights } from './types';\n\n// Re-export OAuth scopes for configuring Google Sign-In\nexport { YOUTUBE_SCOPES, INSTAGRAM_SCOPES } from './types';\n\n// Version\nexport const SDK_VERSION = '1.0.0';\n"]}
|