@postrun/react 2.4.0 → 2.6.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.
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, CSSProperties } from 'react';
3
3
  import * as _tanstack_react_query from '@tanstack/react-query';
4
4
  import { QueryClient, QueryKey } from '@tanstack/react-query';
5
- import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, Metadata, ComposePostInput, PostValidation, MediaKind, XPostVariant, LinkedInPostVariant, TikTokPostVariant, TikTokCreatorInfo, TikTokOptionsValue } from '@postrun/js';
5
+ import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, Metadata, ComposePostInput, PostValidation, MediaKind, XPostVariant, XPoll as XPoll$1, LinkedInPostVariant, TikTokPostVariant, TikTokCreatorInfo, TikTokOptionsValue } from '@postrun/js';
6
6
  export { PostValidation, PostVariant, PostVariantError, TIKTOK_CAPTION_MAX, TikTokCreatorInfo, ValidationIssue, captionMaxFor } from '@postrun/js';
7
7
  import { TwitterComponents } from 'react-tweet';
8
8
 
@@ -1675,6 +1675,16 @@ interface PreviewMedia {
1675
1675
  }
1676
1676
  /** @deprecated Use {@link PreviewMedia}. Kept as an alias for back-compat. */
1677
1677
  type XPreviewMedia = PreviewMedia;
1678
+ /** A media item with its pixels already resolved to a single URL by the
1679
+ * component (shared by every platform preview's renderer). */
1680
+ interface ResolvedMedia {
1681
+ kind: PreviewMediaKind;
1682
+ src: string;
1683
+ width?: number;
1684
+ height?: number;
1685
+ alt?: string;
1686
+ posterSrc?: string;
1687
+ }
1678
1688
  /**
1679
1689
  * Content for the nested quoted card. Supplied separately because our schema
1680
1690
  * carries only an opaque `quote_tweet_id` (no quoted text/author).
@@ -1720,6 +1730,17 @@ declare function XPostPreviewImpl({ variant, author, media, quotedTweet, replyTo
1720
1730
  * already absorbs unstable media arrays). */
1721
1731
  declare const XPostPreview: react.MemoExoticComponent<typeof XPostPreviewImpl>;
1722
1732
 
1733
+ /**
1734
+ * An X poll (`settings.poll`) rendered in the post preview — the 2–4 options as
1735
+ * X's pre-vote outlined buttons, then an honest "0 votes · <time left>" footer
1736
+ * (a draft poll has no votes; never fabricate counts). Colors inherit
1737
+ * react-tweet's CSS variables, so it matches the card in light and dark.
1738
+ */
1739
+ interface XPollProps {
1740
+ poll: XPoll$1;
1741
+ }
1742
+ declare function XPoll({ poll }: XPollProps): react.JSX.Element;
1743
+
1723
1744
  /**
1724
1745
  * LinkedIn preview theming. Unlike the X preview (which inherits react-tweet's
1725
1746
  * CSS), we own the LinkedIn card, so we expose a small set of CSS custom
@@ -1736,8 +1757,9 @@ type LinkedInTheme = 'light' | 'dark' | 'auto';
1736
1757
  * with headline + audience icon, an entity-highlighted body with the "…more"
1737
1758
  * fold, the 1/2/3/4/+N image mosaic (or a video), and a static action bar.
1738
1759
  *
1739
- * v1 renders text + images + video. The richer `content_kind`s (article, poll,
1740
- * document) degrade gracefully to the text/media card and arrive next.
1760
+ * Renders every `content_kind`: text, single/multi image, video, plus the rich
1761
+ * units — article share card, poll, and document — each driven from
1762
+ * `settings.{article,poll,document}` (see `renderContent`).
1741
1763
  *
1742
1764
  * Customize via `theme` (light/dark/auto), `className`/`style`, or by overriding
1743
1765
  * the `--pr-li-*` CSS variables the card reads.
@@ -1765,6 +1787,51 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
1765
1787
  * absorbs unstable media arrays). */
1766
1788
  declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
1767
1789
 
