@happyvertical/social 0.74.8

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.
@@ -0,0 +1,1114 @@
1
+ /**
2
+ * OAuth authorization options
3
+ */
4
+ export declare interface AuthorizationOptions {
5
+ /**
6
+ * OAuth scopes to request
7
+ */
8
+ scopes?: string[];
9
+ /**
10
+ * State parameter for CSRF protection
11
+ */
12
+ state?: string;
13
+ /**
14
+ * Code verifier for PKCE
15
+ */
16
+ codeVerifier?: string;
17
+ /**
18
+ * Redirect URI
19
+ */
20
+ redirectUri?: string;
21
+ }
22
+
23
+ /**
24
+ * OAuth authorization result
25
+ */
26
+ export declare interface AuthorizationResult {
27
+ /**
28
+ * Authorization URL to redirect user to
29
+ */
30
+ url: string;
31
+ /**
32
+ * State parameter (for verification)
33
+ */
34
+ state: string;
35
+ /**
36
+ * Code verifier (for PKCE, store securely)
37
+ */
38
+ codeVerifier?: string;
39
+ }
40
+
41
+ /**
42
+ * Authentication result
43
+ */
44
+ export declare interface AuthResult {
45
+ /**
46
+ * Access token
47
+ */
48
+ accessToken: string;
49
+ /**
50
+ * Refresh token (if available)
51
+ */
52
+ refreshToken?: string;
53
+ /**
54
+ * Token expiration time
55
+ */
56
+ expiresAt?: Date;
57
+ /**
58
+ * Token type (usually 'Bearer')
59
+ */
60
+ tokenType?: string;
61
+ /**
62
+ * Granted scopes
63
+ */
64
+ scopes?: string[];
65
+ }
66
+
67
+ /**
68
+ * Base configuration for social platform adapters
69
+ */
70
+ export declare interface BaseSocialConfig {
71
+ /**
72
+ * Platform type
73
+ */
74
+ type: SocialPlatformType;
75
+ /**
76
+ * Rate limiting configuration (applies at SDK level)
77
+ */
78
+ rateLimit?: {
79
+ /**
80
+ * Maximum requests per minute
81
+ */
82
+ requestsPerMinute?: number;
83
+ /**
84
+ * Maximum concurrent requests
85
+ */
86
+ maxConcurrent?: number;
87
+ };
88
+ /**
89
+ * Request timeout in milliseconds
90
+ * @default 30000
91
+ */
92
+ timeout?: number;
93
+ /**
94
+ * Controls whether publish calls create public content.
95
+ * Defaults to public for backward compatibility.
96
+ */
97
+ publishMode?: PublishMode;
98
+ }
99
+
100
+ /**
101
+ * Bluesky adapter for publishing via AT Protocol
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const bluesky = new BlueskyAdapter({
106
+ * type: 'bluesky',
107
+ * identifier: 'myhandle.bsky.social',
108
+ * password: 'app-password', // Use app password, not main password
109
+ * });
110
+ *
111
+ * await bluesky.authenticate();
112
+ *
113
+ * const result = await bluesky.publishText({
114
+ * text: 'Breaking news from Bentley!',
115
+ * linkUrl: 'https://example.com/article',
116
+ * });
117
+ * ```
118
+ */
119
+ export declare class BlueskyAdapter implements SocialPlatform {
120
+ readonly platform: "bluesky";
121
+ private config;
122
+ private session?;
123
+ constructor(config: BlueskyConfig);
124
+ private get pdsUrl();
125
+ authenticate(): Promise<AuthResult>;
126
+ refreshToken(refreshJwt: string): Promise<AuthResult>;
127
+ publishVideo(_video: VideoPost): Promise<PostResult>;
128
+ publishImage(image: ImagePost): Promise<PostResult>;
129
+ publishText(text: TextPost): Promise<PostResult>;
130
+ publishLink(link: LinkPost): Promise<PostResult>;
131
+ private createPost;
132
+ getPost(postId: string): Promise<Post>;
133
+ deletePost(postId: string): Promise<void>;
134
+ getAnalytics(postId: string): Promise<PostAnalytics>;
135
+ getCapabilities(): PlatformCapabilities;
136
+ /**
137
+ * Get reply reference for threading
138
+ */
139
+ private getReplyRef;
140
+ /**
141
+ * Build post text with hashtags
142
+ */
143
+ private buildPostText;
144
+ /**
145
+ * Handle API errors
146
+ */
147
+ private handleError;
148
+ }
149
+
150
+ /**
151
+ * Bluesky configuration
152
+ */
153
+ export declare interface BlueskyConfig extends BaseSocialConfig {
154
+ type: 'bluesky';
155
+ /**
156
+ * Handle or DID
157
+ */
158
+ identifier: string;
159
+ /**
160
+ * App password (not main password)
161
+ */
162
+ password: string;
163
+ /**
164
+ * PDS URL (optional, defaults to bsky.social)
165
+ */
166
+ pdsUrl?: string;
167
+ }
168
+
169
+ /**
170
+ * OAuth code exchange parameters
171
+ */
172
+ export declare interface CodeExchangeParams {
173
+ /**
174
+ * Authorization code from callback
175
+ */
176
+ code: string;
177
+ /**
178
+ * State parameter (for verification)
179
+ */
180
+ state?: string;
181
+ /**
182
+ * Code verifier (for PKCE)
183
+ */
184
+ codeVerifier?: string;
185
+ /**
186
+ * Redirect URI (must match authorization request)
187
+ */
188
+ redirectUri?: string;
189
+ }
190
+
191
+ /**
192
+ * Facebook Page adapter for publishing feed posts and Page videos.
193
+ */
194
+ export declare class FacebookPageAdapter implements SocialPlatform {
195
+ readonly platform: "facebook";
196
+ private config;
197
+ constructor(config: FacebookPageConfig);
198
+ private get graphUrl();
199
+ authenticate(): Promise<AuthResult>;
200
+ refreshToken(_refreshToken: string): Promise<AuthResult>;
201
+ publishText(text: TextPost): Promise<PostResult>;
202
+ publishLink(link: LinkPost): Promise<PostResult>;
203
+ publishImage(image: ImagePost): Promise<PostResult>;
204
+ publishVideo(video: VideoPost): Promise<PostResult>;
205
+ getPost(postId: string): Promise<Post>;
206
+ deletePost(postId: string): Promise<void>;
207
+ getAnalytics(postId: string): Promise<PostAnalytics>;
208
+ getCapabilities(): PlatformCapabilities;
209
+ private createFeedPost;
210
+ private toPostResult;
211
+ private safetyFeedFields;
212
+ private safetyResultStatus;
213
+ private buildPostText;
214
+ private parseInsights;
215
+ private sumPositiveReactions;
216
+ private handleError;
217
+ }
218
+
219
+ /**
220
+ * Facebook Page configuration
221
+ */
222
+ export declare interface FacebookPageConfig extends BaseSocialConfig {
223
+ type: 'facebook';
224
+ /**
225
+ * Page access token with pages_manage_posts permission
226
+ */
227
+ accessToken: string;
228
+ /**
229
+ * Facebook Page ID
230
+ */
231
+ pageId: string;
232
+ /**
233
+ * Optional Graph API version.
234
+ * @default v24.0
235
+ */
236
+ apiVersion?: string;
237
+ }
238
+
239
+ /**
240
+ * Factory function to create a social platform adapter
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * import { getSocial } from '@happyvertical/social';
245
+ *
246
+ * // YouTube
247
+ * const youtube = await getSocial({
248
+ * type: 'youtube',
249
+ * clientId: 'your-client-id',
250
+ * clientSecret: 'your-client-secret',
251
+ * accessToken: 'user-access-token',
252
+ * });
253
+ *
254
+ * // Bluesky
255
+ * const bluesky = await getSocial({
256
+ * type: 'bluesky',
257
+ * identifier: 'handle.bsky.social',
258
+ * password: 'app-password',
259
+ * });
260
+ *
261
+ * // X (Twitter)
262
+ * const x = await getSocial({
263
+ * type: 'x',
264
+ * apiKey: 'consumer-key',
265
+ * apiSecret: 'consumer-secret',
266
+ * accessToken: 'user-access-token',
267
+ * accessSecret: 'user-access-secret',
268
+ * });
269
+ *
270
+ * // Threads
271
+ * const threads = await getSocial({
272
+ * type: 'threads',
273
+ * accessToken: 'user-access-token',
274
+ * userId: 'threads-user-id',
275
+ * });
276
+ *
277
+ * // Publish text
278
+ * const result = await youtube.publishText({
279
+ * text: 'Hello from Bentley!',
280
+ * });
281
+ * ```
282
+ */
283
+ export declare function getSocial(config: SocialConfig): Promise<SocialPlatform>;
284
+
285
+ /**
286
+ * Create multiple social platform adapters at once
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * import { getSocialMulti } from '@happyvertical/social';
291
+ *
292
+ * const adapters = await getSocialMulti([
293
+ * { type: 'youtube', clientId: '...', clientSecret: '...', accessToken: '...' },
294
+ * { type: 'bluesky', identifier: '...', password: '...' },
295
+ * ]);
296
+ *
297
+ * // Publish to all platforms
298
+ * const results = await Promise.all(
299
+ * adapters.map(adapter => adapter.publishText({ text: 'Hello!' }))
300
+ * );
301
+ * ```
302
+ */
303
+ export declare function getSocialMulti(configs: SocialConfig[]): Promise<SocialPlatform[]>;
304
+
305
+ /**
306
+ * Image post content
307
+ */
308
+ export declare interface ImagePost {
309
+ /**
310
+ * Image file buffer or URL
311
+ */
312
+ file: Buffer | string;
313
+ /**
314
+ * MIME type for the image file. Detected from URLs and common buffer
315
+ * signatures when omitted.
316
+ */
317
+ mimeType?: string;
318
+ /**
319
+ * Alt text for accessibility
320
+ */
321
+ altText?: string;
322
+ /**
323
+ * Post description/caption
324
+ */
325
+ description?: string;
326
+ /**
327
+ * Hashtags to include
328
+ */
329
+ tags?: string[];
330
+ /**
331
+ * Link URL to include
332
+ */
333
+ linkUrl?: string;
334
+ /**
335
+ * Scheduled publish time
336
+ */
337
+ scheduledAt?: Date;
338
+ /**
339
+ * Override the adapter/account default link behavior for this post.
340
+ */
341
+ linkBehavior?: LinkBehavior;
342
+ }
343
+
344
+ /**
345
+ * How adapters should attach links to posts.
346
+ */
347
+ export declare type LinkBehavior = 'inline' | 'attachment' | 'reply' | 'none';
348
+
349
+ /**
350
+ * Link post content
351
+ */
352
+ export declare interface LinkPost {
353
+ /**
354
+ * URL to share
355
+ */
356
+ url: string;
357
+ /**
358
+ * Post text/caption
359
+ */
360
+ text?: string;
361
+ /**
362
+ * Link title for platforms that support link cards
363
+ */
364
+ title?: string;
365
+ /**
366
+ * Link description for platforms that support link cards
367
+ */
368
+ description?: string;
369
+ /**
370
+ * Hashtags to include
371
+ */
372
+ tags?: string[];
373
+ /**
374
+ * Scheduled publish time
375
+ */
376
+ scheduledAt?: Date;
377
+ /**
378
+ * Override the adapter/account default link behavior for this post.
379
+ */
380
+ linkBehavior?: LinkBehavior;
381
+ }
382
+
383
+ /**
384
+ * Platform capabilities
385
+ */
386
+ export declare interface PlatformCapabilities {
387
+ /**
388
+ * Supports video posts
389
+ */
390
+ video: boolean;
391
+ /**
392
+ * Supports image posts
393
+ */
394
+ image: boolean;
395
+ /**
396
+ * Supports text-only posts
397
+ */
398
+ text: boolean;
399
+ /**
400
+ * Supports first-class link posts or link attachments
401
+ */
402
+ link: boolean;
403
+ /**
404
+ * Supports native link attachments/cards instead of plain inline URLs
405
+ */
406
+ linkAttachment?: boolean;
407
+ /**
408
+ * Supports scheduled posting
409
+ */
410
+ scheduling: boolean;
411
+ /**
412
+ * Supports analytics retrieval
413
+ */
414
+ analytics: boolean;
415
+ /**
416
+ * Analytics can include raw platform payloads
417
+ */
418
+ rawAnalytics?: boolean;
419
+ /**
420
+ * Safety modes supported by this adapter.
421
+ */
422
+ publishModes?: PublishMode[];
423
+ /**
424
+ * Supports a non-public remote staging step before final publish.
425
+ */
426
+ staging?: boolean;
427
+ /**
428
+ * Supports creating private, unpublished, or scheduled platform content.
429
+ */
430
+ privatePublishing?: boolean;
431
+ /**
432
+ * Media publishing requires a publicly accessible URL, not a Buffer upload
433
+ */
434
+ requiresPublicMediaUrl?: boolean;
435
+ /**
436
+ * Maximum video duration in seconds
437
+ */
438
+ maxVideoLength: number;
439
+ /**
440
+ * Maximum video file size in bytes
441
+ */
442
+ maxVideoSize: number;
443
+ /**
444
+ * Supported video formats
445
+ */
446
+ supportedVideoFormats: string[];
447
+ /**
448
+ * Supported aspect ratios
449
+ */
450
+ aspectRatios: string[];
451
+ /**
452
+ * Maximum text length
453
+ */
454
+ maxTextLength: number;
455
+ /**
456
+ * Maximum number of hashtags
457
+ */
458
+ maxHashtags?: number;
459
+ /**
460
+ * Supported high-level post types
461
+ */
462
+ supportedPostTypes?: Array<'text' | 'image' | 'video' | 'link'>;
463
+ }
464
+
465
+ /**
466
+ * Retrieved post data
467
+ */
468
+ export declare interface Post {
469
+ /**
470
+ * Platform-specific post ID
471
+ */
472
+ id: string;
473
+ /**
474
+ * Public URL of the post
475
+ */
476
+ url: string;
477
+ /**
478
+ * Post type
479
+ */
480
+ type: 'video' | 'image' | 'text' | 'link';
481
+ /**
482
+ * Post title (if applicable)
483
+ */
484
+ title?: string;
485
+ /**
486
+ * Post description/caption
487
+ */
488
+ description?: string;
489
+ /**
490
+ * When the post was published
491
+ */
492
+ publishedAt: Date;
493
+ /**
494
+ * Current visibility
495
+ */
496
+ visibility: 'public' | 'unlisted' | 'private';
497
+ /**
498
+ * Basic analytics
499
+ */
500
+ analytics?: PostAnalytics;
501
+ }
502
+
503
+ /**
504
+ * Post analytics
505
+ */
506
+ export declare interface PostAnalytics {
507
+ /**
508
+ * View/impression count
509
+ */
510
+ views?: number;
511
+ /**
512
+ * Impression count when the platform distinguishes it from views
513
+ */
514
+ impressions?: number;
515
+ /**
516
+ * Like/favorite count
517
+ */
518
+ likes?: number;
519
+ /**
520
+ * Comment count
521
+ */
522
+ comments?: number;
523
+ /**
524
+ * Share/repost count
525
+ */
526
+ shares?: number;
527
+ /**
528
+ * Click count (for links)
529
+ */
530
+ clicks?: number;
531
+ /**
532
+ * Raw platform analytics payload for debugging and future reporting
533
+ */
534
+ raw?: unknown;
535
+ /**
536
+ * When analytics were last updated
537
+ */
538
+ lastUpdated?: Date;
539
+ }
540
+
541
+ /**
542
+ * Result from publishing a post
543
+ */
544
+ export declare interface PostResult {
545
+ /**
546
+ * Platform-specific post ID
547
+ */
548
+ id: string;
549
+ /**
550
+ * Public URL of the post
551
+ */
552
+ url: string;
553
+ /**
554
+ * Publication status
555
+ */
556
+ status: 'published' | 'scheduled' | 'processing' | 'staged' | 'dry_run';
557
+ /**
558
+ * When the post was/will be published
559
+ */
560
+ publishedAt?: Date;
561
+ /**
562
+ * Scheduled time (if scheduled)
563
+ */
564
+ scheduledAt?: Date;
565
+ /**
566
+ * Platform-specific metadata
567
+ */
568
+ metadata?: Record<string, any>;
569
+ }
570
+
571
+ /**
572
+ * Safety mode for publish operations.
573
+ * - dry_run: Build and validate payloads without platform API writes
574
+ * - stage_remote: Use non-public staging endpoints where available
575
+ * - private_or_scheduled: Create a non-public/private/scheduled platform object where available
576
+ * - public: Publish publicly
577
+ */
578
+ export declare type PublishMode = 'dry_run' | 'stage_remote' | 'private_or_scheduled' | 'public';
579
+
580
+ /**
581
+ * Publish content to multiple platforms at once
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * import { publishToAll, getSocialMulti } from '@happyvertical/social';
586
+ *
587
+ * const adapters = await getSocialMulti([...]);
588
+ *
589
+ * const results = await publishToAll(adapters, {
590
+ * type: 'text',
591
+ * text: 'Breaking news from Bentley!',
592
+ * linkUrl: 'https://example.com/article',
593
+ * tags: ['news', 'local'],
594
+ * });
595
+ * ```
596
+ */
597
+ export declare function publishToAll(adapters: SocialPlatform[], content: {
598
+ type: 'text' | 'image' | 'video' | 'link';
599
+ text?: string;
600
+ description?: string;
601
+ file?: Buffer | string;
602
+ title?: string;
603
+ linkUrl?: string;
604
+ url?: string;
605
+ tags?: string[];
606
+ altText?: string;
607
+ mimeType?: string;
608
+ thumbnail?: Buffer | string;
609
+ thumbnailMimeType?: string;
610
+ }): Promise<Map<string, {
611
+ success: boolean;
612
+ result?: unknown;
613
+ error?: Error;
614
+ }>>;
615
+
616
+ /**
617
+ * Authentication error
618
+ */
619
+ export declare class SocialAuthError extends SocialError {
620
+ constructor(platform: SocialPlatformType, message?: string);
621
+ }
622
+
623
+ /**
624
+ * Union of all platform configurations
625
+ */
626
+ export declare type SocialConfig = YouTubeConfig | ThreadsConfig | FacebookPageConfig | XConfig | BlueskyConfig;
627
+
628
+ /**
629
+ * Error thrown by social platform operations
630
+ */
631
+ export declare class SocialError extends Error {
632
+ code: string;
633
+ platform?: SocialPlatformType | undefined;
634
+ statusCode?: number | undefined;
635
+ constructor(message: string, code: string, platform?: SocialPlatformType | undefined, statusCode?: number | undefined);
636
+ }
637
+
638
+ /**
639
+ * Social platform interface
640
+ */
641
+ export declare interface SocialPlatform {
642
+ /**
643
+ * Platform type
644
+ */
645
+ readonly platform: SocialPlatformType;
646
+ /**
647
+ * Authenticate or refresh authentication
648
+ */
649
+ authenticate(credentials?: Record<string, string>): Promise<AuthResult>;
650
+ /**
651
+ * Refresh expired token
652
+ */
653
+ refreshToken(refreshToken: string): Promise<AuthResult>;
654
+ /**
655
+ * Publish a video post
656
+ */
657
+ publishVideo(video: VideoPost): Promise<PostResult>;
658
+ /**
659
+ * Publish an image post
660
+ */
661
+ publishImage(image: ImagePost): Promise<PostResult>;
662
+ /**
663
+ * Publish a text post
664
+ */
665
+ publishText(text: TextPost): Promise<PostResult>;
666
+ /**
667
+ * Publish a link post
668
+ */
669
+ publishLink(link: LinkPost): Promise<PostResult>;
670
+ /**
671
+ * Get a post by ID
672
+ */
673
+ getPost(postId: string): Promise<Post>;
674
+ /**
675
+ * Delete a post
676
+ */
677
+ deletePost(postId: string): Promise<void>;
678
+ /**
679
+ * Get analytics for a post
680
+ */
681
+ getAnalytics(postId: string): Promise<PostAnalytics>;
682
+ /**
683
+ * Get platform capabilities
684
+ */
685
+ getCapabilities(): PlatformCapabilities;
686
+ }
687
+
688
+ /**
689
+ * Social Platform Types
690
+ *
691
+ * Unified interface for publishing to social media platforms.
692
+ */
693
+ /**
694
+ * Supported social platforms
695
+ */
696
+ export declare type SocialPlatformType = 'youtube' | 'threads' | 'x' | 'bluesky' | 'facebook';
697
+
698
+ /**
699
+ * Rate limit error
700
+ */
701
+ export declare class SocialRateLimitError extends SocialError {
702
+ retryAfter?: number | undefined;
703
+ constructor(platform: SocialPlatformType, retryAfter?: number | undefined);
704
+ }
705
+
706
+ /**
707
+ * Text post content
708
+ */
709
+ export declare interface TextPost {
710
+ /**
711
+ * Post text content
712
+ */
713
+ text: string;
714
+ /**
715
+ * Hashtags to include
716
+ */
717
+ tags?: string[];
718
+ /**
719
+ * Link URL to include
720
+ */
721
+ linkUrl?: string;
722
+ /**
723
+ * Scheduled publish time
724
+ */
725
+ scheduledAt?: Date;
726
+ /**
727
+ * Reply to post ID (for threads/replies)
728
+ */
729
+ replyTo?: string;
730
+ /**
731
+ * Override the adapter/account default link behavior for this post.
732
+ */
733
+ linkBehavior?: LinkBehavior;
734
+ }
735
+
736
+ /**
737
+ * Threads adapter for publishing via Meta Graph API
738
+ *
739
+ * @example
740
+ * ```typescript
741
+ * const threads = new ThreadsAdapter({
742
+ * type: 'threads',
743
+ * accessToken: 'user-access-token',
744
+ * userId: 'threads-user-id',
745
+ * });
746
+ *
747
+ * await threads.authenticate();
748
+ *
749
+ * const result = await threads.publishText({
750
+ * text: 'Breaking news from Bentley!',
751
+ * linkUrl: 'https://example.com/article',
752
+ * });
753
+ * ```
754
+ */
755
+ export declare class ThreadsAdapter implements SocialPlatform {
756
+ readonly platform: "threads";
757
+ private config;
758
+ constructor(config: ThreadsConfig);
759
+ authenticate(): Promise<AuthResult>;
760
+ refreshToken(_refreshToken: string): Promise<AuthResult>;
761
+ publishVideo(video: VideoPost): Promise<PostResult>;
762
+ publishImage(image: ImagePost): Promise<PostResult>;
763
+ publishText(text: TextPost): Promise<PostResult>;
764
+ publishLink(link: LinkPost): Promise<PostResult>;
765
+ /**
766
+ * Wait for media container to finish processing
767
+ */
768
+ private waitForContainer;
769
+ /**
770
+ * Publish a prepared container
771
+ */
772
+ private publishContainer;
773
+ /**
774
+ * Upload buffer to temporary storage and return URL
775
+ * Note: In production, this would upload to a CDN or storage service
776
+ */
777
+ private uploadToTempStorage;
778
+ getPost(postId: string): Promise<Post>;
779
+ deletePost(_postId: string): Promise<void>;
780
+ getAnalytics(postId: string): Promise<PostAnalytics>;
781
+ getCapabilities(): PlatformCapabilities;
782
+ /**
783
+ * Build post text with hashtags and link
784
+ */
785
+ private buildPostText;
786
+ /**
787
+ * Parse insights data into PostAnalytics
788
+ */
789
+ private parseInsights;
790
+ /**
791
+ * Map Threads media type to our type
792
+ */
793
+ private mapMediaType;
794
+ /**
795
+ * Handle API errors
796
+ */
797
+ private handleError;
798
+ }
799
+
800
+ /**
801
+ * Threads (Meta) configuration
802
+ */
803
+ export declare interface ThreadsConfig extends BaseSocialConfig {
804
+ type: 'threads';
805
+ /**
806
+ * Access token from Meta OAuth
807
+ */
808
+ accessToken: string;
809
+ /**
810
+ * Instagram/Threads user ID
811
+ */
812
+ userId: string;
813
+ }
814
+
815
+ /**
816
+ * Video post content
817
+ */
818
+ export declare interface VideoPost {
819
+ /**
820
+ * Video file buffer or URL
821
+ */
822
+ file: Buffer | string;
823
+ /**
824
+ * MIME type for the video file. Detected from URLs and common buffer
825
+ * signatures when omitted.
826
+ */
827
+ mimeType?: string;
828
+ /**
829
+ * Video title (YouTube, some platforms)
830
+ */
831
+ title?: string;
832
+ /**
833
+ * Post description/caption
834
+ */
835
+ description?: string;
836
+ /**
837
+ * Custom thumbnail image
838
+ */
839
+ thumbnail?: Buffer | string;
840
+ /**
841
+ * MIME type for the thumbnail image. Detected from URLs and common buffer
842
+ * signatures when omitted.
843
+ */
844
+ thumbnailMimeType?: string;
845
+ /**
846
+ * Hashtags to include
847
+ */
848
+ tags?: string[];
849
+ /**
850
+ * Link URL to include (e.g., article link)
851
+ */
852
+ linkUrl?: string;
853
+ /**
854
+ * Visibility setting
855
+ * @default 'public'
856
+ */
857
+ visibility?: 'public' | 'unlisted' | 'private';
858
+ /**
859
+ * Scheduled publish time (if supported)
860
+ */
861
+ scheduledAt?: Date;
862
+ /**
863
+ * Category ID (YouTube)
864
+ */
865
+ categoryId?: string;
866
+ /**
867
+ * Whether this is a Short (YouTube)
868
+ */
869
+ isShort?: boolean;
870
+ /**
871
+ * Override the adapter/account default link behavior for this post.
872
+ */
873
+ linkBehavior?: LinkBehavior;
874
+ }
875
+
876
+ /**
877
+ * X (Twitter) adapter for publishing
878
+ *
879
+ * @example
880
+ * ```typescript
881
+ * const x = new XAdapter({
882
+ * type: 'x',
883
+ * apiKey: 'consumer-key',
884
+ * apiSecret: 'consumer-secret',
885
+ * accessToken: 'user-access-token',
886
+ * accessSecret: 'user-access-secret',
887
+ * });
888
+ *
889
+ * await x.authenticate();
890
+ *
891
+ * const result = await x.publishText({
892
+ * text: 'Breaking news from Bentley!',
893
+ * linkUrl: 'https://example.com/article',
894
+ * });
895
+ * ```
896
+ */
897
+ export declare class XAdapter implements SocialPlatform {
898
+ readonly platform: "x";
899
+ private config;
900
+ private logger;
901
+ constructor(config: XConfig);
902
+ /**
903
+ * Generate OAuth 1.0a signature for request
904
+ */
905
+ private generateOAuthSignature;
906
+ private generateNonce;
907
+ private percentEncode;
908
+ private hmacSha1;
909
+ authenticate(): Promise<AuthResult>;
910
+ refreshToken(refreshToken: string): Promise<AuthResult>;
911
+ private basicAuthHeader;
912
+ publishVideo(video: VideoPost): Promise<PostResult>;
913
+ publishImage(image: ImagePost): Promise<PostResult>;
914
+ publishText(text: TextPost): Promise<PostResult>;
915
+ publishLink(link: LinkPost): Promise<PostResult>;
916
+ /**
917
+ * Upload media to Twitter
918
+ */
919
+ private uploadMedia;
920
+ private readMediaData;
921
+ /**
922
+ * Upload media using X API v2 and OAuth 2.0 user context.
923
+ */
924
+ private uploadMediaV2;
925
+ /**
926
+ * Upload media using legacy OAuth 1.0a upload endpoints.
927
+ */
928
+ private uploadMediaOAuth1;
929
+ /**
930
+ * Wait for media processing to complete
931
+ */
932
+ private waitForProcessing;
933
+ /**
934
+ * Set alt text for uploaded media
935
+ * Uses JSON body as required by metadata/create endpoint
936
+ */
937
+ private setMediaAltText;
938
+ /**
939
+ * Post link as reply (algorithm-friendly pattern)
940
+ */
941
+ private postLinkReply;
942
+ getPost(postId: string): Promise<Post>;
943
+ deletePost(postId: string): Promise<void>;
944
+ getAnalytics(postId: string): Promise<PostAnalytics>;
945
+ getCapabilities(): PlatformCapabilities;
946
+ private resolveLinkBehavior;
947
+ private usesOAuth2;
948
+ private requireOAuth1Config;
949
+ /**
950
+ * Build post text with hashtags
951
+ */
952
+ private buildPostText;
953
+ private truncatePostText;
954
+ private resolvePostType;
955
+ private inferMediaTypeFromKey;
956
+ /**
957
+ * Make authenticated request to Twitter API v2
958
+ */
959
+ private makeRequest;
960
+ private makeBearerUploadRequest;
961
+ /**
962
+ * Make authenticated request to Twitter Upload API
963
+ */
964
+ private makeUploadRequest;
965
+ /**
966
+ * Handle API errors
967
+ */
968
+ private handleError;
969
+ }
970
+
971
+ /**
972
+ * X (Twitter) configuration
973
+ */
974
+ export declare interface XConfig extends BaseSocialConfig {
975
+ type: 'x';
976
+ /**
977
+ * Authentication mode. OAuth 2.0 is used when accessSecret is omitted.
978
+ *
979
+ * @default 'oauth1' when accessSecret is present, otherwise 'oauth2'
980
+ */
981
+ authType?: 'oauth1' | 'oauth2';
982
+ /**
983
+ * API key (consumer key) for OAuth 1.0a.
984
+ */
985
+ apiKey?: string;
986
+ /**
987
+ * API secret (consumer secret) for OAuth 1.0a.
988
+ */
989
+ apiSecret?: string;
990
+ /**
991
+ * User access token.
992
+ */
993
+ accessToken: string;
994
+ /**
995
+ * User access token secret for OAuth 1.0a.
996
+ */
997
+ accessSecret?: string;
998
+ /**
999
+ * OAuth 2.0 client ID for refresh-token flows.
1000
+ */
1001
+ clientId?: string;
1002
+ /**
1003
+ * OAuth 2.0 client secret for confidential clients.
1004
+ */
1005
+ clientSecret?: string;
1006
+ /**
1007
+ * OAuth 2.0 refresh token.
1008
+ */
1009
+ refreshToken?: string;
1010
+ /**
1011
+ * Default handling for links.
1012
+ * @default 'inline'
1013
+ */
1014
+ linkBehavior?: LinkBehavior;
1015
+ }
1016
+
1017
+ /**
1018
+ * YouTube adapter for video publishing
1019
+ *
1020
+ * @example
1021
+ * ```typescript
1022
+ * const youtube = new YouTubeAdapter({
1023
+ * type: 'youtube',
1024
+ * clientId: 'your-client-id',
1025
+ * clientSecret: 'your-client-secret',
1026
+ * accessToken: 'user-access-token',
1027
+ * refreshToken: 'user-refresh-token',
1028
+ * });
1029
+ *
1030
+ * const result = await youtube.publishVideo({
1031
+ * file: videoBuffer,
1032
+ * title: 'Breaking News',
1033
+ * description: 'Latest updates...',
1034
+ * tags: ['news', 'local'],
1035
+ * isShort: true,
1036
+ * });
1037
+ * ```
1038
+ */
1039
+ export declare class YouTubeAdapter implements SocialPlatform {
1040
+ readonly platform: "youtube";
1041
+ private config;
1042
+ private logger;
1043
+ private currentAccessToken?;
1044
+ constructor(config: YouTubeConfig);
1045
+ /**
1046
+ * Generate OAuth authorization URL
1047
+ */
1048
+ getAuthorizationUrl(options?: AuthorizationOptions): AuthorizationResult;
1049
+ /**
1050
+ * Exchange authorization code for tokens
1051
+ */
1052
+ exchangeCode(params: CodeExchangeParams): Promise<AuthResult>;
1053
+ authenticate(): Promise<AuthResult>;
1054
+ refreshToken(refreshToken: string): Promise<AuthResult>;
1055
+ publishVideo(video: VideoPost): Promise<PostResult>;
1056
+ /**
1057
+ * Upload custom thumbnail
1058
+ * @returns true if upload succeeded, false otherwise
1059
+ */
1060
+ private uploadThumbnail;
1061
+ publishImage(_image: ImagePost): Promise<PostResult>;
1062
+ publishText(_text: TextPost): Promise<PostResult>;
1063
+ publishLink(_link: LinkPost): Promise<PostResult>;
1064
+ getPost(postId: string): Promise<Post>;
1065
+ deletePost(postId: string): Promise<void>;
1066
+ getAnalytics(postId: string): Promise<PostAnalytics>;
1067
+ getCapabilities(): PlatformCapabilities;
1068
+ /**
1069
+ * Build description with link and hashtags
1070
+ */
1071
+ private buildDescription;
1072
+ private parseMetric;
1073
+ /**
1074
+ * Handle API errors
1075
+ */
1076
+ private handleError;
1077
+ /**
1078
+ * Generate PKCE code verifier
1079
+ */
1080
+ private generateCodeVerifier;
1081
+ /**
1082
+ * Generate PKCE code challenge from verifier using S256
1083
+ */
1084
+ private generateCodeChallenge;
1085
+ }
1086
+
1087
+ /**
1088
+ * YouTube configuration
1089
+ */
1090
+ export declare interface YouTubeConfig extends BaseSocialConfig {
1091
+ type: 'youtube';
1092
+ /**
1093
+ * OAuth2 client ID
1094
+ */
1095
+ clientId: string;
1096
+ /**
1097
+ * OAuth2 client secret
1098
+ */
1099
+ clientSecret: string;
1100
+ /**
1101
+ * Access token (from OAuth flow)
1102
+ */
1103
+ accessToken?: string;
1104
+ /**
1105
+ * Refresh token (from OAuth flow)
1106
+ */
1107
+ refreshToken?: string;
1108
+ /**
1109
+ * Redirect URI for OAuth
1110
+ */
1111
+ redirectUri?: string;
1112
+ }
1113
+
1114
+ export { }