@classytic/social 0.1.0

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.
Files changed (121) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +21 -0
  3. package/README.md +368 -0
  4. package/dist/base-Bw7e52V8.mjs +246 -0
  5. package/dist/base-Bw7e52V8.mjs.map +1 -0
  6. package/dist/base-DBtKFiSX.d.mts +226 -0
  7. package/dist/base-DBtKFiSX.d.mts.map +1 -0
  8. package/dist/chunk-DQk6qfdC.mjs +18 -0
  9. package/dist/client/index.d.mts +44 -0
  10. package/dist/client/index.d.mts.map +1 -0
  11. package/dist/client/index.mjs +154 -0
  12. package/dist/client/index.mjs.map +1 -0
  13. package/dist/common/index.d.mts +3 -0
  14. package/dist/common/index.mjs +7 -0
  15. package/dist/contracts-Cdwa4zlg.d.mts +121 -0
  16. package/dist/contracts-Cdwa4zlg.d.mts.map +1 -0
  17. package/dist/contracts-lCa069IK.mjs +221 -0
  18. package/dist/contracts-lCa069IK.mjs.map +1 -0
  19. package/dist/env-Bl0cwwjC.mjs +955 -0
  20. package/dist/env-Bl0cwwjC.mjs.map +1 -0
  21. package/dist/env-DxOZHf0p.d.mts +394 -0
  22. package/dist/env-DxOZHf0p.d.mts.map +1 -0
  23. package/dist/errors-Cm6LeKf7.mjs +32 -0
  24. package/dist/errors-Cm6LeKf7.mjs.map +1 -0
  25. package/dist/facebook-l_4CghaA.mjs +95 -0
  26. package/dist/facebook-l_4CghaA.mjs.map +1 -0
  27. package/dist/http-DpcLSR1M.mjs +197 -0
  28. package/dist/http-DpcLSR1M.mjs.map +1 -0
  29. package/dist/index.d.mts +42 -0
  30. package/dist/index.d.mts.map +1 -0
  31. package/dist/index.mjs +71 -0
  32. package/dist/index.mjs.map +1 -0
  33. package/dist/instagram-BGaeUFU2.mjs +90 -0
  34. package/dist/instagram-BGaeUFU2.mjs.map +1 -0
  35. package/dist/linkedin-70whtVKa.mjs +101 -0
  36. package/dist/linkedin-70whtVKa.mjs.map +1 -0
  37. package/dist/meta-D3vcJU1c.mjs +126 -0
  38. package/dist/meta-D3vcJU1c.mjs.map +1 -0
  39. package/dist/pkce-jq5II68b.mjs +72 -0
  40. package/dist/pkce-jq5II68b.mjs.map +1 -0
  41. package/dist/polling-DZ1apXtA.mjs +25 -0
  42. package/dist/polling-DZ1apXtA.mjs.map +1 -0
  43. package/dist/providers/facebook.d.mts +135 -0
  44. package/dist/providers/facebook.d.mts.map +1 -0
  45. package/dist/providers/facebook.mjs +450 -0
  46. package/dist/providers/facebook.mjs.map +1 -0
  47. package/dist/providers/instagram.d.mts +122 -0
  48. package/dist/providers/instagram.d.mts.map +1 -0
  49. package/dist/providers/instagram.mjs +496 -0
  50. package/dist/providers/instagram.mjs.map +1 -0
  51. package/dist/providers/linkedin.d.mts +145 -0
  52. package/dist/providers/linkedin.d.mts.map +1 -0
  53. package/dist/providers/linkedin.mjs +574 -0
  54. package/dist/providers/linkedin.mjs.map +1 -0
  55. package/dist/providers/reddit.d.mts +102 -0
  56. package/dist/providers/reddit.d.mts.map +1 -0
  57. package/dist/providers/reddit.mjs +657 -0
  58. package/dist/providers/reddit.mjs.map +1 -0
  59. package/dist/providers/telegram.d.mts +139 -0
  60. package/dist/providers/telegram.d.mts.map +1 -0
  61. package/dist/providers/telegram.mjs +517 -0
  62. package/dist/providers/telegram.mjs.map +1 -0
  63. package/dist/providers/tiktok.d.mts +116 -0
  64. package/dist/providers/tiktok.d.mts.map +1 -0
  65. package/dist/providers/tiktok.mjs +676 -0
  66. package/dist/providers/tiktok.mjs.map +1 -0
  67. package/dist/providers/twitter.d.mts +150 -0
  68. package/dist/providers/twitter.d.mts.map +1 -0
  69. package/dist/providers/twitter.mjs +628 -0
  70. package/dist/providers/twitter.mjs.map +1 -0
  71. package/dist/providers/whatsapp.d.mts +79 -0
  72. package/dist/providers/whatsapp.d.mts.map +1 -0
  73. package/dist/providers/whatsapp.mjs +376 -0
  74. package/dist/providers/whatsapp.mjs.map +1 -0
  75. package/dist/providers/youtube.d.mts +153 -0
  76. package/dist/providers/youtube.d.mts.map +1 -0
  77. package/dist/providers/youtube.mjs +902 -0
  78. package/dist/providers/youtube.mjs.map +1 -0
  79. package/dist/reddit-B10kS4Se.mjs +126 -0
  80. package/dist/reddit-B10kS4Se.mjs.map +1 -0
  81. package/dist/schemas/index.d.mts +819 -0
  82. package/dist/schemas/index.d.mts.map +1 -0
  83. package/dist/schemas/index.mjs +31 -0
  84. package/dist/schemas/index.mjs.map +1 -0
  85. package/dist/security-BXhfebWm.d.mts +338 -0
  86. package/dist/security-BXhfebWm.d.mts.map +1 -0
  87. package/dist/shared-Fvc6xQku.mjs +100 -0
  88. package/dist/shared-Fvc6xQku.mjs.map +1 -0
  89. package/dist/telegram-FaUHpZgB.mjs +107 -0
  90. package/dist/telegram-FaUHpZgB.mjs.map +1 -0
  91. package/dist/tiktok-B_bMk4G-.mjs +94 -0
  92. package/dist/tiktok-B_bMk4G-.mjs.map +1 -0
  93. package/dist/twitter-BC22zfuc.mjs +98 -0
  94. package/dist/twitter-BC22zfuc.mjs.map +1 -0
  95. package/dist/types-BFE4psYI.d.mts +102 -0
  96. package/dist/types-BFE4psYI.d.mts.map +1 -0
  97. package/dist/types-Bv27tcT0.d.mts +230 -0
  98. package/dist/types-Bv27tcT0.d.mts.map +1 -0
  99. package/dist/types-BwkKyqpi.d.mts +253 -0
  100. package/dist/types-BwkKyqpi.d.mts.map +1 -0
  101. package/dist/types-CJrHMDV9.mjs +27 -0
  102. package/dist/types-CJrHMDV9.mjs.map +1 -0
  103. package/dist/types-ClbVc2rc.d.mts +117 -0
  104. package/dist/types-ClbVc2rc.d.mts.map +1 -0
  105. package/dist/types-D91N16Ym.d.mts +242 -0
  106. package/dist/types-D91N16Ym.d.mts.map +1 -0
  107. package/dist/types-DfLp_ibQ.d.mts +178 -0
  108. package/dist/types-DfLp_ibQ.d.mts.map +1 -0
  109. package/dist/types-DfjDgEoJ.d.mts +88 -0
  110. package/dist/types-DfjDgEoJ.d.mts.map +1 -0
  111. package/dist/types-Dp5Z9VBr.mjs +23 -0
  112. package/dist/types-Dp5Z9VBr.mjs.map +1 -0
  113. package/dist/types-hriBJTsU.d.mts +129 -0
  114. package/dist/types-hriBJTsU.d.mts.map +1 -0
  115. package/dist/types-rn6UuLL8.d.mts +184 -0
  116. package/dist/types-rn6UuLL8.d.mts.map +1 -0
  117. package/dist/whatsapp-CFp7ryR4.mjs +101 -0
  118. package/dist/whatsapp-CFp7ryR4.mjs.map +1 -0
  119. package/dist/youtube-Bs0fdY7H.mjs +98 -0
  120. package/dist/youtube-Bs0fdY7H.mjs.map +1 -0
  121. package/package.json +148 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-Bl0cwwjC.mjs","names":["errorResultMsg"],"sources":["../src/client/twitter.ts","../src/client/facebook.ts","../src/client/linkedin.ts","../src/client/reddit.ts","../src/client/instagram.ts","../src/client/youtube.ts","../src/client/tiktok.ts","../src/client/telegram.ts","../src/client/whatsapp.ts","../src/client/env.ts"],"sourcesContent":["/**\n * TwitterClient — credential-bound wrapper over `TwitterProvider`.\n */\n\nimport { TwitterProvider } from '../providers/twitter/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { TwitterClientConfig, SocialClientOptions, UnifiedPostInput, PostResult } from './types.js';\n\nexport class TwitterClient {\n readonly provider: TwitterProvider;\n\n constructor(public config: TwitterClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new TwitterProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n /** OAuth: get the consent URL. Async variant uses S256 PKCE (preferred). */\n async authUrl(state: string): Promise<string> {\n return this.provider.getAuthUrlAsync(state, this.config);\n }\n\n /** OAuth: exchange the callback code for tokens. Stores them on `this.config.tokens`. */\n async exchangeCode(code: string, state?: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config, state);\n this.config.tokens = tokens;\n return tokens;\n }\n\n /** Refresh the access token. Stores updated tokens. */\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token;\n if (!refreshToken) throw new SocialError('twitter', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /**\n * Post a tweet (text + optional media).\n *\n * Twitter requires media to be pre-uploaded via the v1.1 chunked endpoint —\n * pass each pre-uploaded media's ID as `media[i].id`. Items with only a\n * `url` are skipped (no automatic upload). For end-to-end upload see\n * `provider.uploadPhoto()` / `provider.uploadVideo()` on the underlying\n * `TwitterProvider`.\n */\n async post(input: UnifiedPostInput): Promise<PostResult> {\n try {\n const accessToken = this.assertAccessToken();\n const mediaIds = input.media?.map(m => m.id).filter((id): id is string => !!id);\n const skipped = (input.media?.length ?? 0) - (mediaIds?.length ?? 0);\n if (skipped > 0 && mediaIds?.length === 0) {\n throw new SocialError('twitter', 'Twitter requires pre-uploaded media IDs. Upload via TwitterProvider.uploadPhoto/uploadVideo first, then pass `media[i].id`.', { statusCode: 400 });\n }\n\n const result = await this.provider.createTweet(accessToken, {\n text: input.text ?? '',\n mediaIds: mediaIds?.length ? mediaIds : undefined,\n replyTo: input.perPlatform?.twitter?.replyTo,\n quoteTweetId: input.perPlatform?.twitter?.quoteTweet,\n });\n return {\n platform: 'twitter',\n ok: true,\n id: result.id,\n url: result.id ? `https://twitter.com/i/status/${result.id}` : undefined,\n raw: result,\n };\n } catch (err) {\n return errorResult('twitter', err);\n }\n }\n\n /** Delete a tweet by ID. */\n async delete(tweetId: string): Promise<void> {\n const accessToken = this.assertAccessToken();\n await this.provider.deleteTweet(accessToken, tweetId);\n }\n\n /** Get a tweet by ID. */\n async get(tweetId: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getTweet(accessToken, tweetId);\n }\n\n /** Send a direct message. */\n async sendDm(participantId: string, text: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.sendDirectMessage(accessToken, { participantId, text });\n }\n\n /** Get the authenticated user's profile. */\n async me(): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getAccountInfo(accessToken);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('twitter', 'Not authenticated. Call exchangeCode() first or pass tokens in config.', { statusCode: 401 });\n return t;\n }\n}\n\nexport function errorResult(platform: PostResult['platform'], err: unknown): PostResult {\n if (err instanceof SocialError) {\n return {\n platform,\n ok: false,\n error: { message: err.message, code: err.errorCode, retryable: err.retryable },\n };\n }\n return {\n platform,\n ok: false,\n error: { message: err instanceof Error ? err.message : String(err) },\n };\n}\n","/**\n * FacebookClient — credential-bound wrapper over `FacebookProvider`.\n */\n\nimport { FacebookProvider } from '../providers/facebook/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { FacebookClientConfig, SocialClientOptions, UnifiedPostInput, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class FacebookClient {\n readonly provider: FacebookProvider;\n\n constructor(public config: FacebookClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new FacebookProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n async authUrl(state: string): Promise<string> {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token ?? this.config.tokens?.access_token;\n if (!refreshToken) throw new SocialError('facebook', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /**\n * List Pages the authenticated user manages. Each result contains a\n * page-level access token. Set `pageId` + `pageAccessToken` on the config to\n * select a target page for posting.\n */\n async listPages(): Promise<Awaited<ReturnType<FacebookProvider['getPages']>>> {\n return this.provider.getPages(this.userToken());\n }\n\n /**\n * Convenience: pick a page by ID and bind its token to this client.\n */\n async usePage(pageId: string): Promise<void> {\n const pages = await this.listPages();\n const match = pages.find(p => p.id === pageId);\n if (!match) throw new SocialError('facebook', `Page ${pageId} not found in /me/accounts`, { statusCode: 404 });\n this.config.pageId = match.id;\n this.config.pageAccessToken = match.access_token;\n }\n\n /** Create a Page post — text, link, or photo depending on input. */\n async post(input: UnifiedPostInput): Promise<PostResult> {\n try {\n const { pageId, token } = this.assertPage(input);\n const scheduledAt = input.scheduledAt;\n\n // Photo post takes precedence over link / text\n const photo = input.media?.find(m => m.type === 'image' && m.url);\n if (photo?.url) {\n const r = await this.provider.createPhotoPost(token, pageId, photo.url, {\n caption: input.text,\n scheduledAt,\n });\n return {\n platform: 'facebook',\n ok: true,\n id: r.postId,\n url: `https://facebook.com/${r.postId}`,\n raw: r,\n };\n }\n if (input.link) {\n const r = await this.provider.createLinkPost(token, pageId, input.link, {\n message: input.text,\n scheduledAt,\n });\n return {\n platform: 'facebook',\n ok: true,\n id: r.postId,\n url: `https://facebook.com/${r.postId}`,\n raw: r,\n };\n }\n if (input.text) {\n const r = await this.provider.createPost(token, pageId, input.text, { scheduledAt });\n return {\n platform: 'facebook',\n ok: true,\n id: r.postId,\n url: `https://facebook.com/${r.postId}`,\n raw: r,\n };\n }\n throw new SocialError('facebook', 'Provide either text, link, or photo media', { statusCode: 400 });\n } catch (err) {\n return errorResult('facebook', err);\n }\n }\n\n async deletePost(postId: string): Promise<void> {\n const { token } = this.assertPage();\n await this.provider.deletePost(token, postId);\n }\n\n async getPost(postId: string): Promise<unknown> {\n const { token } = this.assertPage();\n return this.provider.getPost(token, postId);\n }\n\n async getFeed(limit?: number): Promise<unknown> {\n const { pageId, token } = this.assertPage();\n return this.provider.getPageFeed(token, pageId, limit);\n }\n\n private userToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('facebook', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n\n private assertPage(input?: UnifiedPostInput): { pageId: string; token: string } {\n const pageId = input?.perPlatform?.facebook?.pageId ?? this.config.pageId;\n const token = input?.perPlatform?.facebook?.pageAccessToken ?? this.config.pageAccessToken;\n if (!pageId || !token) {\n throw new SocialError('facebook', 'No Page selected. Call usePage(pageId) or set pageId/pageAccessToken in config.', { statusCode: 400 });\n }\n return { pageId, token };\n }\n}\n","/**\n * LinkedInClient — credential-bound wrapper over `LinkedInProvider`.\n */\n\nimport { LinkedInProvider } from '../providers/linkedin/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { LinkedInClientConfig, SocialClientOptions, UnifiedPostInput, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class LinkedInClient {\n readonly provider: LinkedInProvider;\n\n constructor(public config: LinkedInClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new LinkedInProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n async authUrl(state: string): Promise<string> {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token;\n if (!refreshToken) throw new SocialError('linkedin', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /** Resolve and cache the authenticated user's URN. */\n async resolveAuthor(): Promise<string> {\n if (this.config.authorUrn) return this.config.authorUrn;\n const accessToken = this.assertAccessToken();\n const info = await this.provider.getAccountInfo(accessToken);\n if (!info?.id) throw new SocialError('linkedin', 'Could not resolve author URN', { statusCode: 502 });\n const urn = `urn:li:person:${info.id}`;\n this.config.authorUrn = urn;\n return urn;\n }\n\n /** Create a post (text, article, or image). */\n async post(input: UnifiedPostInput): Promise<PostResult> {\n try {\n const accessToken = this.assertAccessToken();\n const author = input.perPlatform?.linkedin?.authorUrn ?? await this.resolveAuthor();\n\n if (input.link) {\n const r = await this.provider.createArticlePost(accessToken, author, input.text ?? '', input.link);\n return { platform: 'linkedin', ok: true, id: r.postId, raw: r };\n }\n if (!input.text) {\n throw new SocialError('linkedin', 'Provide text for the post', { statusCode: 400 });\n }\n const r = await this.provider.createTextPost(accessToken, author, input.text);\n return { platform: 'linkedin', ok: true, id: r.postId, raw: r };\n } catch (err) {\n return errorResult('linkedin', err);\n }\n }\n\n async deletePost(postUrn: string): Promise<void> {\n const accessToken = this.assertAccessToken();\n await this.provider.deletePost(accessToken, postUrn);\n }\n\n async getPost(postUrn: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getPost(accessToken, postUrn);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('linkedin', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n}\n","/**\n * RedditClient — credential-bound wrapper over `RedditProvider`.\n *\n * Reddit posts always require a `subreddit` and `title`. Pass them via\n * `input.perPlatform.reddit`.\n */\n\nimport { RedditProvider } from '../providers/reddit/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { RedditClientConfig, SocialClientOptions, UnifiedPostInput, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class RedditClient {\n readonly provider: RedditProvider;\n\n constructor(public config: RedditClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new RedditProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n async authUrl(state: string): Promise<string> {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token;\n if (!refreshToken) throw new SocialError('reddit', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /** Submit to a subreddit. Requires `subreddit` + `title` in `perPlatform.reddit`. */\n async post(input: UnifiedPostInput): Promise<PostResult> {\n try {\n const accessToken = this.assertAccessToken();\n const r = input.perPlatform?.reddit;\n if (!r?.subreddit || !r.title) {\n throw new SocialError('reddit', 'Reddit posts require `perPlatform.reddit.subreddit` and `perPlatform.reddit.title`', { statusCode: 400 });\n }\n const kind = r.kind ?? (input.link ? 'link' : 'self');\n const result = await this.provider.createPost(accessToken, {\n subreddit: r.subreddit,\n title: r.title,\n kind,\n text: input.text,\n url: input.link,\n });\n return { platform: 'reddit', ok: true, id: result.id, url: result.url, raw: result };\n } catch (err) {\n return errorResult('reddit', err);\n }\n }\n\n async deletePost(fullname: string): Promise<void> {\n const accessToken = this.assertAccessToken();\n await this.provider.deleteContent(accessToken, fullname);\n }\n\n async getPost(subreddit: string, postId: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getPost(accessToken, subreddit, postId);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('reddit', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n}\n","/**\n * InstagramClient — credential-bound wrapper over `InstagramProvider`.\n */\n\nimport { InstagramProvider } from '../providers/instagram/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { InstagramClientConfig, SocialClientOptions, UnifiedPostInput, UnifiedMedia, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class InstagramClient {\n readonly provider: InstagramProvider;\n\n constructor(public config: InstagramClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new InstagramProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n async authUrl(state: string): Promise<string> {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token ?? this.config.tokens?.access_token;\n if (!refreshToken) throw new SocialError('instagram', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /** Resolve and cache the Instagram Business User ID. */\n async resolveIgUser(): Promise<string> {\n if (this.config.igUserId) return this.config.igUserId;\n const accessToken = this.assertAccessToken();\n const info = await this.provider.getAccountInfo(accessToken) as { id?: string };\n if (!info?.id) throw new SocialError('instagram', 'Could not resolve Instagram Business Account ID', { statusCode: 502 });\n this.config.igUserId = info.id;\n return info.id;\n }\n\n /**\n * Post to Instagram. Behavior:\n * - 1 image → `uploadPhoto`\n * - 1 video → `uploadVideo` (Reel)\n * - 2-10 mixed media → `uploadCarousel`\n *\n * Text-only posts are not supported by Instagram.\n */\n async post(input: UnifiedPostInput): Promise<PostResult> {\n try {\n const accessToken = this.assertAccessToken();\n const igUserId = input.perPlatform?.instagram?.igUserId ?? await this.resolveIgUser();\n const media = input.media ?? [];\n\n if (media.length === 0) {\n throw new SocialError('instagram', 'Instagram requires at least one media item (image or video)', { statusCode: 400 });\n }\n\n if (media.length === 1) {\n const m = media[0]!;\n if (!m.url) {\n throw new SocialError('instagram', 'Instagram requires a public URL for each media item (no pre-uploaded media support)', { statusCode: 400 });\n }\n if (m.type === 'image') {\n const r = await this.provider.uploadPhoto({\n imageUrl: m.url,\n caption: input.text,\n tokens: { access_token: accessToken, igUserId } as never,\n } as never);\n return { platform: 'instagram', ok: true, id: r.mediaId, raw: r };\n }\n const r = await this.provider.uploadVideo({\n videoUrl: m.url,\n caption: input.text,\n tokens: { access_token: accessToken, igUserId } as never,\n } as never);\n return { platform: 'instagram', ok: true, id: r.platformVideoId ?? r.platformPostId, raw: r };\n }\n\n // Carousel\n const items = media.filter((m): m is UnifiedMedia & { url: string } => !!m.url);\n if (items.length !== media.length) {\n throw new SocialError('instagram', 'Instagram carousels require URLs for every media item', { statusCode: 400 });\n }\n const r = await this.provider.uploadCarousel({\n items: items.map(m => ({ type: m.type === 'image' ? 'IMAGE' : 'VIDEO', url: m.url })),\n caption: input.text,\n tokens: { access_token: accessToken, igUserId } as never,\n } as never);\n return { platform: 'instagram', ok: true, id: r.mediaId, raw: r };\n } catch (err) {\n return errorResult('instagram', err);\n }\n }\n\n async getMedia(mediaId: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getMedia(accessToken, mediaId);\n }\n\n async listMedia(opts?: { limit?: number; cursor?: string }): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n const igUserId = this.config.igUserId ?? await this.resolveIgUser();\n return this.provider.listMedia(accessToken, igUserId, opts);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('instagram', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n}\n","/**\n * YouTubeClient — credential-bound wrapper over `YouTubeProvider`.\n *\n * YouTube doesn't support text-only posts; use `upload()` to publish videos.\n */\n\nimport { YouTubeProvider } from '../providers/youtube/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { YouTubeClientConfig, SocialClientOptions, UnifiedUploadInput, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class YouTubeClient {\n readonly provider: YouTubeProvider;\n\n constructor(public config: YouTubeClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new YouTubeProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n authUrl(state: string): string {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token;\n if (!refreshToken) throw new SocialError('youtube', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /** Upload a video. */\n async upload(input: UnifiedUploadInput): Promise<PostResult> {\n try {\n this.assertAccessToken();\n const r = await this.provider.uploadVideo({\n filePath: input.filePath,\n videoUrl: input.videoUrl,\n title: input.title ?? '',\n description: input.description,\n tags: input.tags,\n privacy: input.privacy,\n scheduledAt: input.scheduledAt,\n credentials: this.config as unknown as Record<string, string>,\n tokens: this.config.tokens!,\n });\n return {\n platform: 'youtube',\n ok: true,\n id: r.platformVideoId ?? r.platformPostId,\n url: r.platformUrl ?? (r.platformVideoId ? `https://youtu.be/${r.platformVideoId}` : undefined),\n raw: r,\n };\n } catch (err) {\n return errorResult('youtube', err);\n }\n }\n\n async deleteVideo(videoId: string): Promise<void> {\n const accessToken = this.assertAccessToken();\n await this.provider.deleteVideo(accessToken, videoId, this.config);\n }\n\n async getVideo(videoId: string): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.getVideo(accessToken, videoId, this.config);\n }\n\n async listVideos(opts?: { maxResults?: number; pageToken?: string }): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.listVideos(accessToken, this.config, opts);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('youtube', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n}\n","/**\n * TikTokClient — credential-bound wrapper over `TikTokProvider`.\n */\n\nimport { TikTokProvider } from '../providers/tiktok/index.js';\nimport { SocialError } from '../errors.js';\nimport type { OAuthTokens } from '../base.js';\nimport type { TikTokClientConfig, SocialClientOptions, UnifiedUploadInput, PostResult } from './types.js';\nimport { errorResult } from './twitter.js';\n\nexport class TikTokClient {\n readonly provider: TikTokProvider;\n\n constructor(public config: TikTokClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new TikTokProvider({\n port: opts.port,\n redirectUri: config.redirectUri,\n environment: opts.environment,\n });\n }\n\n authUrl(state: string): string {\n return this.provider.getAuthUrl(state, this.config);\n }\n\n async exchangeCode(code: string, state?: string): Promise<OAuthTokens> {\n const tokens = await this.provider.exchangeCode(code, this.config, state);\n this.config.tokens = tokens;\n return tokens;\n }\n\n async refresh(): Promise<OAuthTokens> {\n const refreshToken = this.config.tokens?.refresh_token;\n if (!refreshToken) throw new SocialError('tiktok', 'No refresh_token available');\n const tokens = await this.provider.refreshToken(refreshToken, this.config);\n this.config.tokens = { ...this.config.tokens, ...tokens };\n return this.config.tokens;\n }\n\n /** Upload a video. */\n async upload(input: UnifiedUploadInput): Promise<PostResult> {\n try {\n this.assertAccessToken();\n const r = await this.provider.uploadVideo({\n filePath: input.filePath,\n videoUrl: input.videoUrl,\n title: input.title ?? input.caption,\n description: input.description ?? input.caption,\n privacy: input.privacy,\n scheduledAt: input.scheduledAt,\n credentials: this.config as unknown as Record<string, string>,\n tokens: this.config.tokens!,\n });\n return {\n platform: 'tiktok',\n ok: true,\n id: r.platformVideoId ?? r.platformPostId,\n url: r.platformUrl ?? null,\n raw: r,\n };\n } catch (err) {\n return errorResult('tiktok', err);\n }\n }\n\n async listVideos(opts?: { maxCount?: number; cursor?: number }): Promise<unknown> {\n const accessToken = this.assertAccessToken();\n return this.provider.listVideos(accessToken, opts);\n }\n\n private assertAccessToken(): string {\n const t = this.config.tokens?.access_token;\n if (!t) throw new SocialError('tiktok', 'Not authenticated. Call exchangeCode() first.', { statusCode: 401 });\n return t;\n }\n}\n","/**\n * TelegramClient — credential-bound wrapper over `TelegramProvider`.\n *\n * Telegram uses Bot Tokens (no OAuth). The bot must be added as admin to the\n * target channel/group.\n */\n\nimport { TelegramProvider } from '../providers/telegram/index.js';\nimport { SocialError } from '../errors.js';\nimport type { TelegramClientConfig, SocialClientOptions, MessageResult } from './types.js';\n\nexport class TelegramClient {\n readonly provider: TelegramProvider;\n\n constructor(public config: TelegramClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new TelegramProvider({ port: opts.port });\n }\n\n /** Send a text message. Falls back to `config.chatId` if `to` is omitted. */\n async send(text: string, to?: string | number): Promise<MessageResult> {\n try {\n const chatId = this.assertChatId(to);\n const result = await this.provider.sendMessage(this.config.botToken, chatId, text);\n return {\n platform: 'telegram',\n ok: true,\n id: String((result as { message_id?: number }).message_id ?? ''),\n raw: result,\n };\n } catch (err) {\n return errorResultMsg(err);\n }\n }\n\n async sendPhoto(photoUrl: string, opts: { caption?: string; to?: string | number } = {}): Promise<unknown> {\n const chatId = this.assertChatId(opts.to);\n return this.provider.sendPhoto(this.config.botToken, chatId, photoUrl, { caption: opts.caption });\n }\n\n async sendVideo(videoUrl: string, opts: { caption?: string; to?: string | number } = {}): Promise<unknown> {\n const chatId = this.assertChatId(opts.to);\n return this.provider.sendVideo(this.config.botToken, chatId, videoUrl, { caption: opts.caption });\n }\n\n async sendDocument(documentUrl: string, opts: { caption?: string; to?: string | number } = {}): Promise<unknown> {\n const chatId = this.assertChatId(opts.to);\n return this.provider.sendDocument(this.config.botToken, chatId, documentUrl, { caption: opts.caption });\n }\n\n async deleteMessage(messageId: string | number, to?: string | number): Promise<unknown> {\n const chatId = this.assertChatId(to);\n return this.provider.deleteMessage(this.config.botToken, chatId, Number(messageId));\n }\n\n async getChat(chatId?: string | number): Promise<unknown> {\n return this.provider.getChat(this.config.botToken, this.assertChatId(chatId));\n }\n\n async discoverChats(): Promise<unknown> {\n return this.provider.discoverChats(this.config.botToken);\n }\n\n async me(): Promise<unknown> {\n return this.provider.getAccountInfo(this.config.botToken);\n }\n\n private assertChatId(to?: string | number): string | number {\n const id = to ?? this.config.chatId;\n if (id === undefined || id === null || id === '') {\n throw new SocialError('telegram', 'No chat ID provided. Pass `to` or set `chatId` in config.', { statusCode: 400 });\n }\n return id;\n }\n}\n\nfunction errorResultMsg(err: unknown): MessageResult {\n if (err instanceof SocialError) {\n return { platform: 'telegram', ok: false, error: { message: err.message, code: err.errorCode } };\n }\n return {\n platform: 'telegram',\n ok: false,\n error: { message: err instanceof Error ? err.message : String(err) },\n };\n}\n","/**\n * WhatsAppClient — credential-bound wrapper over `WhatsAppProvider`.\n *\n * WhatsApp uses permanent System User tokens (no OAuth).\n */\n\nimport { WhatsAppProvider } from '../providers/whatsapp/index.js';\nimport { SocialError } from '../errors.js';\nimport type { WhatsAppClientConfig, SocialClientOptions, MessageResult } from './types.js';\n\nexport class WhatsAppClient {\n readonly provider: WhatsAppProvider;\n\n constructor(public config: WhatsAppClientConfig, opts: SocialClientOptions = {}) {\n this.provider = new WhatsAppProvider({ port: opts.port });\n }\n\n /** Send a text message to an E.164 phone number. */\n async send(text: string, to: string): Promise<MessageResult> {\n try {\n const phoneNumberId = this.assertPhoneNumberId();\n const result = await this.provider.sendMessage(this.config.accessToken, phoneNumberId, {\n to,\n type: 'text',\n text: { body: text },\n });\n const id = (result as { messages?: Array<{ id: string }> }).messages?.[0]?.id;\n return { platform: 'whatsapp', ok: true, id, raw: result };\n } catch (err) {\n return errorResultMsg(err);\n }\n }\n\n async sendImage(to: string, imageUrl: string, caption?: string): Promise<unknown> {\n const phoneNumberId = this.assertPhoneNumberId();\n return this.provider.sendImage(this.config.accessToken, phoneNumberId, { to, imageUrl, caption });\n }\n\n async sendVideo(to: string, videoUrl: string, caption?: string): Promise<unknown> {\n const phoneNumberId = this.assertPhoneNumberId();\n return this.provider.sendVideo(this.config.accessToken, phoneNumberId, { to, videoUrl, caption });\n }\n\n async sendDocument(to: string, documentUrl: string, opts: { caption?: string; filename?: string } = {}): Promise<unknown> {\n const phoneNumberId = this.assertPhoneNumberId();\n return this.provider.sendDocument(this.config.accessToken, phoneNumberId, {\n to,\n documentUrl,\n caption: opts.caption,\n filename: opts.filename,\n });\n }\n\n async listPhoneNumbers(): Promise<unknown> {\n return this.provider.getPhoneNumbers(this.config.accessToken, this.config.businessAccountId);\n }\n\n async listTemplates(): Promise<unknown> {\n return this.provider.getTemplates(this.config.accessToken, this.config.businessAccountId);\n }\n\n private assertPhoneNumberId(): string {\n if (!this.config.phoneNumberId) {\n throw new SocialError('whatsapp', 'phoneNumberId is required. Set it in config or call listPhoneNumbers() first.', { statusCode: 400 });\n }\n return this.config.phoneNumberId;\n }\n}\n\nfunction errorResultMsg(err: unknown): MessageResult {\n if (err instanceof SocialError) {\n return { platform: 'whatsapp', ok: false, error: { message: err.message, code: err.errorCode } };\n }\n return {\n platform: 'whatsapp',\n ok: false,\n error: { message: err instanceof Error ? err.message : String(err) },\n };\n}\n","/**\n * Auto-configure a `SocialClient` from environment variables.\n *\n * Recognized variables (every platform is optional):\n *\n * YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, YOUTUBE_REDIRECT_URI,\n * YOUTUBE_ACCESS_TOKEN, YOUTUBE_REFRESH_TOKEN\n *\n * TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET, TWITTER_REDIRECT_URI,\n * TWITTER_ACCESS_TOKEN, TWITTER_REFRESH_TOKEN\n *\n * FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, FACEBOOK_REDIRECT_URI,\n * FACEBOOK_ACCESS_TOKEN, FACEBOOK_PAGE_ID, FACEBOOK_PAGE_ACCESS_TOKEN\n *\n * INSTAGRAM_APP_ID, INSTAGRAM_APP_SECRET, INSTAGRAM_REDIRECT_URI,\n * INSTAGRAM_ACCESS_TOKEN, INSTAGRAM_USER_ID\n *\n * LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET, LINKEDIN_REDIRECT_URI,\n * LINKEDIN_ACCESS_TOKEN, LINKEDIN_AUTHOR_URN\n *\n * REDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET, REDDIT_USER_AGENT,\n * REDDIT_REDIRECT_URI, REDDIT_ACCESS_TOKEN, REDDIT_REFRESH_TOKEN\n *\n * TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_REDIRECT_URI,\n * TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN\n *\n * TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID\n *\n * WHATSAPP_ACCESS_TOKEN, WHATSAPP_BUSINESS_ACCOUNT_ID, WHATSAPP_PHONE_NUMBER_ID\n */\n\nimport { SocialClient } from './index.js';\nimport type { ProviderConfigMap, SocialClientOptions } from './types.js';\nimport type { OAuthTokens } from '../base.js';\n\ntype Env = Record<string, string | undefined>;\n\nfunction tokensFrom(env: Env, prefix: string): OAuthTokens | undefined {\n const access = env[`${prefix}_ACCESS_TOKEN`];\n if (!access) return undefined;\n return {\n access_token: access,\n refresh_token: env[`${prefix}_REFRESH_TOKEN`],\n };\n}\n\n/**\n * Build a `SocialClient` from `process.env` (or any compatible record).\n * Only platforms whose required vars are present are enabled.\n */\nexport function fromEnv(env: Env = (typeof process !== 'undefined' ? process.env : {}), opts?: SocialClientOptions): SocialClient {\n const config: ProviderConfigMap = {};\n\n if (env.YOUTUBE_CLIENT_ID && env.YOUTUBE_CLIENT_SECRET) {\n config.youtube = {\n clientId: env.YOUTUBE_CLIENT_ID,\n clientSecret: env.YOUTUBE_CLIENT_SECRET,\n redirectUri: env.YOUTUBE_REDIRECT_URI,\n tokens: tokensFrom(env, 'YOUTUBE'),\n };\n }\n if (env.TWITTER_CLIENT_ID) {\n config.twitter = {\n clientId: env.TWITTER_CLIENT_ID,\n clientSecret: env.TWITTER_CLIENT_SECRET,\n redirectUri: env.TWITTER_REDIRECT_URI,\n tokens: tokensFrom(env, 'TWITTER'),\n };\n }\n if (env.FACEBOOK_APP_ID && env.FACEBOOK_APP_SECRET) {\n config.facebook = {\n appId: env.FACEBOOK_APP_ID,\n appSecret: env.FACEBOOK_APP_SECRET,\n redirectUri: env.FACEBOOK_REDIRECT_URI,\n tokens: tokensFrom(env, 'FACEBOOK'),\n pageId: env.FACEBOOK_PAGE_ID,\n pageAccessToken: env.FACEBOOK_PAGE_ACCESS_TOKEN,\n };\n }\n if (env.INSTAGRAM_APP_ID && env.INSTAGRAM_APP_SECRET) {\n config.instagram = {\n appId: env.INSTAGRAM_APP_ID,\n appSecret: env.INSTAGRAM_APP_SECRET,\n redirectUri: env.INSTAGRAM_REDIRECT_URI,\n tokens: tokensFrom(env, 'INSTAGRAM'),\n igUserId: env.INSTAGRAM_USER_ID,\n };\n }\n if (env.LINKEDIN_CLIENT_ID && env.LINKEDIN_CLIENT_SECRET) {\n config.linkedin = {\n clientId: env.LINKEDIN_CLIENT_ID,\n clientSecret: env.LINKEDIN_CLIENT_SECRET,\n redirectUri: env.LINKEDIN_REDIRECT_URI,\n tokens: tokensFrom(env, 'LINKEDIN'),\n authorUrn: env.LINKEDIN_AUTHOR_URN,\n };\n }\n if (env.REDDIT_CLIENT_ID && env.REDDIT_CLIENT_SECRET && env.REDDIT_USER_AGENT) {\n config.reddit = {\n clientId: env.REDDIT_CLIENT_ID,\n clientSecret: env.REDDIT_CLIENT_SECRET,\n userAgent: env.REDDIT_USER_AGENT,\n redirectUri: env.REDDIT_REDIRECT_URI,\n tokens: tokensFrom(env, 'REDDIT'),\n };\n }\n if (env.TIKTOK_CLIENT_KEY && env.TIKTOK_CLIENT_SECRET) {\n config.tiktok = {\n clientKey: env.TIKTOK_CLIENT_KEY,\n clientSecret: env.TIKTOK_CLIENT_SECRET,\n redirectUri: env.TIKTOK_REDIRECT_URI,\n tokens: tokensFrom(env, 'TIKTOK'),\n };\n }\n if (env.TELEGRAM_BOT_TOKEN) {\n config.telegram = {\n botToken: env.TELEGRAM_BOT_TOKEN,\n chatId: env.TELEGRAM_CHAT_ID,\n };\n }\n if (env.WHATSAPP_ACCESS_TOKEN && env.WHATSAPP_BUSINESS_ACCOUNT_ID) {\n config.whatsapp = {\n accessToken: env.WHATSAPP_ACCESS_TOKEN,\n businessAccountId: env.WHATSAPP_BUSINESS_ACCOUNT_ID,\n phoneNumberId: env.WHATSAPP_PHONE_NUMBER_ID,\n };\n }\n\n return new SocialClient(config, opts);\n}\n"],"mappings":"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"}
@@ -0,0 +1,394 @@
1
+ import { o as OAuthTokens } from "./base-DBtKFiSX.mjs";
2
+ import { TwitterProvider } from "./providers/twitter.mjs";
3
+ import { FacebookProvider } from "./providers/facebook.mjs";
4
+ import { LinkedInProvider } from "./providers/linkedin.mjs";
5
+ import { RedditProvider } from "./providers/reddit.mjs";
6
+ import { InstagramProvider } from "./providers/instagram.mjs";
7
+ import { YouTubeProvider } from "./providers/youtube.mjs";
8
+ import { TikTokProvider } from "./providers/tiktok.mjs";
9
+ import { TelegramProvider } from "./providers/telegram.mjs";
10
+ import { WhatsAppProvider } from "./providers/whatsapp.mjs";
11
+ import { SocialClient } from "./client/index.mjs";
12
+
13
+ //#region src/client/types.d.ts
14
+ interface CommonOAuthCreds {
15
+ redirectUri?: string;
16
+ /** Tokens returned by the OAuth flow. Set after `exchangeCode()`. */
17
+ tokens?: OAuthTokens;
18
+ }
19
+ interface YouTubeClientConfig extends CommonOAuthCreds {
20
+ clientId: string;
21
+ clientSecret: string;
22
+ }
23
+ interface TwitterClientConfig extends CommonOAuthCreds {
24
+ clientId: string;
25
+ /** Required for confidential clients only. */
26
+ clientSecret?: string;
27
+ }
28
+ interface FacebookClientConfig extends CommonOAuthCreds {
29
+ appId: string;
30
+ appSecret: string;
31
+ /** Page to post to. Set after calling `getPages()`. */
32
+ pageId?: string;
33
+ /** Page-specific access token (never expires when derived from a long-lived user token). */
34
+ pageAccessToken?: string;
35
+ }
36
+ interface InstagramClientConfig extends CommonOAuthCreds {
37
+ appId: string;
38
+ appSecret: string;
39
+ /** Instagram Business Account ID. Resolved from getAccountInfo(). */
40
+ igUserId?: string;
41
+ }
42
+ interface LinkedInClientConfig extends CommonOAuthCreds {
43
+ clientId: string;
44
+ clientSecret: string;
45
+ /** Author URN — `urn:li:person:xxx` or `urn:li:organization:xxx`. */
46
+ authorUrn?: string;
47
+ }
48
+ interface RedditClientConfig extends CommonOAuthCreds {
49
+ clientId: string;
50
+ clientSecret: string;
51
+ /** Required: unique User-Agent (e.g. `web:my-app:v1.0 (by /u/yourname)`). */
52
+ userAgent: string;
53
+ }
54
+ interface TikTokClientConfig extends CommonOAuthCreds {
55
+ clientKey: string;
56
+ clientSecret: string;
57
+ }
58
+ interface TelegramClientConfig {
59
+ botToken: string;
60
+ /** Default chat/channel to send to. May be overridden per-call. */
61
+ chatId?: string | number;
62
+ }
63
+ interface WhatsAppClientConfig {
64
+ accessToken: string;
65
+ businessAccountId: string;
66
+ phoneNumberId?: string;
67
+ }
68
+ /**
69
+ * Per-provider credential map. Pass only the platforms you want to use; the
70
+ * client lazily instantiates each sub-client.
71
+ */
72
+ interface ProviderConfigMap {
73
+ youtube?: YouTubeClientConfig;
74
+ twitter?: TwitterClientConfig;
75
+ facebook?: FacebookClientConfig;
76
+ instagram?: InstagramClientConfig;
77
+ linkedin?: LinkedInClientConfig;
78
+ reddit?: RedditClientConfig;
79
+ tiktok?: TikTokClientConfig;
80
+ telegram?: TelegramClientConfig;
81
+ whatsapp?: WhatsAppClientConfig;
82
+ }
83
+ type ProviderName = keyof ProviderConfigMap;
84
+ interface SocialClientOptions {
85
+ /** Default port for OAuth redirect URIs. */
86
+ port?: number;
87
+ /** Provider environment — affects scopes for providers that support sandbox. */
88
+ environment?: 'sandbox' | 'production';
89
+ }
90
+ interface UnifiedMedia {
91
+ type: 'image' | 'video';
92
+ /** Public URL of the media file. Required unless `id` is provided. */
93
+ url?: string;
94
+ /** Pre-uploaded media identifier (e.g. Twitter media ID, WhatsApp media ID). */
95
+ id?: string;
96
+ alt?: string;
97
+ }
98
+ interface UnifiedPostInput {
99
+ /** Body text / caption / tweet content. */
100
+ text?: string;
101
+ /** Up to 4 (Twitter) / 10 (Instagram carousel) media items. */
102
+ media?: UnifiedMedia[];
103
+ /** URL for link-share posts (Facebook, Reddit). */
104
+ link?: string;
105
+ /** Schedule publication (where supported: Facebook, YouTube, TikTok). */
106
+ scheduledAt?: string | Date;
107
+ /** Per-platform overrides — escape hatch. Keys are provider names. */
108
+ perPlatform?: {
109
+ facebook?: {
110
+ pageId?: string;
111
+ pageAccessToken?: string;
112
+ };
113
+ instagram?: {
114
+ igUserId?: string;
115
+ };
116
+ linkedin?: {
117
+ authorUrn?: string;
118
+ };
119
+ reddit?: {
120
+ subreddit: string;
121
+ title: string;
122
+ kind?: 'self' | 'link';
123
+ };
124
+ twitter?: {
125
+ replyTo?: string;
126
+ quoteTweet?: string;
127
+ };
128
+ };
129
+ }
130
+ interface PostResult {
131
+ platform: ProviderName;
132
+ ok: boolean;
133
+ /** Provider-side post identifier. */
134
+ id?: string;
135
+ /** Permalink to the post on the provider's site. */
136
+ url?: string | null;
137
+ /** Error if `ok: false`. */
138
+ error?: {
139
+ message: string;
140
+ code?: string | number | null;
141
+ retryable?: boolean | null;
142
+ };
143
+ /** Original provider response. */
144
+ raw?: unknown;
145
+ }
146
+ interface MultiPostInput extends UnifiedPostInput {
147
+ /** Platforms to publish to. Defaults to all configured posting-capable platforms. */
148
+ platforms?: ProviderName[];
149
+ }
150
+ interface MultiPostResult {
151
+ /** Per-platform outcomes. */
152
+ results: PostResult[];
153
+ /** True if all platforms succeeded. */
154
+ allOk: boolean;
155
+ }
156
+ interface UnifiedUploadInput {
157
+ videoUrl?: string;
158
+ filePath?: string;
159
+ title?: string;
160
+ caption?: string;
161
+ description?: string;
162
+ tags?: string[];
163
+ privacy?: 'public' | 'private' | 'unlisted';
164
+ scheduledAt?: string | Date;
165
+ thumbnailUrl?: string;
166
+ }
167
+ interface MultiUploadInput extends UnifiedUploadInput {
168
+ platforms?: ProviderName[];
169
+ }
170
+ interface MessageInput {
171
+ platform: 'telegram' | 'whatsapp';
172
+ /** Recipient — chat ID for Telegram, E.164 phone number for WhatsApp. */
173
+ to?: string | number;
174
+ text: string;
175
+ }
176
+ interface MessageResult {
177
+ platform: 'telegram' | 'whatsapp';
178
+ ok: boolean;
179
+ id?: string;
180
+ error?: {
181
+ message: string;
182
+ code?: string | number | null;
183
+ };
184
+ raw?: unknown;
185
+ }
186
+ //#endregion
187
+ //#region src/client/twitter.d.ts
188
+ declare class TwitterClient {
189
+ config: TwitterClientConfig;
190
+ readonly provider: TwitterProvider;
191
+ constructor(config: TwitterClientConfig, opts?: SocialClientOptions);
192
+ /** OAuth: get the consent URL. Async variant uses S256 PKCE (preferred). */
193
+ authUrl(state: string): Promise<string>;
194
+ /** OAuth: exchange the callback code for tokens. Stores them on `this.config.tokens`. */
195
+ exchangeCode(code: string, state?: string): Promise<OAuthTokens>;
196
+ /** Refresh the access token. Stores updated tokens. */
197
+ refresh(): Promise<OAuthTokens>;
198
+ /**
199
+ * Post a tweet (text + optional media).
200
+ *
201
+ * Twitter requires media to be pre-uploaded via the v1.1 chunked endpoint —
202
+ * pass each pre-uploaded media's ID as `media[i].id`. Items with only a
203
+ * `url` are skipped (no automatic upload). For end-to-end upload see
204
+ * `provider.uploadPhoto()` / `provider.uploadVideo()` on the underlying
205
+ * `TwitterProvider`.
206
+ */
207
+ post(input: UnifiedPostInput): Promise<PostResult>;
208
+ /** Delete a tweet by ID. */
209
+ delete(tweetId: string): Promise<void>;
210
+ /** Get a tweet by ID. */
211
+ get(tweetId: string): Promise<unknown>;
212
+ /** Send a direct message. */
213
+ sendDm(participantId: string, text: string): Promise<unknown>;
214
+ /** Get the authenticated user's profile. */
215
+ me(): Promise<unknown>;
216
+ private assertAccessToken;
217
+ }
218
+ //#endregion
219
+ //#region src/client/facebook.d.ts
220
+ declare class FacebookClient {
221
+ config: FacebookClientConfig;
222
+ readonly provider: FacebookProvider;
223
+ constructor(config: FacebookClientConfig, opts?: SocialClientOptions);
224
+ authUrl(state: string): Promise<string>;
225
+ exchangeCode(code: string): Promise<OAuthTokens>;
226
+ refresh(): Promise<OAuthTokens>;
227
+ /**
228
+ * List Pages the authenticated user manages. Each result contains a
229
+ * page-level access token. Set `pageId` + `pageAccessToken` on the config to
230
+ * select a target page for posting.
231
+ */
232
+ listPages(): Promise<Awaited<ReturnType<FacebookProvider['getPages']>>>;
233
+ /**
234
+ * Convenience: pick a page by ID and bind its token to this client.
235
+ */
236
+ usePage(pageId: string): Promise<void>;
237
+ /** Create a Page post — text, link, or photo depending on input. */
238
+ post(input: UnifiedPostInput): Promise<PostResult>;
239
+ deletePost(postId: string): Promise<void>;
240
+ getPost(postId: string): Promise<unknown>;
241
+ getFeed(limit?: number): Promise<unknown>;
242
+ private userToken;
243
+ private assertPage;
244
+ }
245
+ //#endregion
246
+ //#region src/client/linkedin.d.ts
247
+ declare class LinkedInClient {
248
+ config: LinkedInClientConfig;
249
+ readonly provider: LinkedInProvider;
250
+ constructor(config: LinkedInClientConfig, opts?: SocialClientOptions);
251
+ authUrl(state: string): Promise<string>;
252
+ exchangeCode(code: string): Promise<OAuthTokens>;
253
+ refresh(): Promise<OAuthTokens>;
254
+ /** Resolve and cache the authenticated user's URN. */
255
+ resolveAuthor(): Promise<string>;
256
+ /** Create a post (text, article, or image). */
257
+ post(input: UnifiedPostInput): Promise<PostResult>;
258
+ deletePost(postUrn: string): Promise<void>;
259
+ getPost(postUrn: string): Promise<unknown>;
260
+ private assertAccessToken;
261
+ }
262
+ //#endregion
263
+ //#region src/client/reddit.d.ts
264
+ declare class RedditClient {
265
+ config: RedditClientConfig;
266
+ readonly provider: RedditProvider;
267
+ constructor(config: RedditClientConfig, opts?: SocialClientOptions);
268
+ authUrl(state: string): Promise<string>;
269
+ exchangeCode(code: string): Promise<OAuthTokens>;
270
+ refresh(): Promise<OAuthTokens>;
271
+ /** Submit to a subreddit. Requires `subreddit` + `title` in `perPlatform.reddit`. */
272
+ post(input: UnifiedPostInput): Promise<PostResult>;
273
+ deletePost(fullname: string): Promise<void>;
274
+ getPost(subreddit: string, postId: string): Promise<unknown>;
275
+ private assertAccessToken;
276
+ }
277
+ //#endregion
278
+ //#region src/client/instagram.d.ts
279
+ declare class InstagramClient {
280
+ config: InstagramClientConfig;
281
+ readonly provider: InstagramProvider;
282
+ constructor(config: InstagramClientConfig, opts?: SocialClientOptions);
283
+ authUrl(state: string): Promise<string>;
284
+ exchangeCode(code: string): Promise<OAuthTokens>;
285
+ refresh(): Promise<OAuthTokens>;
286
+ /** Resolve and cache the Instagram Business User ID. */
287
+ resolveIgUser(): Promise<string>;
288
+ /**
289
+ * Post to Instagram. Behavior:
290
+ * - 1 image → `uploadPhoto`
291
+ * - 1 video → `uploadVideo` (Reel)
292
+ * - 2-10 mixed media → `uploadCarousel`
293
+ *
294
+ * Text-only posts are not supported by Instagram.
295
+ */
296
+ post(input: UnifiedPostInput): Promise<PostResult>;
297
+ getMedia(mediaId: string): Promise<unknown>;
298
+ listMedia(opts?: {
299
+ limit?: number;
300
+ cursor?: string;
301
+ }): Promise<unknown>;
302
+ private assertAccessToken;
303
+ }
304
+ //#endregion
305
+ //#region src/client/youtube.d.ts
306
+ declare class YouTubeClient {
307
+ config: YouTubeClientConfig;
308
+ readonly provider: YouTubeProvider;
309
+ constructor(config: YouTubeClientConfig, opts?: SocialClientOptions);
310
+ authUrl(state: string): string;
311
+ exchangeCode(code: string): Promise<OAuthTokens>;
312
+ refresh(): Promise<OAuthTokens>;
313
+ /** Upload a video. */
314
+ upload(input: UnifiedUploadInput): Promise<PostResult>;
315
+ deleteVideo(videoId: string): Promise<void>;
316
+ getVideo(videoId: string): Promise<unknown>;
317
+ listVideos(opts?: {
318
+ maxResults?: number;
319
+ pageToken?: string;
320
+ }): Promise<unknown>;
321
+ private assertAccessToken;
322
+ }
323
+ //#endregion
324
+ //#region src/client/tiktok.d.ts
325
+ declare class TikTokClient {
326
+ config: TikTokClientConfig;
327
+ readonly provider: TikTokProvider;
328
+ constructor(config: TikTokClientConfig, opts?: SocialClientOptions);
329
+ authUrl(state: string): string;
330
+ exchangeCode(code: string, state?: string): Promise<OAuthTokens>;
331
+ refresh(): Promise<OAuthTokens>;
332
+ /** Upload a video. */
333
+ upload(input: UnifiedUploadInput): Promise<PostResult>;
334
+ listVideos(opts?: {
335
+ maxCount?: number;
336
+ cursor?: number;
337
+ }): Promise<unknown>;
338
+ private assertAccessToken;
339
+ }
340
+ //#endregion
341
+ //#region src/client/telegram.d.ts
342
+ declare class TelegramClient {
343
+ config: TelegramClientConfig;
344
+ readonly provider: TelegramProvider;
345
+ constructor(config: TelegramClientConfig, opts?: SocialClientOptions);
346
+ /** Send a text message. Falls back to `config.chatId` if `to` is omitted. */
347
+ send(text: string, to?: string | number): Promise<MessageResult>;
348
+ sendPhoto(photoUrl: string, opts?: {
349
+ caption?: string;
350
+ to?: string | number;
351
+ }): Promise<unknown>;
352
+ sendVideo(videoUrl: string, opts?: {
353
+ caption?: string;
354
+ to?: string | number;
355
+ }): Promise<unknown>;
356
+ sendDocument(documentUrl: string, opts?: {
357
+ caption?: string;
358
+ to?: string | number;
359
+ }): Promise<unknown>;
360
+ deleteMessage(messageId: string | number, to?: string | number): Promise<unknown>;
361
+ getChat(chatId?: string | number): Promise<unknown>;
362
+ discoverChats(): Promise<unknown>;
363
+ me(): Promise<unknown>;
364
+ private assertChatId;
365
+ }
366
+ //#endregion
367
+ //#region src/client/whatsapp.d.ts
368
+ declare class WhatsAppClient {
369
+ config: WhatsAppClientConfig;
370
+ readonly provider: WhatsAppProvider;
371
+ constructor(config: WhatsAppClientConfig, opts?: SocialClientOptions);
372
+ /** Send a text message to an E.164 phone number. */
373
+ send(text: string, to: string): Promise<MessageResult>;
374
+ sendImage(to: string, imageUrl: string, caption?: string): Promise<unknown>;
375
+ sendVideo(to: string, videoUrl: string, caption?: string): Promise<unknown>;
376
+ sendDocument(to: string, documentUrl: string, opts?: {
377
+ caption?: string;
378
+ filename?: string;
379
+ }): Promise<unknown>;
380
+ listPhoneNumbers(): Promise<unknown>;
381
+ listTemplates(): Promise<unknown>;
382
+ private assertPhoneNumberId;
383
+ }
384
+ //#endregion
385
+ //#region src/client/env.d.ts
386
+ type Env = Record<string, string | undefined>;
387
+ /**
388
+ * Build a `SocialClient` from `process.env` (or any compatible record).
389
+ * Only platforms whose required vars are present are enabled.
390
+ */
391
+ declare function fromEnv(env?: Env, opts?: SocialClientOptions): SocialClient;
392
+ //#endregion
393
+ export { WhatsAppClientConfig as A, SocialClientOptions as C, UnifiedMedia as D, TwitterClientConfig as E, UnifiedPostInput as O, RedditClientConfig as S, TikTokClientConfig as T, MultiPostResult as _, YouTubeClient as a, ProviderConfigMap as b, LinkedInClient as c, FacebookClientConfig as d, InstagramClientConfig as f, MultiPostInput as g, MessageResult as h, TikTokClient as i, YouTubeClientConfig as j, UnifiedUploadInput as k, FacebookClient as l, MessageInput as m, WhatsAppClient as n, InstagramClient as o, LinkedInClientConfig as p, TelegramClient as r, RedditClient as s, fromEnv as t, TwitterClient as u, MultiUploadInput as v, TelegramClientConfig as w, ProviderName as x, PostResult as y };
394
+ //# sourceMappingURL=env-DxOZHf0p.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-DxOZHf0p.d.mts","names":[],"sources":["../src/client/types.ts","../src/client/twitter.ts","../src/client/facebook.ts","../src/client/linkedin.ts","../src/client/reddit.ts","../src/client/instagram.ts","../src/client/youtube.ts","../src/client/tiktok.ts","../src/client/telegram.ts","../src/client/whatsapp.ts","../src/client/env.ts"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ //#region src/errors.ts
2
+ var SocialError = class extends Error {
3
+ provider;
4
+ statusCode;
5
+ status;
6
+ isOperational;
7
+ errorCode;
8
+ hint;
9
+ retryable;
10
+ retryAfter;
11
+ originalError;
12
+ constructor(provider, message, options = {}) {
13
+ const { statusCode = 502, errorCode, hint, retryable, retryAfter, originalError, ...extra } = options instanceof Error ? { originalError: options } : options;
14
+ super(`[${provider}] ${message}`);
15
+ this.name = "SocialError";
16
+ this.provider = provider;
17
+ this.statusCode = statusCode;
18
+ this.status = `${statusCode}`.startsWith("4") ? "fail" : "error";
19
+ this.isOperational = true;
20
+ this.errorCode = errorCode ?? null;
21
+ this.hint = hint ?? null;
22
+ this.retryable = retryable ?? null;
23
+ this.retryAfter = retryAfter ?? null;
24
+ this.originalError = originalError ?? null;
25
+ if (Object.keys(extra).length) Object.assign(this, extra);
26
+ Error.captureStackTrace(this, this.constructor);
27
+ }
28
+ };
29
+
30
+ //#endregion
31
+ export { SocialError as t };
32
+ //# sourceMappingURL=errors-Cm6LeKf7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-Cm6LeKf7.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Social Provider Error\n * =====================\n * Standalone error class for social media provider failures.\n * Mirrors the behavior of ProviderError but with zero app dependencies.\n *\n * Usage:\n * throw new SocialError('youtube', 'Upload failed', { errorCode: 403, retryable: false });\n * throw new SocialError('telegram', 'Rate limited', { retryable: true, retryAfter: 30 });\n */\n\nexport interface SocialErrorOptions {\n statusCode?: number;\n errorCode?: string | number | null;\n hint?: string | null;\n retryable?: boolean | null;\n retryAfter?: number | null;\n originalError?: Error | null;\n [key: string]: unknown;\n}\n\nexport class SocialError extends Error {\n public readonly provider: string;\n public readonly statusCode: number;\n public readonly status: string;\n public readonly isOperational: boolean;\n public readonly errorCode: string | number | null;\n public readonly hint: string | null;\n public readonly retryable: boolean | null;\n public readonly retryAfter: number | null;\n public readonly originalError: Error | null;\n\n constructor(provider: string, message: string, options: SocialErrorOptions | Error = {}) {\n // Backward compat: if 3rd arg is an Error, treat as originalError\n const opts: SocialErrorOptions = options instanceof Error ? { originalError: options } : options;\n const { statusCode = 502, errorCode, hint, retryable, retryAfter, originalError, ...extra } = opts;\n\n super(`[${provider}] ${message}`);\n this.name = 'SocialError';\n this.provider = provider;\n this.statusCode = statusCode;\n this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';\n this.isOperational = true;\n this.errorCode = errorCode ?? null;\n this.hint = hint ?? null;\n this.retryable = retryable ?? null;\n this.retryAfter = retryAfter ?? null;\n this.originalError = originalError ?? null;\n\n // Platform-specific extras (e.g., errorSubcode, errorType, fbtraceId)\n if (Object.keys(extra).length) Object.assign(this, extra);\n\n Error.captureStackTrace(this, this.constructor);\n }\n}\n"],"mappings":";AAqBA,IAAa,cAAb,cAAiC,MAAM;CACrC,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAEhB,YAAY,UAAkB,SAAiB,UAAsC,EAAE,EAAE;EAGvF,MAAM,EAAE,aAAa,KAAK,WAAW,MAAM,WAAW,YAAY,eAAe,GAAG,UADnD,mBAAmB,QAAQ,EAAE,eAAe,SAAS,GAAG;AAGzF,QAAM,IAAI,SAAS,IAAI,UAAU;AACjC,OAAK,OAAO;AACZ,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,OAAK,SAAS,GAAG,aAAa,WAAW,IAAI,GAAG,SAAS;AACzD,OAAK,gBAAgB;AACrB,OAAK,YAAY,aAAa;AAC9B,OAAK,OAAO,QAAQ;AACpB,OAAK,YAAY,aAAa;AAC9B,OAAK,aAAa,cAAc;AAChC,OAAK,gBAAgB,iBAAiB;AAGtC,MAAI,OAAO,KAAK,MAAM,CAAC,OAAQ,QAAO,OAAO,MAAM,MAAM;AAEzD,QAAM,kBAAkB,MAAM,KAAK,YAAY"}