1790
+ /**
1791
+ * A LinkedIn article share card (`content_kind: 'article'`) — the link unit
1792
+ * LinkedIn renders below the commentary: an optional thumbnail, then a panel with
1793
+ * the source domain (muted), the headline (bold), and the optional description.
1794
+ * Driven straight from `settings.article`; the thumbnail pixels (resolved from
1795
+ * `article.thumbnail_media_id`) are passed in by the host.
1796
+ */
1797
+ /** The article settings shape — derived from the contract, never re-declared. */
1798
+ type LinkedInArticle = NonNullable<NonNullable<LinkedInPostVariant['settings']>['article']>;
1799
+ interface ArticleCardProps {
1800
+ article: LinkedInArticle;
1801
+ /** Resolved thumbnail pixels (from `article.thumbnail_media_id`), if any. */
1802
+ thumbnail?: ResolvedMedia;
1803
+ }
1804
+ declare function ArticleCard({ article, thumbnail }: ArticleCardProps): react.JSX.Element;
1805
+
1806
+ /**
1807
+ * A LinkedIn poll (`content_kind: 'poll'`) — the question, the 2–4 option rows
1808
+ * (rendered as the pre-vote outlined buttons LinkedIn shows), and the footer
1809
+ * ("0 votes • <duration>"). A fresh poll has no votes, so we never fabricate
1810
+ * counts. Driven straight from `settings.poll`.
1811
+ */
1812
+ /** The poll settings shape — derived from the contract, never re-declared. */
1813
+ type LinkedInPoll = NonNullable<NonNullable<LinkedInPostVariant['settings']>['poll']>;
1814
+ interface PollProps {
1815
+ poll: LinkedInPoll;
1816
+ }
1817
+ declare function Poll({ poll }: PollProps): react.JSX.Element;
1818
+
1819
+ /**
1820
+ * A LinkedIn document post (`content_kind: 'document'`) — the PDF/slide unit
1821
+ * LinkedIn renders as a page preview with a dark caption bar (title + "Document").
1822
+ * The document asset rides on the variant `media[]`; if the host resolves a
1823
+ * first-page image it shows here, otherwise a clean document affordance. Title is
1824
+ * required by the contract, so it always renders. Driven by `settings.document`.
1825
+ */
1826
+ /** The document settings shape — derived from the contract, never re-declared. */
1827
+ type LinkedInDocument = NonNullable<NonNullable<LinkedInPostVariant['settings']>['document']>;
1828
+ interface DocumentCardProps {
1829
+ document: LinkedInDocument;
1830
+ /** Resolved first-page pixels (from the document asset on media[]), if any. */
1831
+ cover?: ResolvedMedia;
1832
+ }
1833
+ declare function DocumentCard({ document, cover }: DocumentCardProps): react.JSX.Element;
1834
+
1768
1835
  /**
1769
1836
  * Public props for the TikTok post preview — a faithful render of how a post will
1770
1837
  * look on TikTok, driven straight from our Post object plus the live creator info
@@ -1897,4 +1964,4 @@ declare function Declaration({ brandedContent }: {
1897
1964
  brandedContent: boolean;
1898
1965
  }): react.JSX.Element;
1899
1966
 
1900
- export { AudienceSelect, type CalendarFilters, CommercialDisclosure, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, Declaration, type DiscoverableAccount, type InfiniteList, InteractionToggles, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, TikTokCaptionField, type TikTokCaptionFieldProps, TikTokPostPreview, type TikTokPostPreviewProps, TikTokPublishPanel, type TikTokPublishPanelProps, type TikTokTheme, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
1967
+ export { ArticleCard, type ArticleCardProps, AudienceSelect, type CalendarFilters, CommercialDisclosure, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, Declaration, type DiscoverableAccount, DocumentCard, type DocumentCardProps, type InfiniteList, InteractionToggles, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, Poll, type PollProps, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, TikTokCaptionField, type TikTokCaptionFieldProps, TikTokPostPreview, type TikTokPostPreviewProps, TikTokPublishPanel, type TikTokPublishPanelProps, type TikTokTheme, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPoll, type XPollProps, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, CSSProperties } from 'react';
3
3
  import * as _tanstack_react_query from '@tanstack/react-query';
4
4
  import { QueryClient, QueryKey } from '@tanstack/react-query';
5
- import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, Metadata, ComposePostInput, PostValidation, MediaKind, XPostVariant, LinkedInPostVariant, TikTokPostVariant, TikTokCreatorInfo, TikTokOptionsValue } from '@postrun/js';
5
+ import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, Metadata, ComposePostInput, PostValidation, MediaKind, XPostVariant, XPoll as XPoll$1, LinkedInPostVariant, TikTokPostVariant, TikTokCreatorInfo, TikTokOptionsValue } from '@postrun/js';
6
6
  export { PostValidation, PostVariant, PostVariantError, TIKTOK_CAPTION_MAX, TikTokCreatorInfo, ValidationIssue, captionMaxFor } from '@postrun/js';
7
7
  import { TwitterComponents } from 'react-tweet';
8
8
 
@@ -1675,6 +1675,16 @@ interface PreviewMedia {
1675
1675
  }
1676
1676
  /** @deprecated Use {@link PreviewMedia}. Kept as an alias for back-compat. */
1677
1677
  type XPreviewMedia = PreviewMedia;
1678
+ /** A media item with its pixels already resolved to a single URL by the
1679
+ * component (shared by every platform preview's renderer). */
1680
+ interface ResolvedMedia {
1681
+ kind: PreviewMediaKind;
1682
+ src: string;
1683
+ width?: number;
1684
+ height?: number;
1685
+ alt?: string;
1686
+ posterSrc?: string;
1687
+ }
1678
1688
  /**
1679
1689
  * Content for the nested quoted card. Supplied separately because our schema
1680
1690
  * carries only an opaque `quote_tweet_id` (no quoted text/author).
@@ -1720,6 +1730,17 @@ declare function XPostPreviewImpl({ variant, author, media, quotedTweet, replyTo
1720
1730
  * already absorbs unstable media arrays). */
1721
1731
  declare const XPostPreview: react.MemoExoticComponent<typeof XPostPreviewImpl>;
1722
1732
 
1733
+ /**
1734
+ * An X poll (`settings.poll`) rendered in the post preview — the 2–4 options as
1735
+ * X's pre-vote outlined buttons, then an honest "0 votes · <time left>" footer
1736
+ * (a draft poll has no votes; never fabricate counts). Colors inherit
1737
+ * react-tweet's CSS variables, so it matches the card in light and dark.
1738
+ */
1739
+ interface XPollProps {
1740
+ poll: XPoll$1;
1741
+ }
1742
+ declare function XPoll({ poll }: XPollProps): react.JSX.Element;
1743
+
1723
1744
  /**
1724
1745
  * LinkedIn preview theming. Unlike the X preview (which inherits react-tweet's
1725
1746
  * CSS), we own the LinkedIn card, so we expose a small set of CSS custom
@@ -1736,8 +1757,9 @@ type LinkedInTheme = 'light' | 'dark' | 'auto';
1736
1757
  * with headline + audience icon, an entity-highlighted body with the "…more"
1737
1758
  * fold, the 1/2/3/4/+N image mosaic (or a video), and a static action bar.
1738
1759
  *
1739
- * v1 renders text + images + video. The richer `content_kind`s (article, poll,
1740
- * document) degrade gracefully to the text/media card and arrive next.
1760
+ * Renders every `content_kind`: text, single/multi image, video, plus the rich
1761
+ * units — article share card, poll, and document — each driven from
1762
+ * `settings.{article,poll,document}` (see `renderContent`).
1741
1763
  *
1742
1764
  * Customize via `theme` (light/dark/auto), `className`/`style`, or by overriding
1743
1765
  * the `--pr-li-*` CSS variables the card reads.
@@ -1765,6 +1787,51 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
1765
1787
  * absorbs unstable media arrays). */
1766
1788
  declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
1767
1789
 
1790
+ /**
1791
+ * A LinkedIn article share card (`content_kind: 'article'`) — the link unit
1792
+ * LinkedIn renders below the commentary: an optional thumbnail, then a panel with
1793
+ * the source domain (muted), the headline (bold), and the optional description.
1794
+ * Driven straight from `settings.article`; the thumbnail pixels (resolved from
1795
+ * `article.thumbnail_media_id`) are passed in by the host.
1796
+ */
1797
+ /** The article settings shape — derived from the contract, never re-declared. */
1798
+ type LinkedInArticle = NonNullable<NonNullable<LinkedInPostVariant['settings']>['article']>;
1799
+ interface ArticleCardProps {
1800
+ article: LinkedInArticle;
1801
+ /** Resolved thumbnail pixels (from `article.thumbnail_media_id`), if any. */
1802
+ thumbnail?: ResolvedMedia;
1803
+ }
1804
+ declare function ArticleCard({ article, thumbnail }: ArticleCardProps): react.JSX.Element;
1805
+
1806
+ /**
1807
+ * A LinkedIn poll (`content_kind: 'poll'`) — the question, the 2–4 option rows
1808
+ * (rendered as the pre-vote outlined buttons LinkedIn shows), and the footer
1809
+ * ("0 votes • <duration>"). A fresh poll has no votes, so we never fabricate
1810
+ * counts. Driven straight from `settings.poll`.
1811
+ */
1812
+ /** The poll settings shape — derived from the contract, never re-declared. */
1813
+ type LinkedInPoll = NonNullable<NonNullable<LinkedInPostVariant['settings']>['poll']>;
1814
+ interface PollProps {
1815
+ poll: LinkedInPoll;
1816
+ }
1817
+ declare function Poll({ poll }: PollProps): react.JSX.Element;
1818
+
1819
+ /**
1820
+ * A LinkedIn document post (`content_kind: 'document'`) — the PDF/slide unit
1821
+ * LinkedIn renders as a page preview with a dark caption bar (title + "Document").
1822
+ * The document asset rides on the variant `media[]`; if the host resolves a
1823
+ * first-page image it shows here, otherwise a clean document affordance. Title is
1824
+ * required by the contract, so it always renders. Driven by `settings.document`.
1825
+ */
1826
+ /** The document settings shape — derived from the contract, never re-declared. */
1827
+ type LinkedInDocument = NonNullable<NonNullable<LinkedInPostVariant['settings']>['document']>;
1828
+ interface DocumentCardProps {
1829
+ document: LinkedInDocument;
1830
+ /** Resolved first-page pixels (from the document asset on media[]), if any. */
1831
+ cover?: ResolvedMedia;
1832
+ }
1833
+ declare function DocumentCard({ document, cover }: DocumentCardProps): react.JSX.Element;
1834
+
1768
1835
  /**
1769
1836
  * Public props for the TikTok post preview — a faithful render of how a post will
1770
1837
  * look on TikTok, driven straight from our Post object plus the live creator info
@@ -1897,4 +1964,4 @@ declare function Declaration({ brandedContent }: {
1897
1964
  brandedContent: boolean;
1898
1965
  }): react.JSX.Element;
1899
1966
 
1900
- export { AudienceSelect, type CalendarFilters, CommercialDisclosure, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, Declaration, type DiscoverableAccount, type InfiniteList, InteractionToggles, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, TikTokCaptionField, type TikTokCaptionFieldProps, TikTokPostPreview, type TikTokPostPreviewProps, TikTokPublishPanel, type TikTokPublishPanelProps, type TikTokTheme, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
1967
+ export { ArticleCard, type ArticleCardProps, AudienceSelect, type CalendarFilters, CommercialDisclosure, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, Declaration, type DiscoverableAccount, DocumentCard, type DocumentCardProps, type InfiniteList, InteractionToggles, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, Poll, type PollProps, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, TikTokCaptionField, type TikTokCaptionFieldProps, TikTokPostPreview, type TikTokPostPreviewProps, TikTokPublishPanel, type TikTokPublishPanelProps, type TikTokTheme, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPoll, type XPollProps, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { createContext, memo, useMemo, useState, useEffect, useRef, useLayoutEffect, Fragment as Fragment$1, useCallback, createElement, useContext, useId } from 'react';
3
3
  import { useInfiniteQuery, useQuery, useMutation, QueryClient } from '@tanstack/react-query';
4
- import { createPostrunClient, profilesList, profilesGet, profilesCreate, profilesUpdate, profilesDelete, connectionsConnect, connectionsListByProfile, connectionsGet, connectionsListAccounts, connectionsSelect, connectionsDelete, mediaGet, mediaList, mediaUpdate, mediaDelete, postsList, postsGet, postsCreate, buildCreatePost, isPostPlatform, failedVariants, isPublished, postsValidate, postsUpdate, postsDelete, tiktokCreatorInfo, audiencePrivacyOptions, audienceUnselected, tiktokPrivacyLabel, parsePrivacyLevel, TIKTOK_AUDIENCE_REQUIRED_HINT, captionMaxFor, commercialLabelNotice, commercialDisclosureIncomplete, setCommercialDisclosure, setBrandKind, TIKTOK_DISCLOSURE_REQUIRED_HINT, TIKTOK_BRANDED_CONTENT_POLICY_URL, TIKTOK_MUSIC_CONFIRMATION_URL, interactionRows, interactionValueKey, toggleInteraction, tiktokOptionsReady, TIKTOK_PROCESSING_NOTICE, brandedContentDeclared, mediaCreate, PostrunError } from '@postrun/js';
4
+ import { xPollDurationLabel, linkedinPollDurationLabel, createPostrunClient, profilesList, profilesGet, profilesCreate, profilesUpdate, profilesDelete, connectionsConnect, connectionsListByProfile, connectionsGet, connectionsListAccounts, connectionsSelect, connectionsDelete, mediaGet, mediaList, mediaUpdate, mediaDelete, postsList, postsGet, postsCreate, buildCreatePost, isPostPlatform, failedVariants, isPublished, postsValidate, postsUpdate, postsDelete, tiktokCreatorInfo, audiencePrivacyOptions, audienceUnselected, tiktokPrivacyLabel, parsePrivacyLevel, TIKTOK_AUDIENCE_REQUIRED_HINT, captionMaxFor, commercialLabelNotice, commercialDisclosureIncomplete, setCommercialDisclosure, setBrandKind, TIKTOK_DISCLOSURE_REQUIRED_HINT, TIKTOK_BRANDED_CONTENT_POLICY_URL, TIKTOK_MUSIC_CONFIRMATION_URL, interactionRows, interactionValueKey, toggleInteraction, tiktokOptionsReady, TIKTOK_PROCESSING_NOTICE, brandedContentDeclared, mediaCreate, PostrunError } from '@postrun/js';
5
5
  export { TIKTOK_CAPTION_MAX, captionMaxFor } from '@postrun/js';
6
6
  import Nango, { AuthError } from '@nangohq/frontend';
7
7
  import pWaitFor, { TimeoutError } from 'p-wait-for';
@@ -9,8 +9,8 @@ import pLimit from 'p-limit';
9
9
  import pRetry, { AbortError } from 'p-retry';
10
10
  import axios, { isAxiosError } from 'axios';
11
11
  import { enrichTweet, TweetContainer, TweetHeader, TweetInReplyTo, TweetBody, TweetMedia, QuotedTweet } from 'react-tweet';
12
- import { FiMessageCircle, FiRepeat, FiHeart, FiBarChart2, FiShare, FiGlobe, FiUsers, FiThumbsUp, FiMessageSquare, FiSend } from 'react-icons/fi';
13
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
13
+ import { FiMessageCircle, FiRepeat, FiHeart, FiBarChart2, FiShare, FiGlobe, FiUsers, FiThumbsUp, FiMessageSquare, FiSend, FiFileText } from 'react-icons/fi';
14
14
  import twitterText from 'twitter-text';
15
15
  import { LuBadgeCheck } from 'react-icons/lu';
16
16
  import useEmblaCarousel from 'embla-carousel-react';
@@ -1029,6 +1029,37 @@ function useResolvedMedia(media, altFallbacks, altSignature) {
1029
1029
  [signature, altSignature, objectUrls]
1030
1030
  );
1031
1031
  }
1032
+ function XPoll({ poll }) {
1033
+ return /* @__PURE__ */ jsxs("div", { style: wrapStyle, children: [
1034
+ poll.options.map((option, i) => /* @__PURE__ */ jsx("div", { style: optionStyle, children: option }, `${option}-${i}`)),
1035
+ /* @__PURE__ */ jsxs("div", { style: footerStyle, children: [
1036
+ "0 votes \xB7 ",
1037
+ xPollDurationLabel(poll.duration_minutes)
1038
+ ] })
1039
+ ] });
1040
+ }
1041
+ var BLUE = "var(--tweet-color-blue-primary, #1d9bf0)";
1042
+ var MUTED = "var(--tweet-color-gray-secondary, #536471)";
1043
+ var wrapStyle = {
1044
+ display: "flex",
1045
+ flexDirection: "column",
1046
+ gap: 8,
1047
+ marginTop: 12
1048
+ };
1049
+ var optionStyle = {
1050
+ border: `1px solid ${BLUE}`,
1051
+ color: BLUE,
1052
+ borderRadius: 999,
1053
+ padding: "8px 16px",
1054
+ textAlign: "center",
1055
+ fontSize: 15,
1056
+ fontWeight: 700
1057
+ };
1058
+ var footerStyle = {
1059
+ fontSize: 13,
1060
+ color: MUTED,
1061
+ marginTop: 2
1062
+ };
1032
1063
  var ROW = {
1033
1064
  display: "flex",
1034
1065
  justifyContent: "space-between",
@@ -1269,6 +1300,7 @@ function XPostPreviewImpl({
1269
1300
  tweet.in_reply_to_screen_name ? /* @__PURE__ */ jsx(TweetInReplyTo, { tweet }) : null,
1270
1301
  /* @__PURE__ */ jsx(TweetBody, { tweet }),
1271
1302
  tweet.mediaDetails?.length ? /* @__PURE__ */ jsx(TweetMedia, { tweet, components }) : null,
1303
+ variant.settings?.poll ? /* @__PURE__ */ jsx(XPoll, { poll: variant.settings.poll }) : null,
1272
1304
  tweet.quoted_tweet ? /* @__PURE__ */ jsx(QuotedTweet, { tweet: tweet.quoted_tweet }) : null,
1273
1305
  showActions ? /* @__PURE__ */ jsx(XPreviewActions, {}) : null
1274
1306
  ] })
@@ -1331,6 +1363,111 @@ function useIsDark(theme) {
1331
1363
  }
1332
1364
  return theme === "dark";
1333
1365
  }
1366
+ function domainOf(source) {
1367
+ try {
1368
+ return new URL(source).hostname.replace(/^www\./, "");
1369
+ } catch {
1370
+ return source;
1371
+ }
1372
+ }
1373
+ function ArticleCard({ article, thumbnail }) {
1374
+ return /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
1375
+ thumbnail ? /* @__PURE__ */ jsx("img", { src: thumbnail.src, alt: thumbnail.alt ?? "", style: thumbStyle }) : null,
1376
+ /* @__PURE__ */ jsxs("div", { style: metaStyle, children: [
1377
+ /* @__PURE__ */ jsx("div", { style: domainStyle, children: domainOf(article.source) }),
1378
+ article.title ? /* @__PURE__ */ jsx("div", { style: titleStyle, children: article.title }) : null,
1379
+ article.description ? /* @__PURE__ */ jsx("div", { style: descStyle, children: article.description }) : null
1380
+ ] })
1381
+ ] });
1382
+ }
1383
+ var cardStyle = {
1384
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1385
+ borderRadius: 8,
1386
+ overflow: "hidden"
1387
+ };
1388
+ var thumbStyle = {
1389
+ width: "100%",
1390
+ display: "block",
1391
+ aspectRatio: "1.91 / 1",
1392
+ objectFit: "cover"
1393
+ };
1394
+ var metaStyle = {
1395
+ padding: "8px 12px",
1396
+ display: "flex",
1397
+ flexDirection: "column",
1398
+ gap: 2
1399
+ };
1400
+ var domainStyle = {
1401
+ fontSize: 12,
1402
+ color: varRef(LI_VAR.muted)
1403
+ };
1404
+ var titleStyle = {
1405
+ fontSize: 14,
1406
+ fontWeight: 600,
1407
+ color: varRef(LI_VAR.text),
1408
+ lineHeight: 1.3,
1409
+ display: "-webkit-box",
1410
+ WebkitLineClamp: 2,
1411
+ WebkitBoxOrient: "vertical",
1412
+ overflow: "hidden"
1413
+ };
1414
+ var descStyle = {
1415
+ fontSize: 12,
1416
+ color: varRef(LI_VAR.muted),
1417
+ lineHeight: 1.3,
1418
+ display: "-webkit-box",
1419
+ WebkitLineClamp: 1,
1420
+ WebkitBoxOrient: "vertical",
1421
+ overflow: "hidden"
1422
+ };
1423
+ function DocumentCard({ document, cover }) {
1424
+ return /* @__PURE__ */ jsxs("div", { style: cardStyle2, children: [
1425
+ /* @__PURE__ */ jsx("div", { style: pageStyle, children: cover ? /* @__PURE__ */ jsx("img", { src: cover.src, alt: cover.alt ?? "", style: coverStyle }) : /* @__PURE__ */ jsx(FiFileText, { size: 56, "aria-hidden": true, style: { opacity: 0.5 } }) }),
1426
+ /* @__PURE__ */ jsxs("div", { style: barStyle, children: [
1427
+ /* @__PURE__ */ jsx("div", { style: titleStyle2, children: document.title }),
1428
+ /* @__PURE__ */ jsx("div", { style: kindStyle, children: "Document" })
1429
+ ] })
1430
+ ] });
1431
+ }
1432
+ var cardStyle2 = {
1433
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1434
+ borderRadius: 8,
1435
+ overflow: "hidden"
1436
+ };
1437
+ var pageStyle = {
1438
+ position: "relative",
1439
+ aspectRatio: "4 / 3",
1440
+ background: "rgba(127,127,127,0.12)",
1441
+ display: "grid",
1442
+ placeItems: "center",
1443
+ color: varRef(LI_VAR.muted)
1444
+ };
1445
+ var coverStyle = {
1446
+ width: "100%",
1447
+ height: "100%",
1448
+ objectFit: "cover"
1449
+ };
1450
+ var barStyle = {
1451
+ background: "rgba(0,0,0,0.85)",
1452
+ color: "#fff",
1453
+ padding: "10px 14px",
1454
+ display: "flex",
1455
+ flexDirection: "column",
1456
+ gap: 1
1457
+ };
1458
+ var titleStyle2 = {
1459
+ fontSize: 14,
1460
+ fontWeight: 600,
1461
+ lineHeight: 1.3,
1462
+ display: "-webkit-box",
1463
+ WebkitLineClamp: 2,
1464
+ WebkitBoxOrient: "vertical",
1465
+ overflow: "hidden"
1466
+ };
1467
+ var kindStyle = {
1468
+ fontSize: 12,
1469
+ color: "rgba(255,255,255,0.7)"
1470
+ };
1334
1471
  var ROW2 = {
1335
1472
  display: "flex",
1336
1473
  justifyContent: "space-around",
@@ -1484,11 +1621,11 @@ function Tile({
1484
1621
  ] });
1485
1622
  }
1486
1623
  function ImageMosaic({ media }) {
1487
- if (media.length === 0) {
1624
+ const [only] = media;
1625
+ if (!only) {
1488
1626
  return null;
1489
1627
  }
1490
1628
  if (media.length === 1) {
1491
- const only = media[0];
1492
1629
  return /* @__PURE__ */ jsx(
1493
1630
  "img",
1494
1631
  {
@@ -1534,6 +1671,48 @@ function Media({ media }) {
1534
1671
  const images = media.filter((item) => item.kind === "image");
1535
1672
  return /* @__PURE__ */ jsx(ImageMosaic, { media: images });
1536
1673
  }
1674
+ function Poll({ poll }) {
1675
+ return /* @__PURE__ */ jsxs("div", { style: wrapStyle2, children: [
1676
+ /* @__PURE__ */ jsx("div", { style: questionStyle, children: poll.question }),
1677
+ /* @__PURE__ */ jsx("div", { style: optionsStyle, children: poll.options.map((option, i) => /* @__PURE__ */ jsx("div", { style: optionStyle2, children: option }, `${option}-${i}`)) }),
1678
+ /* @__PURE__ */ jsxs("div", { style: footerStyle2, children: [
1679
+ "0 votes \u2022 ",
1680
+ linkedinPollDurationLabel(poll.duration)
1681
+ ] })
1682
+ ] });
1683
+ }
1684
+ var wrapStyle2 = {
1685
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1686
+ borderRadius: 8,
1687
+ padding: 12,
1688
+ display: "flex",
1689
+ flexDirection: "column",
1690
+ gap: 10
1691
+ };
1692
+ var questionStyle = {
1693
+ fontSize: 14,
1694
+ fontWeight: 600,
1695
+ color: varRef(LI_VAR.text),
1696
+ lineHeight: 1.35
1697
+ };
1698
+ var optionsStyle = {
1699
+ display: "flex",
1700
+ flexDirection: "column",
1701
+ gap: 8
1702
+ };
1703
+ var optionStyle2 = {
1704
+ border: `1px solid ${varRef(LI_VAR.accent)}`,
1705
+ borderRadius: 999,
1706
+ padding: "8px 16px",
1707
+ textAlign: "center",
1708
+ fontSize: 14,
1709
+ fontWeight: 600,
1710
+ color: varRef(LI_VAR.accent)
1711
+ };
1712
+ var footerStyle2 = {
1713
+ fontSize: 12,
1714
+ color: varRef(LI_VAR.muted)
1715
+ };
1537
1716
  var FOLD_CHARS = 200;
1538
1717
  var BODY_STYLE = {
1539
1718
  whiteSpace: "pre-wrap",
@@ -1661,7 +1840,7 @@ function LinkedInPostPreviewImpl({
1661
1840
  accent: varRef(LI_VAR.accent),
1662
1841
  muted: varRef(LI_VAR.muted)
1663
1842
  };
1664
- const cardStyle2 = {
1843
+ const cardStyle4 = {
1665
1844
  ...paletteVars(dark),
1666
1845
  background: varRef(LI_VAR.bg),
1667
1846
  color: varRef(LI_VAR.text),
@@ -1672,7 +1851,7 @@ function LinkedInPostPreviewImpl({
1672
1851
  fontFamily: FONT_STACK,
1673
1852
  ...style
1674
1853
  };
1675
- return /* @__PURE__ */ jsxs("div", { className, style: cardStyle2, children: [
1854
+ return /* @__PURE__ */ jsxs("div", { className, style: cardStyle4, children: [
1676
1855
  /* @__PURE__ */ jsx(Header, { author, visibility, time }),
1677
1856
  variant.body ? /* @__PURE__ */ jsx("div", { style: { padding: "8px 16px 0" }, children: /* @__PURE__ */ jsx(
1678
1857
  PostBody,
@@ -1682,10 +1861,26 @@ function LinkedInPostPreviewImpl({
1682
1861
  colors: bodyColors
1683
1862
  }
1684
1863
  ) }) : null,
1685
- resolvedMedia.length > 0 ? /* @__PURE__ */ jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsx(Media, { media: resolvedMedia }) }) : null,
1864
+ renderContent(variant, resolvedMedia),
1686
1865
  showActions ? /* @__PURE__ */ jsx(EngagementBar, {}) : null
1687
1866
  ] });
1688
1867
  }
1868
+ function renderContent(variant, media) {
1869
+ const settings = variant.settings;
1870
+ const kind = settings?.content_kind;
1871
+ const [firstMedia] = media;
1872
+ if (kind === "article" && settings?.article) {
1873
+ return /* @__PURE__ */ jsx("div", { style: INSET, children: /* @__PURE__ */ jsx(ArticleCard, { article: settings.article, thumbnail: firstMedia }) });
1874
+ }
1875
+ if (kind === "poll" && settings?.poll) {
1876
+ return /* @__PURE__ */ jsx("div", { style: INSET, children: /* @__PURE__ */ jsx(Poll, { poll: settings.poll }) });
1877
+ }
1878
+ if (kind === "document" && settings?.document) {
1879
+ return /* @__PURE__ */ jsx("div", { style: INSET, children: /* @__PURE__ */ jsx(DocumentCard, { document: settings.document, cover: firstMedia }) });
1880
+ }
1881
+ return media.length > 0 ? /* @__PURE__ */ jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsx(Media, { media }) }) : null;
1882
+ }
1883
+ var INSET = { padding: "12px 16px 0" };
1689
1884
  var LinkedInPostPreview = memo(LinkedInPostPreviewImpl);
1690
1885
  var LINK_COLOR = "#8ab4ff";
1691
1886
  var TOKEN = /([#@][\p{L}\p{N}_.]+)/gu;
@@ -1702,7 +1897,7 @@ function Caption({ body }) {
1702
1897
  setOverflowing(el.scrollHeight > el.clientHeight + 1);
1703
1898
  }, [body, expanded]);
1704
1899
  const parts = body.split(TOKEN);
1705
- return /* @__PURE__ */ jsxs("div", { style: wrapStyle, children: [
1900
+ return /* @__PURE__ */ jsxs("div", { style: wrapStyle3, children: [
1706
1901
  /* @__PURE__ */ jsx("div", { ref, style: expanded ? expandedTextStyle : clampedTextStyle, children: parts.map(
1707
1902
  (part, i) => IS_TOKEN.test(part) ? /* @__PURE__ */ jsx("span", { style: { color: LINK_COLOR }, children: part }, i) : /* @__PURE__ */ jsx("span", { children: part }, i)
1708
1903
  ) }),
@@ -1719,7 +1914,7 @@ function Caption({ body }) {
1719
1914
  ) : null
1720
1915
  ] });
1721
1916
  }
1722
- var wrapStyle = {
1917
+ var wrapStyle3 = {
1723
1918
  fontSize: 14,
1724
1919
  lineHeight: 1.35
1725
1920
  };
@@ -1768,7 +1963,7 @@ function Media2({
1768
1963
  muted: true,
1769
1964
  loop: true,
1770
1965
  playsInline: true,
1771
- style: coverStyle
1966
+ style: coverStyle2
1772
1967
  }
1773
1968
  );
1774
1969
  }
@@ -1795,7 +1990,7 @@ function PhotoCarousel({ media }) {
1795
1990
  };
1796
1991
  }, [emblaApi, sync]);
1797
1992
  return /* @__PURE__ */ jsxs("div", { style: { position: "absolute", inset: 0 }, children: [
1798
- /* @__PURE__ */ jsx("div", { ref: emblaRef, style: viewportStyle, children: /* @__PURE__ */ jsx("div", { style: containerStyle, children: media.map((m, i) => /* @__PURE__ */ jsx("div", { style: slideStyle, children: /* @__PURE__ */ jsx("img", { src: m.src, alt: m.alt ?? "", style: coverStyle }) }, `${m.src}-${i}`)) }) }),
1993
+ /* @__PURE__ */ jsx("div", { ref: emblaRef, style: viewportStyle, children: /* @__PURE__ */ jsx("div", { style: containerStyle, children: media.map((m, i) => /* @__PURE__ */ jsx("div", { style: slideStyle, children: /* @__PURE__ */ jsx("img", { src: m.src, alt: m.alt ?? "", style: coverStyle2 }) }, `${m.src}-${i}`)) }) }),
1799
1994
  media.length > 1 ? /* @__PURE__ */ jsx("div", { style: dotsStyle, children: media.map((m, i) => /* @__PURE__ */ jsx(
1800
1995
  "span",
1801
1996
  {
@@ -1814,7 +2009,7 @@ function ProcessingMedia() {
1814
2009
  /* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children: "Processing media\u2026" })
1815
2010
  ] });
1816
2011
  }
1817
- var coverStyle = {
2012
+ var coverStyle2 = {
1818
2013
  position: "absolute",
1819
2014
  inset: 0,
1820
2015
  width: "100%",
@@ -1940,7 +2135,7 @@ function TikTokPostPreviewImpl({
1940
2135
  const label = commercialLabel(variant.settings);
1941
2136
  const isAigc = Boolean(variant.settings?.is_aigc);
1942
2137
  const pending = (media?.length ?? 0) > 0 && resolvedMedia.length === 0;
1943
- return /* @__PURE__ */ jsxs("div", { className, style: { ...cardStyle, ...style }, children: [
2138
+ return /* @__PURE__ */ jsxs("div", { className, style: { ...cardStyle3, ...style }, children: [
1944
2139
  /* @__PURE__ */ jsx("style", { children: KEYFRAMES }),
1945
2140
  /* @__PURE__ */ jsx(Media2, { media: resolvedMedia, pending }),
1946
2141
  /* @__PURE__ */ jsx("div", { style: scrimStyle }),
@@ -1987,7 +2182,7 @@ function Avatar({ url, name }) {
1987
2182
  function Disc({ url }) {
1988
2183
  return /* @__PURE__ */ jsx("div", { style: discStyle, children: url ? /* @__PURE__ */ jsx("img", { src: url, alt: "", style: discImgStyle }) : null });
1989
2184
  }
1990
- var cardStyle = {
2185
+ var cardStyle3 = {
1991
2186
  position: "relative",
1992
2187
  width: "100%",
1993
2188
  maxWidth: 320,
@@ -2174,7 +2369,7 @@ function useIsDark2(theme) {
2174
2369
  }
2175
2370
  return theme === "dark";
2176
2371
  }
2177
- var MUTED = varRef2(TT_VAR.muted);
2372
+ var MUTED2 = varRef2(TT_VAR.muted);
2178
2373
  var BORDER = varRef2(TT_VAR.border);
2179
2374
  var ACCENT = varRef2(TT_VAR.accent);
2180
2375
  var SWITCH_OFF = varRef2(TT_VAR.switchOff);
@@ -2188,7 +2383,7 @@ function Row({
2188
2383
  return /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
2189
2384
  /* @__PURE__ */ jsxs("label", { htmlFor, style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
2190
2385
  /* @__PURE__ */ jsx("span", { style: { fontSize: 14 }, children: label }),
2191
- sublabel ? /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: MUTED }, children: sublabel }) : null
2386
+ sublabel ? /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: MUTED2 }, children: sublabel }) : null
2192
2387
  ] }),
2193
2388
  control
2194
2389
  ] });
@@ -2296,7 +2491,7 @@ var hintStyle = {
2296
2491
  var noticeStyle = {
2297
2492
  margin: 0,
2298
2493
  fontSize: 12,
2299
- color: MUTED,
2494
+ color: MUTED2,
2300
2495
  lineHeight: 1.4
2301
2496
  };
2302
2497
  var checkRowStyle = {
@@ -2305,7 +2500,7 @@ var checkRowStyle = {
2305
2500
  gap: 10,
2306
2501
  cursor: "pointer"
2307
2502
  };
2308
- var TOKENS = { MUTED, BORDER, ACCENT};
2503
+ var TOKENS = { MUTED: MUTED2, BORDER, ACCENT};
2309
2504
  function AudienceSelect({
2310
2505
  creatorInfo,
2311
2506
  value,
@@ -2362,7 +2557,7 @@ function TikTokCaptionField({
2362
2557
  const max = captionMaxFor(postType);
2363
2558
  const count = value.length;
2364
2559
  const over = count > max;
2365
- return /* @__PURE__ */ jsxs("div", { className, style: { ...wrapStyle2, ...style }, children: [
2560
+ return /* @__PURE__ */ jsxs("div", { className, style: { ...wrapStyle4, ...style }, children: [
2366
2561
  /* @__PURE__ */ jsxs("div", { style: labelRowStyle, children: [
2367
2562
  /* @__PURE__ */ jsx("label", { htmlFor: id, style: labelStyle, children: "Caption" }),
2368
2563
  /* @__PURE__ */ jsxs(
@@ -2396,7 +2591,7 @@ function TikTokCaptionField({
2396
2591
  )
2397
2592
  ] });
2398
2593
  }
2399
- var wrapStyle2 = {
2594
+ var wrapStyle4 = {
2400
2595
  display: "flex",
2401
2596
  flexDirection: "column",
2402
2597
  gap: 6,
@@ -2655,6 +2850,6 @@ var postButtonStyle = {
2655
2850
  transition: "opacity 160ms ease"
2656
2851
  };
2657
2852
 
2658
- export { AudienceSelect, CommercialDisclosure, Connect, Declaration, InteractionToggles, LinkedInPostPreview, PostrunProvider, TikTokCaptionField, TikTokPostPreview, TikTokPublishPanel, UploadError, XPostPreview, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
2853
+ export { ArticleCard, AudienceSelect, CommercialDisclosure, Connect, Declaration, DocumentCard, InteractionToggles, LinkedInPostPreview, Poll, PostrunProvider, TikTokCaptionField, TikTokPostPreview, TikTokPublishPanel, UploadError, XPoll, XPostPreview, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
2659
2854
  //# sourceMappingURL=index.js.map
2660
2855
  //# sourceMappingURL=index.js.map