@postrun/react 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context.tsx","../src/infinite-list.ts","../src/keys.ts","../src/profiles.ts","../src/navigate.ts","../src/connections.ts","../src/upload-bytes.ts","../src/media.ts","../src/posts.ts","../src/preview/use-resolved-media.ts","../src/preview/x/XPreviewActions.tsx","../src/preview/x/entities.ts","../src/preview/x/to-tweet.ts","../src/preview/x/XPostPreview.tsx","../src/preview/linkedin/theme.ts","../src/preview/linkedin/EngagementBar.tsx","../src/preview/linkedin/Header.tsx","../src/preview/linkedin/ImageMosaic.tsx","../src/preview/linkedin/Media.tsx","../src/preview/linkedin/PostBody.tsx","../src/preview/linkedin/LinkedInPostPreview.tsx"],"names":["QueryClient","createContext","useRef","useEffect","useMemo","createPostrunClient","createElement","useContext","useInfiniteQuery","useQuery","profilesList","profilesGet","useMutation","profilesCreate","profilesUpdate","profilesDelete","connectionsConnect","connectionsListByProfile","connectionsGet","connectionsListAccounts","connectionsSelect","connectionsDelete","axios","isAxiosError","pWaitFor","mediaGet","useState","useCallback","mediaCreate","pRetry","AbortError","mediaUpdate","mediaDelete","postsList","postsGet","postsCreate","buildCreatePost","isPostPlatform","postsUpdate","postsDelete","FiMessageCircle","FiRepeat","FiHeart","FiBarChart2","FiShare","jsx","twitterText","enrichTweet","TweetContainer","TweetHeader","TweetInReplyTo","TweetBody","TweetMedia","QuotedTweet","memo","ROW","ACTIONS","FiThumbsUp","FiMessageSquare","FiSend","jsxs","PLACEHOLDER_AVATAR","LuBadgeCheck","FiGlobe","FiUsers","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { QueryClient } from '@tanstack/react-query';\n\nimport { createPostrunClient } from '@postrun/js';\nimport type { PostrunClient } from '@postrun/js';\n\n/**\n * The value every hook and component reads from context: the typed SDK client\n * plus a private TanStack `QueryClient` that powers caching, dedup, and\n * revalidation. Hooks pass this `queryClient` explicitly to `useQuery` /\n * `useMutation`, so it stays fully isolated from any QueryClient the host app\n * runs of its own — no `QueryClientProvider` setup required from the customer.\n */\nexport interface PostrunContextValue {\n client: PostrunClient;\n queryClient: QueryClient;\n}\n\n/** Sensible defaults: treat data as fresh briefly to avoid refetch storms. */\nfunction createDefaultQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: { staleTime: 30_000 },\n },\n });\n}\n\nconst PostrunContext = createContext<PostrunContextValue | null>(null);\nPostrunContext.displayName = 'PostrunContext';\n\nexport interface PostrunProviderProps {\n /**\n * Returns a valid short-lived scoped token. The host app's backend mints it\n * from a secret `pr_` key (`POST /v1/tokens`); the secret never reaches the\n * browser. Called per request — cache and refresh before `exp` inside here.\n */\n getToken: () => string | Promise<string>;\n /** Override the API base URL (defaults to the production gateway). */\n baseUrl?: string;\n /**\n * Bring your own TanStack `QueryClient` (advanced: shared DevTools, custom\n * defaults, tests). Omit it and a private, isolated one is created for you.\n */\n queryClient?: QueryClient;\n children: ReactNode;\n}\n\nexport function PostrunProvider({\n getToken,\n baseUrl,\n queryClient,\n children,\n}: PostrunProviderProps) {\n // Keep the latest `getToken` in a ref so the client can always call the\n // freshest closure WITHOUT being rebuilt when callers pass a new arrow each\n // render (the common case). The client is constructed once per `baseUrl`.\n const getTokenRef = useRef(getToken);\n useEffect(() => {\n getTokenRef.current = getToken;\n }, [getToken]);\n\n const client = useMemo(\n () =>\n createPostrunClient({ getToken: () => getTokenRef.current(), baseUrl }),\n [baseUrl],\n );\n\n const resolvedQueryClient = useMemo(\n () => queryClient ?? createDefaultQueryClient(),\n [queryClient],\n );\n\n const value = useMemo<PostrunContextValue>(\n () => ({ client, queryClient: resolvedQueryClient }),\n [client, resolvedQueryClient],\n );\n\n return createElement(PostrunContext.Provider, { value }, children);\n}\n\n/** Access the configured Postrun client. Throws if used outside a provider. */\nexport function usePostrun(): PostrunContextValue {\n const value = useContext(PostrunContext);\n\n if (value === null) {\n throw new Error('usePostrun must be used within a <PostrunProvider>.');\n }\n\n return value;\n}\n","import { useInfiniteQuery } from '@tanstack/react-query';\nimport type { QueryKey } from '@tanstack/react-query';\n\nimport { usePostrun } from './context';\n\n/**\n * The offset-pagination envelope every Postrun list endpoint returns. The helper\n * only needs these fields; the concrete page type comes from the SDK response\n * (e.g. `PostList`), which satisfies this structurally — nothing is redeclared.\n */\ninterface PageEnvelope<TItem> {\n data: TItem[];\n total: number;\n offset: number;\n has_more: boolean;\n}\n\n/** A flattened, append-style (\"load more\") view over a paginated list endpoint. */\nexport interface InfiniteList<TItem> {\n /** Every item loaded so far, flattened across all fetched pages. */\n items: TItem[];\n /** Total items matching the filter (from the first page's envelope). */\n total: number;\n /** Fetch the next page and append it. No-op once `hasMore` is false. */\n loadMore: () => void;\n /** Whether another page exists beyond what's loaded. */\n hasMore: boolean;\n /** The first page is loading (no items yet). */\n isLoading: boolean;\n /** A `loadMore()` is in flight (items are already shown). */\n isLoadingMore: boolean;\n /** The last error, or null. Narrow with `instanceof PostrunError`. */\n error: Error | null;\n /** Refetch from the first page (re-runs every loaded page). */\n refetch: () => void;\n}\n\n/**\n * Turn an offset-paginated Postrun list endpoint into a clean append-style\n * `{ items, loadMore, hasMore, … }` surface — the \"Load more\" / infinite-scroll\n * shape a feed or calendar wants.\n *\n * Built on TanStack `useInfiniteQuery`, so page accumulation is its job and never\n * hand-rolled. The next offset is read from the envelope itself\n * (`offset + data.length`), so it stays correct regardless of page size.\n * `fetchPage` supplies the resource-specific SDK call; the page type is inferred\n * from its return, so item types are derived, never redeclared.\n */\nexport function useInfiniteList<TItem>(args: {\n queryKey: QueryKey;\n fetchPage: (page: {\n limit: number;\n offset: number;\n }) => Promise<PageEnvelope<TItem>>;\n /** Items per page (default 20, the API's own default). */\n limit?: number;\n enabled?: boolean;\n}): InfiniteList<TItem> {\n const { queryClient } = usePostrun();\n const limit = args.limit ?? 20;\n\n const query = useInfiniteQuery(\n {\n queryKey: args.queryKey,\n queryFn: ({ pageParam }) => args.fetchPage({ limit, offset: pageParam }),\n initialPageParam: 0,\n getNextPageParam: (last) =>\n last.has_more ? last.offset + last.data.length : undefined,\n enabled: args.enabled,\n },\n queryClient,\n );\n\n return {\n items: query.data?.pages.flatMap((page) => page.data) ?? [],\n total: query.data?.pages[0]?.total ?? 0,\n loadMore: () => {\n void query.fetchNextPage();\n },\n hasMore: query.hasNextPage,\n isLoading: query.isLoading,\n isLoadingMore: query.isFetchingNextPage,\n error: query.error,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n","import type { ListPostsQuery, ListProfilesQuery } from '@postrun/js';\n\n/** Root namespace so our cache never collides with the host app's own queries. */\nconst ROOT = 'postrun';\n\n/**\n * Query-key factory for profiles. Hierarchical so a mutation can invalidate at\n * the right granularity: `lists()` after a create, `detail(id)` after an update.\n */\nexport const profileKeys = {\n all: [ROOT, 'profiles'] as const,\n lists: () => [...profileKeys.all, 'list'] as const,\n list: (query?: ListProfilesQuery) =>\n [...profileKeys.lists(), query ?? {}] as const,\n // Nested under lists() so a create/update/delete invalidating lists() also\n // refreshes the infinite cache; distinct tail so the two cache shapes (a\n // single Page vs accumulated pages) never collide on one key.\n infinite: (query?: ListProfilesQuery) =>\n [...profileKeys.lists(), 'infinite', query ?? {}] as const,\n details: () => [...profileKeys.all, 'detail'] as const,\n detail: (id: string) => [...profileKeys.details(), id] as const,\n};\n\n/** Query-key factory for posts (list filtered by query; detail by id). */\nexport const postKeys = {\n all: [ROOT, 'posts'] as const,\n lists: () => [...postKeys.all, 'list'] as const,\n list: (query?: ListPostsQuery) => [...postKeys.lists(), query ?? {}] as const,\n // Nested under lists() so a create/update/delete invalidating lists() also\n // refreshes the infinite cache; distinct tail so the two cache shapes (a\n // single Page vs accumulated pages) never collide on one key.\n infinite: (query?: ListPostsQuery) =>\n [...postKeys.lists(), 'infinite', query ?? {}] as const,\n details: () => [...postKeys.all, 'detail'] as const,\n detail: (id: string) => [...postKeys.details(), id] as const,\n};\n\n/** Query-key factory for media assets (single-asset only; no list endpoint yet). */\nexport const mediaKeys = {\n all: [ROOT, 'media'] as const,\n details: () => [...mediaKeys.all, 'detail'] as const,\n detail: (id: string) => [...mediaKeys.details(), id] as const,\n};\n\n/** Query-key factory for connections (lists keyed by owning profile). */\nexport const connectionKeys = {\n all: [ROOT, 'connections'] as const,\n lists: () => [...connectionKeys.all, 'list'] as const,\n list: (profileId: string) => [...connectionKeys.lists(), profileId] as const,\n details: () => [...connectionKeys.all, 'detail'] as const,\n detail: (id: string) => [...connectionKeys.details(), id] as const,\n accounts: (id: string) => [...connectionKeys.all, 'accounts', id] as const,\n};\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n profilesCreate,\n profilesDelete,\n profilesGet,\n profilesList,\n profilesUpdate,\n} from '@postrun/js';\nimport type {\n CreateProfileInput,\n ListProfilesQuery,\n Profile,\n UpdateProfileInput,\n} from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { useInfiniteList } from './infinite-list';\nimport { profileKeys } from './keys';\n\n/**\n * List the account's profiles (client/brand workspaces), filtered and paginated.\n * `data` is the typed `ProfileList` envelope — inferred straight from the SDK\n * call, never hand-typed. Caching, dedup, and revalidation come from the\n * provider's private QueryClient.\n */\nexport function useProfiles(query?: ListProfilesQuery) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: profileKeys.list(query),\n queryFn: async () =>\n (await profilesList({ client, query })).data,\n },\n queryClient,\n );\n}\n\n/**\n * List profiles with append-style (\"load more\") pagination. Returns\n * `{ items, loadMore, hasMore, isLoading, isLoadingMore, total }`: render\n * `items`, call `loadMore()` while `hasMore`. `pageSize` defaults to 20. Filters\n * match `useProfiles` minus paging, which the hook owns. Shares list-cache\n * invalidation with the other profile hooks.\n */\nexport function useProfilesInfinite(\n filters?: Omit<ListProfilesQuery, 'limit' | 'offset'>,\n options?: { pageSize?: number },\n) {\n const { client } = usePostrun();\n return useInfiniteList<Profile>({\n queryKey: profileKeys.infinite(filters),\n limit: options?.pageSize,\n fetchPage: async ({ limit, offset }) =>\n (await profilesList({ client, query: { ...filters, limit, offset } }))\n .data,\n });\n}\n\n/** Retrieve a single profile by id. Disabled until an id is provided. */\nexport function useProfile(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: profileKeys.detail(id),\n queryFn: async () =>\n (await profilesGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** Create a profile; on success the profile lists are refetched. */\nexport function useCreateProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (body: CreateProfileInput) =>\n (await profilesCreate({ client, body })).data,\n onSuccess: () =>\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() }),\n },\n queryClient,\n );\n}\n\n/** Update a profile by id; on success the lists and that profile are refreshed. */\nexport function useUpdateProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & UpdateProfileInput) =>\n (await profilesUpdate({ client, path: { id }, body })).data,\n onSuccess: (_result, { id }) => {\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() });\n queryClient.invalidateQueries({ queryKey: profileKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n\n/** Delete a profile by id; on success the lists refresh and its detail is dropped. */\nexport function useDeleteProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await profilesDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() });\n queryClient.removeQueries({ queryKey: profileKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","/**\n * Navigate the browser to a URL. The single impure browser call behind the\n * connect redirect, isolated here so it can be mocked in tests and swapped if a\n * host ever needs custom navigation.\n */\nexport function navigate(url: string): void {\n window.location.assign(url);\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n connectionsConnect,\n connectionsDelete,\n connectionsGet,\n connectionsListAccounts,\n connectionsListByProfile,\n connectionsSelect,\n} from '@postrun/js';\nimport type { ConnectablePlatform, SelectAccountInput } from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { connectionKeys } from './keys';\nimport { navigate } from './navigate';\n\nexport interface ConnectParams {\n /** The profile to attach the new connection to. */\n profileId: string;\n /** The platform to connect (X, LinkedIn, Meta, …). */\n platform: ConnectablePlatform;\n}\n\n/**\n * Start a connect flow: mint a session and redirect the browser to the hosted\n * connect URL on postrun.ai, where the full white-labeled OAuth journey runs and\n * the user is returned to the host app. Bare-bones by design — the OAuth UI is\n * ours and hosted, so the host app just calls `mutate({ profileId, platform })`.\n * On return, the new connection appears via `useConnections`.\n */\nexport function useConnect() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ profileId, platform }: ConnectParams) => {\n const session = (\n await connectionsConnect({\n client,\n path: { id: profileId },\n body: { platform },\n })\n ).data;\n navigate(session.connect_url);\n return session;\n },\n },\n queryClient,\n );\n}\n\n/** List a profile's connected accounts. */\nexport function useConnections(profileId: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.list(profileId),\n queryFn: async () =>\n (await connectionsListByProfile({ client, path: { id: profileId } }))\n .data,\n enabled: Boolean(profileId),\n },\n queryClient,\n );\n}\n\n/** Retrieve a single connection by id. */\nexport function useConnection(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.detail(id),\n queryFn: async () =>\n (await connectionsGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** List the accounts discoverable on a pending connection (for selection). */\nexport function useDiscoverableAccounts(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.accounts(id),\n queryFn: async () =>\n (await connectionsListAccounts({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** Select an account on a pending connection, activating it. */\nexport function useSelectAccount() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & SelectAccountInput) =>\n (await connectionsSelect({ client, path: { id }, body })).data,\n onSuccess: (_result, { id }) => {\n queryClient.invalidateQueries({ queryKey: connectionKeys.lists() });\n queryClient.invalidateQueries({ queryKey: connectionKeys.detail(id) });\n queryClient.invalidateQueries({ queryKey: connectionKeys.accounts(id) });\n },\n },\n queryClient,\n );\n}\n\n/** Disconnect (delete) a connection by id. */\nexport function useDisconnect() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await connectionsDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: connectionKeys.lists() });\n queryClient.removeQueries({ queryKey: connectionKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","import axios, { isAxiosError } from 'axios';\n\nimport type { UploadTarget } from '@postrun/js';\n\n/** A failed direct-to-storage upload, carrying the HTTP status (0 = network). */\nexport class UploadError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'UploadError';\n this.status = status;\n }\n}\n\nexport interface UploadBytesOptions {\n /** Fraction uploaded, 0..1. Called as bytes flow and once with 1 on success. */\n onProgress?: (fraction: number) => void;\n /** Abort the in-flight upload. */\n signal?: AbortSignal;\n}\n\n/**\n * PUT a file's bytes to a signed upload target, with progress and cancellation.\n * axios drives the XHR (the Fetch API can't report upload progress in browsers);\n * retry/poll are composed on top via p-retry/p-wait-for.\n */\nexport async function uploadBytes(\n target: UploadTarget,\n file: Blob,\n options: UploadBytesOptions = {},\n): Promise<void> {\n const { onProgress, signal } = options;\n\n try {\n await axios.request({\n method: target.method,\n url: target.url,\n data: file,\n headers: target.headers,\n signal,\n onUploadProgress: (event) => {\n if (event.total) {\n onProgress?.(event.loaded / event.total);\n }\n },\n });\n onProgress?.(1);\n } catch (error) {\n // A cancellation propagates as-is so callers (and p-retry) treat it as abort.\n if (signal?.aborted) {\n throw error;\n }\n if (isAxiosError(error)) {\n const status = error.response?.status ?? 0;\n throw new UploadError(\n status,\n status ? `Upload failed (HTTP ${status}).` : 'Upload failed: network error.',\n );\n }\n throw error;\n }\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\nimport pRetry, { AbortError } from 'p-retry';\nimport pWaitFor from 'p-wait-for';\nimport { useCallback, useRef, useState } from 'react';\n\nimport {\n mediaCreate,\n mediaDelete,\n mediaGet,\n mediaUpdate,\n} from '@postrun/js';\nimport type {\n CreateMediaInput,\n MediaKind,\n MediaResource,\n MediaTarget,\n PostrunClient,\n UpdateMediaInput,\n} from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { mediaKeys } from './keys';\nimport { UploadError, uploadBytes } from './upload-bytes';\n\nconst DOCUMENT_MIME =\n /^application\\/(pdf|msword|vnd\\.(openxmlformats-officedocument\\.(wordprocessingml\\.document|presentationml\\.presentation)|ms-powerpoint))$/;\n\n/** Map a file's MIME to a media kind so callers pass a File, not metadata. */\nfunction inferKind(contentType: string): MediaKind {\n if (contentType === 'image/gif') return 'gif';\n if (contentType.startsWith('image/')) return 'image';\n if (contentType.startsWith('video/')) return 'video';\n if (DOCUMENT_MIME.test(contentType)) return 'document';\n throw new Error(\n `Could not infer media kind from \"${contentType}\". Pass { kind } explicitly.`,\n );\n}\n\n/** Poll the asset until it settles (ready/failed), respecting cancellation. */\nasync function pollUntilSettled(\n client: PostrunClient,\n id: string,\n signal: AbortSignal,\n): Promise<MediaResource> {\n let latest: MediaResource | undefined;\n await pWaitFor(\n async () => {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n latest = (await mediaGet({ client, path: { id } })).data;\n return latest.status === 'ready' || latest.status === 'failed';\n },\n { interval: 1500, timeout: 300_000 },\n );\n\n if (!latest) {\n throw new Error('Media polling returned no result.');\n }\n return latest;\n}\n\nexport type MediaUploadStatus =\n | 'idle'\n | 'uploading'\n | 'processing'\n | 'ready'\n | 'failed';\n\nexport interface MediaUploadOptions {\n /** Profile that owns the asset. */\n profileId: string;\n /** Platforms to validate + render for (omit to add later via useUpdateMedia). */\n targets?: MediaTarget[];\n /** Override the kind inferred from the file's MIME. */\n kind?: MediaKind;\n /** The file's MIME type. Defaults to `file.type`; required when that's empty. */\n contentType?: string;\n /** Store as-is with zero processing. */\n raw?: boolean;\n altText?: string;\n externalId?: string;\n metadata?: CreateMediaInput['metadata'];\n}\n\n/**\n * Upload a file and get back a platform-validated asset. The hook owns the whole\n * journey: infer kind/content_type from the `File`, create the asset, PUT the\n * bytes with live `progress` + retry, poll until processing settles, and expose\n * `media.per_platform` (per-target status, url, warnings, errors). `cancel()`\n * aborts an in-flight upload.\n */\nexport function useMediaUpload() {\n const { client, queryClient } = usePostrun();\n const [status, setStatus] = useState<MediaUploadStatus>('idle');\n const [progress, setProgress] = useState(0);\n const [media, setMedia] = useState<MediaResource | null>(null);\n const [error, setError] = useState<unknown>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const upload = useCallback(\n async (file: File, options: MediaUploadOptions): Promise<MediaResource> => {\n // Resolve the MIME up front (before touching state) — the API rejects a\n // fabricated `application/octet-stream`, so fail clearly instead.\n const contentType = options.contentType || file.type;\n if (!contentType) {\n throw new Error(\n \"Could not determine the file's content type. Pass { contentType } explicitly.\",\n );\n }\n const kind = options.kind ?? inferKind(contentType);\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('uploading');\n setProgress(0);\n setMedia(null);\n setError(null);\n\n try {\n const created = (\n await mediaCreate({\n client,\n body: {\n profile_id: options.profileId,\n kind,\n content_type: contentType,\n targets: options.targets,\n raw: options.raw,\n alt_text: options.altText,\n external_id: options.externalId,\n metadata: options.metadata,\n },\n })\n ).data;\n\n if (created.upload) {\n const target = created.upload;\n await pRetry(\n async () => {\n try {\n await uploadBytes(target, file, {\n onProgress: setProgress,\n signal: controller.signal,\n });\n } catch (uploadError) {\n // A client error (e.g. an expired signed URL) won't fix on retry.\n if (\n uploadError instanceof UploadError &&\n uploadError.status >= 400 &&\n uploadError.status < 500\n ) {\n throw new AbortError(uploadError);\n }\n throw uploadError;\n }\n },\n { retries: 3, signal: controller.signal },\n );\n }\n\n setStatus('processing');\n const settled = await pollUntilSettled(\n client,\n created.id,\n controller.signal,\n );\n queryClient.setQueryData(mediaKeys.detail(created.id), settled);\n setMedia(settled);\n setStatus(settled.status === 'failed' ? 'failed' : 'ready');\n return settled;\n } catch (caught) {\n setError(caught);\n setStatus('failed');\n throw caught;\n } finally {\n if (abortRef.current === controller) {\n abortRef.current = null;\n }\n }\n },\n [client, queryClient],\n );\n\n const cancel = useCallback(() => abortRef.current?.abort(), []);\n const reset = useCallback(() => {\n setStatus('idle');\n setProgress(0);\n setMedia(null);\n setError(null);\n }, []);\n\n return { upload, cancel, reset, status, progress, media, error };\n}\n\n/** Retrieve a media asset; auto-polls while it is still uploading/processing. */\nexport function useMedia(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: mediaKeys.detail(id),\n queryFn: async () =>\n (await mediaGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n refetchInterval: (query) => {\n const current = query.state.data;\n return current?.status === 'uploading' || current?.status === 'processing'\n ? 2000\n : false;\n },\n },\n queryClient,\n );\n}\n\n/** Update a media asset: alt text / metadata / external_id, or extend targets. */\nexport function useUpdateMedia() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & UpdateMediaInput) =>\n (await mediaUpdate({ client, path: { id }, body })).data,\n onSuccess: (result, { id }) =>\n queryClient.setQueryData(mediaKeys.detail(id), result),\n },\n queryClient,\n );\n}\n\n/** Delete a media asset and its stored renditions. */\nexport function useDeleteMedia() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await mediaDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) =>\n queryClient.removeQueries({ queryKey: mediaKeys.detail(id) }),\n },\n queryClient,\n );\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n buildCreatePost,\n isPostPlatform,\n postsCreate,\n postsDelete,\n postsGet,\n postsList,\n postsUpdate,\n} from '@postrun/js';\nimport type {\n ComposePostInput,\n ListPostsQuery,\n Post,\n UpdatePostInput,\n} from '@postrun/js';\n\n/**\n * The calendar/queue filter surface — a date window over `schedule_at` plus a\n * derived-status multi-select, scoped to an optional profile. Picked straight\n * from the generated `ListPostsQuery` contract (no hand-typed shapes), so it\n * can never drift from the API. Pagination still rides through via `usePosts`.\n */\nexport type CalendarFilters = Pick<\n ListPostsQuery,\n 'profile_id' | 'scheduled_after' | 'scheduled_before' | 'status'\n>;\n\nimport { useConnections } from './connections';\nimport { usePostrun } from './context';\nimport { useInfiniteList } from './infinite-list';\nimport { postKeys } from './keys';\n\n/**\n * A post's status as it appears on the RESPONSE (not the list `status` filter) —\n * the value a live poll actually inspects. Sourced from `Post['status']` so the\n * predicate below is type-correct against `query.state.data?.status`, and a\n * future contract change to the status set surfaces at compile time here.\n */\ntype PostResponseStatus = Post['status'];\n\n/**\n * Statuses that are still moving on their own and warrant polling: `scheduled`\n * (fires at its time with no user action → must be caught transitioning) and\n * `publishing` (mid-flight by definition). Everything else is terminal and stops\n * the poll: `published` / `failed` (end states), `partially_published` (no\n * further automatic movement), and `draft` (only an explicit update — which\n * already invalidates lists — moves it). Modelling in-flight as the small set\n * means any future status defaults to \"terminal/stop\" — the safe, no-runaway\n * default.\n */\nconst IN_FLIGHT: ReadonlySet<PostResponseStatus> = new Set([\n 'scheduled',\n 'publishing',\n]);\n\nconst isLivePostStatus = (status: PostResponseStatus): boolean =>\n IN_FLIGHT.has(status);\n\n/** Per-hook live-poll control: live is on by default; `{ live: false }` opts out. */\nexport interface LiveOptions {\n /** Auto-poll while a post is in-flight (default `true`). Set `false` for one-shot. */\n live?: boolean;\n}\n\n/**\n * List posts — the calendar/queue data, filtered (profile_id / external_id /\n * metadata) and paginated. `data` is the typed `PostList` envelope, with each\n * post's derived status (draft / scheduled / publishing / published / failed).\n */\nexport function usePosts(query?: ListPostsQuery) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.list(query),\n queryFn: async () =>\n (await postsList({ client, query })).data,\n },\n queryClient,\n );\n}\n\n/**\n * List posts with append-style (\"load more\") pagination — the calendar/queue\n * feed. Returns `{ items, loadMore, hasMore, isLoading, isLoadingMore, total }`:\n * render `items`, call `loadMore()` (on a button or scroll end) while `hasMore`.\n * `pageSize` defaults to 20. Filters are the same as `usePosts` minus paging,\n * which the hook owns. Shares list-cache invalidation with the other post hooks,\n * so a create/update/delete refreshes it automatically.\n */\nexport function usePostsInfinite(\n filters?: Omit<ListPostsQuery, 'limit' | 'offset'>,\n options?: { pageSize?: number },\n) {\n const { client } = usePostrun();\n return useInfiniteList<Post>({\n queryKey: postKeys.infinite(filters),\n limit: options?.pageSize,\n fetchPage: async ({ limit, offset }) =>\n (await postsList({ client, query: { ...filters, limit, offset } })).data,\n });\n}\n\n/**\n * Calendar/queue view — list posts in a `schedule_at` date window, optionally\n * narrowed to a profile and to one or more derived statuses (e.g. only\n * `scheduled` + `failed`). Forwards the date-range + multi-status filters (and\n * any `limit`/`offset`) to the generated `postsList` and returns the same typed\n * `PostList` envelope. It shares the `postKeys.list(filters)` cache identity with\n * `usePosts` but owns its own self-terminating poll: while ANY post in the\n * window is in-flight it refetches (5s — a list is heavier than one detail), and\n * stops once every item is terminal (or the window is empty). `live` is a\n * separate option, never mixed into the API filter object; default-on, opt out\n * with `{ live: false }`.\n */\nexport function useCalendar(\n filters?: CalendarFilters & Pick<ListPostsQuery, 'limit' | 'offset'>,\n options?: LiveOptions,\n) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.list(filters),\n queryFn: async () => (await postsList({ client, query: filters })).data,\n refetchInterval: (query) => {\n if (options?.live === false) return false;\n const posts = query.state.data?.data ?? [];\n return posts.some((post) => isLivePostStatus(post.status)) ? 5000 : false;\n },\n },\n queryClient,\n );\n}\n\n/**\n * Retrieve a single post by id (its variants, schedule, and derived status).\n * Auto-polls (2s) while the post is in-flight (`scheduled` / `publishing`) and\n * stops once it reaches a terminal status — so a scheduled post visibly\n * transitions with no manual refetch. `live` is on by default; pass\n * `{ live: false }` to force a one-shot.\n */\nexport function usePost(id: string, options?: LiveOptions) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.detail(id),\n queryFn: async () =>\n (await postsGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n refetchInterval: (query) => {\n if (options?.live === false) return false;\n const status = query.state.data?.status;\n return status && isLivePostStatus(status) ? 2000 : false;\n },\n },\n queryClient,\n );\n}\n\n/**\n * Compose and create a post. Resolves the profile's connections, builds the full\n * variant set from `{ content, channels }` (per the `buildCreatePost` rules), and\n * sends it — the customer never assembles variants or passes a `connection_id`.\n * `connectedChannels` is the set of posting platforms this profile can reach.\n */\nexport function useCreatePost(profileId: string) {\n const { client, queryClient } = usePostrun();\n const connections = useConnections(profileId);\n const connected = connections.data?.data ?? [];\n\n const mutation = useMutation(\n {\n mutationFn: async (input: Omit<ComposePostInput, 'profileId'>) =>\n (\n await postsCreate({\n client,\n body: buildCreatePost({ ...input, profileId }, connected),\n })\n ).data,\n onSuccess: () =>\n queryClient.invalidateQueries({ queryKey: postKeys.lists() }),\n },\n queryClient,\n );\n\n return {\n create: mutation.mutateAsync,\n isPending: mutation.isPending,\n error: mutation.error,\n data: mutation.data,\n reset: mutation.reset,\n // The profile's connections must load before `create` can resolve a channel;\n // gate on this so a call during loading isn't mislabeled \"not connected\".\n isReady: connections.isSuccess,\n connectedChannels: connected\n .map((connection) => connection.platform)\n .filter(isPostPlatform),\n };\n}\n\n/**\n * Update a post by id. Pass a light edit directly (`{ schedule_at }`,\n * `{ tags }`, …) or a rebuilt body from `buildUpdatePost(input, connections)`\n * for content edits (the API's PATCH replaces the variant set).\n */\nexport function useUpdatePost(postId: string) {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (body: UpdatePostInput) =>\n (await postsUpdate({ client, path: { id: postId }, body })).data,\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: postKeys.lists() });\n queryClient.setQueryData(postKeys.detail(postId), result);\n },\n },\n queryClient,\n );\n}\n\n/** Delete a post by id; on success the lists refresh and its detail is dropped. */\nexport function useDeletePost() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await postsDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: postKeys.lists() });\n queryClient.removeQueries({ queryKey: postKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\n\nimport type { PreviewMedia, ResolvedMedia } from './types';\n\n/**\n * Shared media resolution for every platform preview. URL-backed items resolve\n * SYNCHRONOUSLY (the common, processed-asset path — no first-paint flash);\n * compose-time `File` items get an object URL minted in an effect and revoked on\n * change/unmount. Keyed on a content signature, so the resolved array is stable\n * across parent re-renders that don't change the media — the heavy work (object\n * URLs) never churns and downstream mapping stays memoized. Alt text falls back\n * to the variant media's `alt_text_override`.\n */\n\n/** Per-item alt-text fallback source (the variant's media refs). */\nexport type AltFallbacks =\n | readonly { alt_text_override?: string | null }[]\n | undefined;\n\nfunction fileKey(file: File | undefined): string {\n return file ? `${file.name}:${file.size}:${file.lastModified}` : '';\n}\n\n/** A content signature so object-URL work only re-runs when the media actually\n * changes — not on every parent re-render that passes a new array. */\nexport function mediaSignature(\n media: readonly PreviewMedia[] | undefined,\n): string {\n return (media ?? [])\n .map((item) => {\n const source = item.url ?? fileKey(item.file);\n const size = `${item.width ?? ''}x${item.height ?? ''}`;\n return `${item.kind}|${source}|${item.posterUrl ?? ''}|${size}|${item.alt ?? ''}`;\n })\n .join('§');\n}\n\n/** Stable string of the per-item alt fallbacks, for memo keying. */\nexport function altSignatureOf(media: AltFallbacks): string {\n return (media ?? []).map((m) => m?.alt_text_override ?? '').join('§');\n}\n\nexport function useResolvedMedia(\n media: readonly PreviewMedia[] | undefined,\n altFallbacks: AltFallbacks,\n altSignature: string,\n): ResolvedMedia[] {\n const signature = mediaSignature(media);\n const [objectUrls, setObjectUrls] = useState<Record<number, string>>({});\n\n useEffect(() => {\n const created: string[] = [];\n const next: Record<number, string> = {};\n (media ?? []).forEach((item, index) => {\n if (!item.url && item.file) {\n const url = URL.createObjectURL(item.file);\n created.push(url);\n next[index] = url;\n }\n });\n setObjectUrls(next);\n return () => {\n for (const url of created) {\n URL.revokeObjectURL(url);\n }\n };\n // `signature` captures every File identity that needs an object URL.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature]);\n\n return useMemo(\n () =>\n (media ?? []).flatMap((item, index): ResolvedMedia[] => {\n const src = item.url ?? objectUrls[index];\n if (!src) {\n return [];\n }\n return [\n {\n kind: item.kind,\n src,\n width: item.width,\n height: item.height,\n alt: item.alt ?? altFallbacks?.[index]?.alt_text_override ?? undefined,\n posterSrc: item.posterUrl,\n },\n ];\n }),\n // `signature` + `altSignature` capture the content; `objectUrls` flips once\n // File blobs resolve. Referencing `media`/`altFallbacks` directly is safe.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [signature, altSignature, objectUrls],\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { IconType } from 'react-icons';\nimport {\n FiBarChart2,\n FiHeart,\n FiMessageCircle,\n FiRepeat,\n FiShare,\n} from 'react-icons/fi';\n\n/**\n * A static, honest action row for the X preview: reply, repost, like, views, and\n * share — real Feather icons (via react-icons), NO fabricated counts and no\n * outbound links (a draft hasn't been engaged with). We render our own row rather\n * than react-tweet's `TweetActions` because that one prints a `0` like-count,\n * which would be a lie on an unpublished post.\n *\n * Color inherits react-tweet's CSS variable, so it matches the card in light and\n * dark and restyles with the same variable the rest of the card uses.\n */\n\nconst ROW: CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n maxWidth: 425,\n marginTop: 12,\n color: 'var(--tweet-color-gray-secondary, #536471)',\n};\n\nconst ACTIONS: { label: string; Icon: IconType }[] = [\n { label: 'Reply', Icon: FiMessageCircle },\n { label: 'Repost', Icon: FiRepeat },\n { label: 'Like', Icon: FiHeart },\n { label: 'Views', Icon: FiBarChart2 },\n { label: 'Share', Icon: FiShare },\n];\n\nexport function XPreviewActions() {\n return (\n <div style={ROW}>\n {ACTIONS.map(({ label, Icon }) => (\n <Icon key={label} size={18} aria-label={label} role=\"img\" />\n ))}\n </div>\n );\n}\n","import twitterText from 'twitter-text';\nimport type { TweetEntities } from 'react-tweet/api';\n\n// twitter-text's ESM entry exposes a single default object (no named exports),\n// so a default import is the only form that resolves across bundlers — named\n// imports compile under @types but break in esbuild/rollup at the consumer.\nconst {\n extractCashtagsWithIndices,\n extractHashtagsWithIndices,\n extractMentionsWithIndices,\n extractUrlsWithIndices,\n modifyIndicesFromUTF16ToUnicode,\n} = twitterText;\n\n/**\n * Extract the X text entities (hashtags, @mentions, URLs, $cashtags) from a post\n * body, in the shape `react-tweet`'s `enrichTweet` consumes to rebuild the rich\n * body. Indices come straight from `twitter-text` — the reference implementation\n * X itself uses — so highlighting matches the real platform exactly (Unicode,\n * punctuation boundaries, and all). We never hand-roll the parsing.\n *\n * Fields X's syndication payload carries that a compose-time preview cannot know\n * (a mention's numeric `id_str` / display `name`) are filled with honest stand-ins\n * (`screen_name`), which is all the renderer needs to draw the entity.\n */\nexport function extractEntities(text: string): TweetEntities {\n const hashtags = extractHashtagsWithIndices(text);\n const mentions = extractMentionsWithIndices(text);\n const urls = extractUrlsWithIndices(text);\n const cashtags = extractCashtagsWithIndices(text);\n\n // twitter-text's regex indices are UTF-16; react-tweet slices `Array.from(text)`\n // (codepoint-aware), so convert in place — otherwise any astral char (emoji)\n // before an entity shifts every later highlight. Converting one combined array\n // keeps the per-list references in sync (the helper mutates `.indices`).\n modifyIndicesFromUTF16ToUnicode(text, [\n ...hashtags,\n ...mentions,\n ...urls,\n ...cashtags,\n ]);\n\n return {\n hashtags: hashtags.map((h) => ({ text: h.hashtag, indices: h.indices })),\n user_mentions: mentions.map((m) => ({\n id_str: '',\n name: m.screenName,\n screen_name: m.screenName,\n indices: m.indices,\n })),\n urls: urls.map((u) => ({\n display_url: u.url,\n expanded_url: u.url,\n url: u.url,\n indices: u.indices,\n })),\n symbols: cashtags.map((c) => ({ text: c.cashtag, indices: c.indices })),\n };\n}\n","import type { XPostVariant } from '@postrun/js';\nimport type {\n MediaAnimatedGif,\n MediaDetails,\n MediaPhoto,\n MediaVideo,\n QuotedTweet,\n Tweet,\n TweetUser,\n VideoInfo,\n} from 'react-tweet/api';\n\nimport type { ResolvedMedia, XPreviewAuthor } from '../types';\nimport { extractEntities } from './entities';\n\n/**\n * Maps a Postrun X variant (+ the customer-supplied author/media) into the\n * `Tweet` object `react-tweet` renders. This is the whole \"schema → exact X\n * preview\" brain: a PURE function, no DOM, no network, no `File` handling (the\n * component resolves pixels to URLs before calling this). Every field\n * `react-tweet` reads is filled with a real value — no casts — and engagement\n * metrics are honest zeros (a draft has no likes).\n */\n\n/** Quoted-card content with media already resolved. */\nexport interface ResolvedQuotedTweet {\n author: XPreviewAuthor;\n body?: string;\n media?: ResolvedMedia[];\n}\n\nexport interface ToTweetInput {\n variant: XPostVariant;\n author: XPreviewAuthor;\n media?: ResolvedMedia[];\n quotedTweet?: ResolvedQuotedTweet;\n /** The replied-to account's handle (our schema only stores the parent id). */\n replyToHandle?: string;\n}\n\n/** Neutral placeholder avatar (a grey circle) for when no avatar is supplied —\n * keeps the header from showing a broken image. */\nconst PLACEHOLDER_AVATAR =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\">' +\n '<circle cx=\"24\" cy=\"24\" r=\"24\" fill=\"#cfd9de\"/></svg>',\n );\n\n/** Fallback pixel dimensions when the customer doesn't know the asset's size —\n * a 3:2 frame keeps react-tweet's aspect-ratio math from dividing by zero. */\nconst FALLBACK_WIDTH = 1200;\nconst FALLBACK_HEIGHT = 800;\n\n/** Length in Unicode codepoints (astral-aware), matching how react-tweet slices\n * the body via `Array.from(text)`. */\nfunction codepointLength(text: string): number {\n return Array.from(text).length;\n}\n\nfunction buildUser(author: XPreviewAuthor): TweetUser {\n const verified = author.verified ?? false;\n return {\n id_str: '',\n name: author.name,\n profile_image_url_https: author.avatarUrl ?? PLACEHOLDER_AVATAR,\n profile_image_shape: 'Circle',\n screen_name: author.handle,\n verified: false,\n is_blue_verified: verified,\n };\n}\n\n/** The fields shared by every media kind, contextually typed (derived from\n * `MediaPhoto`) so tuple/literal fields infer correctly without a cast. */\nfunction mediaBase(\n src: string,\n width?: number,\n height?: number,\n): Omit<MediaPhoto, 'type' | 'ext_alt_text'> {\n const w = width ?? FALLBACK_WIDTH;\n const h = height ?? FALLBACK_HEIGHT;\n const size = { h, w, resize: 'fit' };\n return {\n display_url: '',\n expanded_url: '',\n ext_media_availability: { status: 'available' },\n ext_media_color: { palette: [] },\n indices: [0, 0],\n media_url_https: src,\n original_info: { height: h, width: w, focus_rects: [] },\n sizes: { large: size, medium: size, small: size, thumb: size },\n url: src,\n };\n}\n\nfunction buildPhoto(media: ResolvedMedia): MediaPhoto {\n return {\n ...mediaBase(media.src, media.width, media.height),\n type: 'photo',\n ext_alt_text: media.alt,\n };\n}\n\nfunction buildVideo(media: ResolvedMedia): MediaVideo | MediaAnimatedGif {\n const poster = media.posterSrc ?? media.src;\n const videoInfo: VideoInfo = {\n aspect_ratio: [media.width ?? 16, media.height ?? 9],\n variants: [{ content_type: 'video/mp4', url: media.src }],\n };\n const base = mediaBase(poster, media.width, media.height);\n return media.kind === 'gif'\n ? { ...base, type: 'animated_gif', video_info: videoInfo }\n : { ...base, type: 'video', video_info: videoInfo };\n}\n\nfunction buildMediaDetails(media: readonly ResolvedMedia[]): MediaDetails[] {\n return media.map((item) =>\n item.kind === 'image' ? buildPhoto(item) : buildVideo(item),\n );\n}\n\n/** The static, draft-honest scaffolding every synthesized tweet shares. */\nfunction tweetScaffold(): Pick<\n Tweet,\n | 'lang'\n | 'created_at'\n | 'edit_control'\n | 'isEdited'\n | 'isStaleEdit'\n | 'favorite_count'\n | 'conversation_count'\n | 'news_action_type'\n> {\n return {\n lang: 'en',\n created_at: '',\n edit_control: {\n edit_tweet_ids: [],\n editable_until_msecs: '0',\n is_edit_eligible: false,\n edits_remaining: '0',\n },\n isEdited: false,\n isStaleEdit: false,\n favorite_count: 0,\n conversation_count: 0,\n news_action_type: 'conversation',\n };\n}\n\nfunction buildQuoted(\n quote: ResolvedQuotedTweet | undefined,\n hasQuoteId: boolean,\n): QuotedTweet | undefined {\n if (!quote && !hasQuoteId) {\n return undefined;\n }\n\n const author = quote?.author ?? { name: 'Quoted post', handle: '' };\n const body = quote?.body ?? '';\n const media = quote?.media ?? [];\n\n return {\n lang: 'en',\n created_at: '',\n display_text_range: [0, codepointLength(body)],\n entities: extractEntities(body),\n id_str: '',\n text: body,\n user: buildUser(author),\n edit_control: {\n edit_tweet_ids: [],\n editable_until_msecs: '0',\n is_edit_eligible: false,\n edits_remaining: '0',\n },\n isEdited: false,\n isStaleEdit: false,\n reply_count: 0,\n retweet_count: 0,\n favorite_count: 0,\n self_thread: { id_str: '' },\n ...(media.length > 0 ? { mediaDetails: buildMediaDetails(media) } : {}),\n };\n}\n\nexport function toTweet(input: ToTweetInput): Tweet {\n const { variant, author, media = [], quotedTweet, replyToHandle } = input;\n const text = variant.body ?? '';\n const mediaDetails = buildMediaDetails(media);\n const quoted = buildQuoted(\n quotedTweet,\n variant.settings?.quote_tweet_id !== undefined,\n );\n const reply = variant.settings?.reply;\n\n return {\n __typename: 'Tweet',\n ...tweetScaffold(),\n // Codepoint length, not `text.length` (UTF-16) — react-tweet renders the\n // body off `Array.from(text)`, so emoji must not shift the range.\n display_text_range: [0, codepointLength(text)],\n entities: extractEntities(text),\n id_str: '',\n text,\n user: buildUser(author),\n ...(mediaDetails.length > 0 ? { mediaDetails } : {}),\n ...(quoted ? { quoted_tweet: quoted } : {}),\n // Both the handle AND the parent id are needed: enrichTweet builds the\n // reply link as `…/${screen_name}/status/${status_id_str}`, so omitting the\n // id yields a `/status/undefined` href.\n ...(reply && replyToHandle\n ? {\n in_reply_to_screen_name: replyToHandle,\n in_reply_to_status_id_str: reply.in_reply_to_tweet_id,\n }\n : {}),\n };\n}\n","'use client';\n\nimport type { XPostVariant } from '@postrun/js';\nimport { memo, useMemo } from 'react';\nimport type { CSSProperties } from 'react';\nimport {\n QuotedTweet,\n TweetBody,\n TweetContainer,\n TweetHeader,\n TweetInReplyTo,\n TweetMedia,\n type TwitterComponents,\n enrichTweet,\n} from 'react-tweet';\n\nimport type {\n PreviewMedia,\n XPreviewAuthor,\n XPreviewQuotedTweet,\n} from '../types';\nimport { altSignatureOf, useResolvedMedia } from '../use-resolved-media';\nimport { XPreviewActions } from './XPreviewActions';\nimport { toTweet } from './to-tweet';\n\nexport interface XPostPreviewProps {\n /** The X variant from our schema — the content source, untouched. */\n variant: XPostVariant;\n /** Author identity (not stored on our connection — supplied by you). */\n author: XPreviewAuthor;\n /** Resolved media pixels (URLs or compose-time File blobs). */\n media?: PreviewMedia[];\n /** Content for the quoted card when `settings.quote_tweet_id` is set. */\n quotedTweet?: XPreviewQuotedTweet;\n /** The replied-to account's handle (our schema only stores the parent id). */\n replyToHandle?: string;\n /** Color scheme. `auto` (default) inherits the host's theme. */\n theme?: 'light' | 'dark' | 'auto';\n /** Show the static action row (icons, no counts). Default true. */\n showActions?: boolean;\n /** Class applied to the wrapper — your hook for sizing, shadows, etc. */\n className?: string;\n /** Inline styles on the wrapper — e.g. react-tweet CSS variables\n * (`{ ['--tweet-container-margin']: '0' }`). */\n style?: CSSProperties;\n /** Override react-tweet's internal pieces (e.g. `next/image` avatars). */\n components?: TwitterComponents;\n}\n\n/**\n * A faithful, pixel-accurate preview of how an X post will look once published,\n * rendered straight from a Postrun X variant. Built on `react-tweet` (the same\n * card X itself ships), so you write zero card UI — pass the schema, render the\n * preview. Fully customizable: restyle via `className`/`style` (CSS variables)\n * or swap internals via `components`; theme light/dark/auto.\n */\nfunction XPostPreviewImpl({\n variant,\n author,\n media,\n quotedTweet,\n replyToHandle,\n theme = 'auto',\n showActions = true,\n className,\n style,\n components,\n}: XPostPreviewProps) {\n const resolvedMedia = useResolvedMedia(\n media,\n variant.media,\n altSignatureOf(variant.media),\n );\n const resolvedQuotedMedia = useResolvedMedia(quotedTweet?.media, undefined, '');\n\n const tweet = useMemo(() => {\n const resolvedQuoted = quotedTweet\n ? {\n author: quotedTweet.author,\n body: quotedTweet.body,\n media: resolvedQuotedMedia,\n }\n : undefined;\n\n return enrichTweet(\n toTweet({\n variant,\n author,\n media: resolvedMedia,\n quotedTweet: resolvedQuoted,\n replyToHandle,\n }),\n );\n }, [\n variant,\n author,\n resolvedMedia,\n quotedTweet,\n resolvedQuotedMedia,\n replyToHandle,\n ]);\n\n return (\n <div\n data-theme={theme === 'auto' ? undefined : theme}\n className={className}\n style={style}\n >\n <TweetContainer>\n <TweetHeader tweet={tweet} components={components} />\n {tweet.in_reply_to_screen_name ? <TweetInReplyTo tweet={tweet} /> : null}\n <TweetBody tweet={tweet} />\n {tweet.mediaDetails?.length ? (\n <TweetMedia tweet={tweet} components={components} />\n ) : null}\n {tweet.quoted_tweet ? <QuotedTweet tweet={tweet.quoted_tweet} /> : null}\n {showActions ? <XPreviewActions /> : null}\n </TweetContainer>\n </div>\n );\n}\n\n/** Memoized: re-renders only when its props change (the resolved-media hook\n * already absorbs unstable media arrays). */\nexport const XPostPreview = memo(XPostPreviewImpl);\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * LinkedIn preview theming. Unlike the X preview (which inherits react-tweet's\n * CSS), we own the LinkedIn card, so we expose a small set of CSS custom\n * properties on the wrapper. The resolved palette sets their default values;\n * a customer can override any of them via `style`/`className`. Components read\n * `var(--pr-li-*)`, so restyling needs no fork.\n */\n\nexport type LinkedInTheme = 'light' | 'dark' | 'auto';\n\nexport const LI_VAR = {\n bg: '--pr-li-bg',\n text: '--pr-li-text',\n muted: '--pr-li-muted',\n border: '--pr-li-border',\n accent: '--pr-li-accent',\n};\n\ninterface Palette {\n bg: string;\n text: string;\n muted: string;\n border: string;\n accent: string;\n}\n\nconst LIGHT: Palette = {\n bg: '#ffffff',\n text: 'rgba(0,0,0,0.9)',\n muted: 'rgba(0,0,0,0.6)',\n border: 'rgba(0,0,0,0.08)',\n accent: 'rgb(10,102,194)',\n};\n\nconst DARK: Palette = {\n bg: '#1b1f23',\n text: 'rgba(255,255,255,0.9)',\n muted: 'rgba(255,255,255,0.6)',\n border: 'rgba(255,255,255,0.15)',\n accent: 'rgb(112,181,249)',\n};\n\n/** A CSS `var(...)` reference to one of the LinkedIn theme variables. */\nexport function varRef(name: string): string {\n return `var(${name})`;\n}\n\n/** The CSS custom-property declarations for a resolved scheme. Typed as a plain\n * string record (React's `CSSProperties` doesn't model `--custom` keys); it is\n * spread into the card's `style`, where React forwards it to the DOM. */\nexport function paletteVars(dark: boolean): Record<string, string> {\n const p = dark ? DARK : LIGHT;\n return {\n '--pr-li-bg': p.bg,\n '--pr-li-text': p.text,\n '--pr-li-muted': p.muted,\n '--pr-li-border': p.border,\n '--pr-li-accent': p.accent,\n };\n}\n\n/** Track the OS color scheme for `theme=\"auto\"`. Starts light (SSR-safe, no\n * hydration mismatch) and updates after mount. */\nexport function usePrefersDark(): boolean {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return;\n }\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n setDark(mq.matches);\n const onChange = (event: MediaQueryListEvent) => setDark(event.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n\n return dark;\n}\n\n/** Resolve whether the card should render dark for a given theme prop. */\nexport function useIsDark(theme: LinkedInTheme): boolean {\n const prefersDark = usePrefersDark();\n if (theme === 'auto') {\n return prefersDark;\n }\n return theme === 'dark';\n}\n","import type { CSSProperties } from 'react';\nimport type { IconType } from 'react-icons';\nimport { FiMessageSquare, FiRepeat, FiSend, FiThumbsUp } from 'react-icons/fi';\n\nimport { LI_VAR, varRef } from './theme';\n\n/**\n * The static LinkedIn action bar — Like / Comment / Repost / Send. Real Feather\n * icons (via react-icons) + labels, no fabricated reaction counts (a draft has\n * none). Honest, like the X preview's footer.\n */\n\nconst ROW: CSSProperties = {\n display: 'flex',\n justifyContent: 'space-around',\n borderTop: `1px solid ${varRef(LI_VAR.border)}`,\n marginTop: 8,\n padding: '4px 8px',\n};\n\nconst ITEM: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px',\n color: varRef(LI_VAR.muted),\n fontSize: 14,\n fontWeight: 600,\n};\n\nconst ACTIONS: { label: string; Icon: IconType }[] = [\n { label: 'Like', Icon: FiThumbsUp },\n { label: 'Comment', Icon: FiMessageSquare },\n { label: 'Repost', Icon: FiRepeat },\n { label: 'Send', Icon: FiSend },\n];\n\nexport function EngagementBar() {\n return (\n <div style={ROW}>\n {ACTIONS.map(({ label, Icon }) => (\n <span key={label} style={ITEM}>\n <Icon size={20} aria-hidden />\n {label}\n </span>\n ))}\n </div>\n );\n}\n","import { FiGlobe, FiUsers } from 'react-icons/fi';\nimport { LuBadgeCheck } from 'react-icons/lu';\n\nimport type { LinkedInPreviewAuthor } from '../types';\nimport { LI_VAR, varRef } from './theme';\n\n/**\n * The LinkedIn post header: avatar, actor name (+ optional verified badge),\n * one-line headline, then a muted row with a relative time and the audience icon\n * (globe = public, people = connections-only). Real Feather/Lucide icons via\n * react-icons — no hand-drawn paths.\n */\n\nexport type LinkedInVisibility = 'PUBLIC' | 'CONNECTIONS';\n\nconst PLACEHOLDER_AVATAR =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\">' +\n '<circle cx=\"24\" cy=\"24\" r=\"24\" fill=\"#9aa6b2\"/></svg>',\n );\n\nexport interface HeaderProps {\n author: LinkedInPreviewAuthor;\n visibility: LinkedInVisibility;\n /** Relative time label, e.g. \"Now\". */\n time?: string;\n}\n\nexport function Header({ author, visibility, time = 'Now' }: HeaderProps) {\n return (\n <div style={{ display: 'flex', gap: 8, padding: '12px 16px 0' }}>\n <img\n src={author.avatarUrl ?? PLACEHOLDER_AVATAR}\n alt=\"\"\n width={48}\n height={48}\n style={{ width: 48, height: 48, borderRadius: '50%', objectFit: 'cover', flex: '0 0 auto' }}\n />\n <div style={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n fontSize: 14,\n fontWeight: 600,\n color: varRef(LI_VAR.text),\n lineHeight: 1.3,\n }}\n >\n {author.name}\n {author.verified ? (\n <LuBadgeCheck\n size={16}\n aria-label=\"Verified\"\n role=\"img\"\n style={{ color: varRef(LI_VAR.accent), marginLeft: 3, flex: '0 0 auto' }}\n />\n ) : null}\n </span>\n {author.headline ? (\n <span style={{ fontSize: 12, color: varRef(LI_VAR.muted), lineHeight: 1.3 }}>\n {author.headline}\n </span>\n ) : null}\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 12,\n color: varRef(LI_VAR.muted),\n lineHeight: 1.3,\n }}\n >\n {time} •{' '}\n {visibility === 'PUBLIC' ? (\n <FiGlobe size={13} aria-label=\"Public\" role=\"img\" />\n ) : (\n <FiUsers size={13} aria-label=\"Connections\" role=\"img\" />\n )}\n </span>\n </div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\n\nimport type { ResolvedMedia } from '../types';\n\n/**\n * LinkedIn's image layout: a single full-bleed image, or the 2/3/4 mosaic with a\n * \"+N\" overlay on the fourth tile when there are more than four. Edge-to-edge,\n * 2px gutters — matching the in-feed look.\n */\n\nconst MAX_TILES = 4;\nconst MOSAIC_HEIGHT = 272;\n\nconst GRID_BASE: CSSProperties = {\n display: 'grid',\n gap: 2,\n height: MOSAIC_HEIGHT,\n overflow: 'hidden',\n};\n\n/** Grid template for a given visible-tile count (2, 3 or 4). */\nfunction gridStyle(tiles: number): CSSProperties {\n if (tiles === 2) {\n return { ...GRID_BASE, gridTemplateColumns: '1fr 1fr' };\n }\n if (tiles === 3) {\n // One tall image on the left, two stacked on the right.\n return {\n ...GRID_BASE,\n gridTemplateColumns: '1fr 1fr',\n gridTemplateRows: '1fr 1fr',\n gridTemplateAreas: '\"a b\" \"a c\"',\n };\n }\n return {\n ...GRID_BASE,\n gridTemplateColumns: '1fr 1fr',\n gridTemplateRows: '1fr 1fr',\n };\n}\n\nconst IMG_STYLE: CSSProperties = {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n};\n\nconst AREAS = ['a', 'b', 'c'];\n\nfunction Tile({\n item,\n area,\n overlay,\n}: {\n item: ResolvedMedia;\n area?: string;\n overlay?: number;\n}) {\n return (\n <div style={{ position: 'relative', gridArea: area, overflow: 'hidden' }}>\n <img src={item.src} alt={item.alt ?? ''} style={IMG_STYLE} />\n {overlay ? (\n <div\n aria-hidden={false}\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.5)',\n color: '#fff',\n fontSize: 28,\n fontWeight: 600,\n }}\n >\n {`+${overlay}`}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface ImageMosaicProps {\n media: readonly ResolvedMedia[];\n}\n\nexport function ImageMosaic({ media }: ImageMosaicProps) {\n if (media.length === 0) {\n return null;\n }\n\n if (media.length === 1) {\n const only = media[0]!;\n return (\n <img\n src={only.src}\n alt={only.alt ?? ''}\n style={{ width: '100%', height: 'auto', display: 'block' }}\n />\n );\n }\n\n const tiles = media.slice(0, MAX_TILES);\n const hidden = media.length - MAX_TILES;\n\n return (\n <div style={gridStyle(tiles.length)}>\n {tiles.map((item, index) => (\n <Tile\n key={item.src + index}\n item={item}\n area={tiles.length === 3 ? AREAS[index] : undefined}\n overlay={\n hidden > 0 && index === MAX_TILES - 1 ? hidden : undefined\n }\n />\n ))}\n </div>\n );\n}\n","import type { ResolvedMedia } from '../types';\nimport { ImageMosaic } from './ImageMosaic';\n\n/**\n * The media area of a LinkedIn post (v1: images + video). A post carries either\n * a video or images; a video wins if present and renders as a playable element\n * with its poster, otherwise the image mosaic. Edge-to-edge, like the feed.\n */\n\nfunction VideoTile({ item }: { item: ResolvedMedia }) {\n return (\n <video\n src={item.src}\n poster={item.posterSrc}\n controls\n style={{ width: '100%', display: 'block', background: '#000' }}\n />\n );\n}\n\nexport interface MediaProps {\n media: readonly ResolvedMedia[];\n}\n\nexport function Media({ media }: MediaProps) {\n if (media.length === 0) {\n return null;\n }\n\n const video = media.find(\n (item) => item.kind === 'video' || item.kind === 'gif',\n );\n if (video) {\n return <VideoTile item={video} />;\n }\n\n const images = media.filter((item) => item.kind === 'image');\n return <ImageMosaic media={images} />;\n}\n","'use client';\n\nimport { Fragment, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\n/**\n * The LinkedIn post body: entity-highlighted text with the platform's faithful\n * \"…more\" fold. LinkedIn truncates a long post to a few lines with an inline\n * \"…more\" toggle; we mirror that. Hashtags, URLs, and supplied @mention names\n * render in the accent color, exactly as they appear in-feed.\n */\n\n/** Roughly the in-feed fold point — long posts collapse here behind \"…more\". */\nconst FOLD_CHARS = 200;\n\nexport interface PostBodyColors {\n accent: string;\n muted: string;\n}\n\nexport interface PostBodyProps {\n text: string;\n /** Names to highlight as @mentions (from `settings.mentions[].name`). */\n mentionNames?: readonly string[];\n colors: PostBodyColors;\n}\n\nconst BODY_STYLE: CSSProperties = {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n fontSize: 14,\n lineHeight: 1.43,\n};\n\n/** Truncate to at most `max` characters, backing up to the last word boundary. */\nfunction truncateAtWord(text: string, max: number): string {\n if (text.length <= max) {\n return text;\n }\n const slice = text.slice(0, max);\n const lastSpace = slice.lastIndexOf(' ');\n return slice.slice(0, lastSpace > 0 ? lastSpace : max);\n}\n\n/** Escape a string for safe use inside a RegExp. */\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/** Build the tokenizer: hashtags, URLs, then any supplied mention names. */\nfunction buildPattern(mentionNames: readonly string[]): RegExp {\n const mentionAlt = mentionNames\n .filter((name) => name.trim().length > 0)\n .map(escapeRegExp)\n .join('|');\n const parts = [\n 'https?:\\\\/\\\\/[^\\\\s]+', // urls\n '#[\\\\p{L}\\\\p{N}_]+', // hashtags (unicode-aware)\n ...(mentionAlt ? [mentionAlt] : []),\n ];\n return new RegExp(`(${parts.join('|')})`, 'gu');\n}\n\nfunction linkStyle(color: string): CSSProperties {\n return { color, textDecoration: 'none', fontWeight: 500 };\n}\n\n/** Split text into plain runs and highlighted entity nodes. */\nfunction linkify(\n text: string,\n colors: PostBodyColors,\n mentionNames: readonly string[],\n): ReactNode[] {\n const pattern = buildPattern(mentionNames);\n const nodes: ReactNode[] = [];\n let lastIndex = 0;\n let key = 0;\n\n for (const match of text.matchAll(pattern)) {\n const token = match[0];\n const start = match.index;\n if (start > lastIndex) {\n nodes.push(\n <Fragment key={key++}>{text.slice(lastIndex, start)}</Fragment>,\n );\n }\n if (token.startsWith('http')) {\n nodes.push(\n <a\n key={key++}\n href={token}\n style={linkStyle(colors.accent)}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {token}\n </a>,\n );\n } else if (token.startsWith('#')) {\n nodes.push(\n <a key={key++} href=\"#\" style={linkStyle(colors.accent)}>\n {token}\n </a>,\n );\n } else {\n nodes.push(\n <span key={key++} style={linkStyle(colors.accent)}>\n {token}\n </span>,\n );\n }\n lastIndex = start + token.length;\n }\n\n if (lastIndex < text.length) {\n nodes.push(<Fragment key={key++}>{text.slice(lastIndex)}</Fragment>);\n }\n return nodes;\n}\n\nexport function PostBody({ text, mentionNames = [], colors }: PostBodyProps) {\n const [expanded, setExpanded] = useState(false);\n const isLong = text.length > FOLD_CHARS;\n const shown = isLong && !expanded ? truncateAtWord(text, FOLD_CHARS) : text;\n\n return (\n <div style={BODY_STYLE}>\n {linkify(shown, colors, mentionNames)}\n {isLong && !expanded ? (\n <>\n {'…'}{' '}\n <button\n type=\"button\"\n onClick={() => setExpanded(true)}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n color: colors.muted,\n fontWeight: 600,\n fontSize: 14,\n }}\n >\n more\n </button>\n </>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport type { LinkedInPostVariant } from '@postrun/js';\nimport { memo } from 'react';\nimport type { CSSProperties } from 'react';\n\nimport type { LinkedInPreviewAuthor, PreviewMedia } from '../types';\nimport { altSignatureOf, useResolvedMedia } from '../use-resolved-media';\nimport { EngagementBar } from './EngagementBar';\nimport { Header } from './Header';\nimport type { LinkedInVisibility } from './Header';\nimport { Media } from './Media';\nimport { PostBody } from './PostBody';\nimport {\n LI_VAR,\n type LinkedInTheme,\n paletteVars,\n useIsDark,\n varRef,\n} from './theme';\n\n/**\n * A faithful, schema-driven preview of how a LinkedIn post will look in-feed,\n * rendered straight from a Postrun LinkedIn variant. Clean-room components (no\n * dependency to \"buy\" exists for LinkedIn), mirroring the real feed card: header\n * with headline + audience icon, an entity-highlighted body with the \"…more\"\n * fold, the 1/2/3/4/+N image mosaic (or a video), and a static action bar.\n *\n * v1 renders text + images + video. The richer `content_kind`s (article, poll,\n * document) degrade gracefully to the text/media card and arrive next.\n *\n * Customize via `theme` (light/dark/auto), `className`/`style`, or by overriding\n * the `--pr-li-*` CSS variables the card reads.\n */\nexport interface LinkedInPostPreviewProps {\n /** The LinkedIn variant from our schema — the content source, untouched. */\n variant: LinkedInPostVariant;\n /** Author identity (LinkedIn stores no avatar/headline on our connection). */\n author: LinkedInPreviewAuthor;\n /** Resolved media pixels (URLs or compose-time File blobs). */\n media?: PreviewMedia[];\n /** Color scheme. `auto` (default) follows the OS preference. */\n theme?: LinkedInTheme;\n /** Relative time label shown in the header. Default \"Now\". */\n time?: string;\n /** Show the static action bar (Like/Comment/Repost/Send). Default true. */\n showActions?: boolean;\n /** Class applied to the card — your hook for sizing, shadows, etc. */\n className?: string;\n /** Inline styles on the card — including `--pr-li-*` variable overrides. */\n style?: CSSProperties;\n}\n\nconst FONT_STACK =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\nfunction LinkedInPostPreviewImpl({\n variant,\n author,\n media,\n theme = 'auto',\n time,\n showActions = true,\n className,\n style,\n}: LinkedInPostPreviewProps) {\n const dark = useIsDark(theme);\n const resolvedMedia = useResolvedMedia(\n media,\n variant.media,\n altSignatureOf(variant.media),\n );\n\n const visibility: LinkedInVisibility =\n variant.settings?.visibility ?? 'PUBLIC';\n const mentionNames = (variant.settings?.mentions ?? []).map((m) => m.name);\n const bodyColors = {\n accent: varRef(LI_VAR.accent),\n muted: varRef(LI_VAR.muted),\n };\n\n const cardStyle: CSSProperties = {\n ...paletteVars(dark),\n background: varRef(LI_VAR.bg),\n color: varRef(LI_VAR.text),\n border: `1px solid ${varRef(LI_VAR.border)}`,\n borderRadius: 10,\n maxWidth: 552,\n overflow: 'hidden',\n fontFamily: FONT_STACK,\n ...style,\n };\n\n return (\n <div className={className} style={cardStyle}>\n <Header author={author} visibility={visibility} time={time} />\n {variant.body ? (\n <div style={{ padding: '8px 16px 0' }}>\n <PostBody\n text={variant.body}\n mentionNames={mentionNames}\n colors={bodyColors}\n />\n </div>\n ) : null}\n {resolvedMedia.length > 0 ? (\n <div style={{ marginTop: 12 }}>\n <Media media={resolvedMedia} />\n </div>\n ) : null}\n {showActions ? <EngagementBar /> : null}\n </div>\n );\n}\n\n/** Memoized: re-renders only when its props change (the resolved-media hook\n * absorbs unstable media arrays). */\nexport const LinkedInPostPreview = memo(LinkedInPostPreviewImpl);\n"]}
1
+ {"version":3,"sources":["../src/context.tsx","../src/infinite-list.ts","../src/keys.ts","../src/profiles.ts","../src/navigate.ts","../src/connections.ts","../src/upload-bytes.ts","../src/media.ts","../src/posts.ts","../src/preview/use-resolved-media.ts","../src/preview/x/XPreviewActions.tsx","../src/preview/x/entities.ts","../src/preview/x/to-tweet.ts","../src/preview/x/XPostPreview.tsx","../src/preview/linkedin/theme.ts","../src/preview/linkedin/EngagementBar.tsx","../src/preview/linkedin/Header.tsx","../src/preview/linkedin/ImageMosaic.tsx","../src/preview/linkedin/Media.tsx","../src/preview/linkedin/PostBody.tsx","../src/preview/linkedin/LinkedInPostPreview.tsx"],"names":["QueryClient","createContext","useRef","useEffect","useMemo","createPostrunClient","createElement","useContext","useInfiniteQuery","useQuery","profilesList","profilesGet","useMutation","profilesCreate","profilesUpdate","profilesDelete","connectionsConnect","connectionsListByProfile","connectionsGet","connectionsListAccounts","connectionsSelect","connectionsDelete","axios","isAxiosError","pWaitFor","mediaGet","useState","useCallback","mediaCreate","pRetry","AbortError","mediaList","mediaUpdate","mediaDelete","postsList","postsGet","postsCreate","buildCreatePost","isPostPlatform","postsUpdate","postsDelete","FiMessageCircle","FiRepeat","FiHeart","FiBarChart2","FiShare","jsx","twitterText","enrichTweet","TweetContainer","TweetHeader","TweetInReplyTo","TweetBody","TweetMedia","QuotedTweet","memo","ROW","ACTIONS","FiThumbsUp","FiMessageSquare","FiSend","jsxs","PLACEHOLDER_AVATAR","LuBadgeCheck","FiGlobe","FiUsers","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { QueryClient } from '@tanstack/react-query';\n\nimport { createPostrunClient } from '@postrun/js';\nimport type { PostrunClient } from '@postrun/js';\n\n/**\n * The value every hook and component reads from context: the typed SDK client\n * plus a private TanStack `QueryClient` that powers caching, dedup, and\n * revalidation. Hooks pass this `queryClient` explicitly to `useQuery` /\n * `useMutation`, so it stays fully isolated from any QueryClient the host app\n * runs of its own — no `QueryClientProvider` setup required from the customer.\n */\nexport interface PostrunContextValue {\n client: PostrunClient;\n queryClient: QueryClient;\n}\n\n/** Sensible defaults: treat data as fresh briefly to avoid refetch storms. */\nfunction createDefaultQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: { staleTime: 30_000 },\n },\n });\n}\n\nconst PostrunContext = createContext<PostrunContextValue | null>(null);\nPostrunContext.displayName = 'PostrunContext';\n\nexport interface PostrunProviderProps {\n /**\n * Returns a valid short-lived scoped token. The host app's backend mints it\n * from a secret `pr_` key (`POST /v1/tokens`); the secret never reaches the\n * browser. Called per request — cache and refresh before `exp` inside here.\n */\n getToken: () => string | Promise<string>;\n /** Override the API base URL (defaults to the production gateway). */\n baseUrl?: string;\n /**\n * Bring your own TanStack `QueryClient` (advanced: shared DevTools, custom\n * defaults, tests). Omit it and a private, isolated one is created for you.\n */\n queryClient?: QueryClient;\n children: ReactNode;\n}\n\nexport function PostrunProvider({\n getToken,\n baseUrl,\n queryClient,\n children,\n}: PostrunProviderProps) {\n // Keep the latest `getToken` in a ref so the client can always call the\n // freshest closure WITHOUT being rebuilt when callers pass a new arrow each\n // render (the common case). The client is constructed once per `baseUrl`.\n const getTokenRef = useRef(getToken);\n useEffect(() => {\n getTokenRef.current = getToken;\n }, [getToken]);\n\n const client = useMemo(\n () =>\n createPostrunClient({ getToken: () => getTokenRef.current(), baseUrl }),\n [baseUrl],\n );\n\n const resolvedQueryClient = useMemo(\n () => queryClient ?? createDefaultQueryClient(),\n [queryClient],\n );\n\n const value = useMemo<PostrunContextValue>(\n () => ({ client, queryClient: resolvedQueryClient }),\n [client, resolvedQueryClient],\n );\n\n return createElement(PostrunContext.Provider, { value }, children);\n}\n\n/** Access the configured Postrun client. Throws if used outside a provider. */\nexport function usePostrun(): PostrunContextValue {\n const value = useContext(PostrunContext);\n\n if (value === null) {\n throw new Error('usePostrun must be used within a <PostrunProvider>.');\n }\n\n return value;\n}\n","import { useInfiniteQuery } from '@tanstack/react-query';\nimport type { QueryKey } from '@tanstack/react-query';\n\nimport { usePostrun } from './context';\n\n/**\n * The offset-pagination envelope every Postrun list endpoint returns. The helper\n * only needs these fields; the concrete page type comes from the SDK response\n * (e.g. `PostList`), which satisfies this structurally — nothing is redeclared.\n */\ninterface PageEnvelope<TItem> {\n data: TItem[];\n total: number;\n offset: number;\n has_more: boolean;\n}\n\n/** A flattened, append-style (\"load more\") view over a paginated list endpoint. */\nexport interface InfiniteList<TItem> {\n /** Every item loaded so far, flattened across all fetched pages. */\n items: TItem[];\n /** Total items matching the filter (from the first page's envelope). */\n total: number;\n /** Fetch the next page and append it. No-op once `hasMore` is false. */\n loadMore: () => void;\n /** Whether another page exists beyond what's loaded. */\n hasMore: boolean;\n /** The first page is loading (no items yet). */\n isLoading: boolean;\n /** A `loadMore()` is in flight (items are already shown). */\n isLoadingMore: boolean;\n /** The last error, or null. Narrow with `instanceof PostrunError`. */\n error: Error | null;\n /** Refetch from the first page (re-runs every loaded page). */\n refetch: () => void;\n}\n\n/**\n * Turn an offset-paginated Postrun list endpoint into a clean append-style\n * `{ items, loadMore, hasMore, … }` surface — the \"Load more\" / infinite-scroll\n * shape a feed or calendar wants.\n *\n * Built on TanStack `useInfiniteQuery`, so page accumulation is its job and never\n * hand-rolled. The next offset is read from the envelope itself\n * (`offset + data.length`), so it stays correct regardless of page size.\n * `fetchPage` supplies the resource-specific SDK call; the page type is inferred\n * from its return, so item types are derived, never redeclared.\n */\nexport function useInfiniteList<TItem>(args: {\n queryKey: QueryKey;\n fetchPage: (page: {\n limit: number;\n offset: number;\n }) => Promise<PageEnvelope<TItem>>;\n /** Items per page (default 20, the API's own default). */\n limit?: number;\n enabled?: boolean;\n}): InfiniteList<TItem> {\n const { queryClient } = usePostrun();\n const limit = args.limit ?? 20;\n\n const query = useInfiniteQuery(\n {\n queryKey: args.queryKey,\n queryFn: ({ pageParam }) => args.fetchPage({ limit, offset: pageParam }),\n initialPageParam: 0,\n getNextPageParam: (last) =>\n last.has_more ? last.offset + last.data.length : undefined,\n enabled: args.enabled,\n },\n queryClient,\n );\n\n return {\n items: query.data?.pages.flatMap((page) => page.data) ?? [],\n total: query.data?.pages[0]?.total ?? 0,\n loadMore: () => {\n void query.fetchNextPage();\n },\n hasMore: query.hasNextPage,\n isLoading: query.isLoading,\n isLoadingMore: query.isFetchingNextPage,\n error: query.error,\n refetch: () => {\n void query.refetch();\n },\n };\n}\n","import type {\n ConnectionKind,\n ConnectionStatus,\n ListMediaQuery,\n ListPostsQuery,\n ListProfilesQuery,\n} from '@postrun/js';\n\n/** The connection-list filter that keys the cache (social/ads + lifecycle). */\nexport interface ConnectionsFilter {\n kind?: ConnectionKind;\n status?: ConnectionStatus;\n}\n\n/** Root namespace so our cache never collides with the host app's own queries. */\nconst ROOT = 'postrun';\n\n/**\n * Query-key factory for profiles. Hierarchical so a mutation can invalidate at\n * the right granularity: `lists()` after a create, `detail(id)` after an update.\n */\nexport const profileKeys = {\n all: [ROOT, 'profiles'] as const,\n lists: () => [...profileKeys.all, 'list'] as const,\n list: (query?: ListProfilesQuery) =>\n [...profileKeys.lists(), query ?? {}] as const,\n // Nested under lists() so a create/update/delete invalidating lists() also\n // refreshes the infinite cache; distinct tail so the two cache shapes (a\n // single Page vs accumulated pages) never collide on one key. The filter omits\n // limit/offset — the infinite hook owns pagination, so they never key the cache.\n infinite: (query?: Omit<ListProfilesQuery, 'limit' | 'offset'>) =>\n [...profileKeys.lists(), 'infinite', query ?? {}] as const,\n details: () => [...profileKeys.all, 'detail'] as const,\n detail: (id: string) => [...profileKeys.details(), id] as const,\n};\n\n/** Query-key factory for posts (list filtered by query; detail by id). */\nexport const postKeys = {\n all: [ROOT, 'posts'] as const,\n lists: () => [...postKeys.all, 'list'] as const,\n list: (query?: ListPostsQuery) => [...postKeys.lists(), query ?? {}] as const,\n // Nested under lists() so a create/update/delete invalidating lists() also\n // refreshes the infinite cache; distinct tail so the two cache shapes (a\n // single Page vs accumulated pages) never collide on one key. The filter omits\n // limit/offset — the infinite hook owns pagination, so they never key the cache.\n infinite: (query?: Omit<ListPostsQuery, 'limit' | 'offset'>) =>\n [...postKeys.lists(), 'infinite', query ?? {}] as const,\n details: () => [...postKeys.all, 'detail'] as const,\n detail: (id: string) => [...postKeys.details(), id] as const,\n};\n\n/** Query-key factory for media assets (list filtered by query; detail by id). */\nexport const mediaKeys = {\n all: [ROOT, 'media'] as const,\n lists: () => [...mediaKeys.all, 'list'] as const,\n list: (query?: ListMediaQuery) => [...mediaKeys.lists(), query ?? {}] as const,\n // Nested under lists() so an upload/update/delete invalidating lists() also\n // refreshes the infinite cache; distinct tail so the two cache shapes (a\n // single Page vs accumulated pages) never collide on one key. The filter omits\n // limit/offset — the infinite hook owns pagination, so they never key the cache.\n infinite: (query?: Omit<ListMediaQuery, 'limit' | 'offset'>) =>\n [...mediaKeys.lists(), 'infinite', query ?? {}] as const,\n details: () => [...mediaKeys.all, 'detail'] as const,\n detail: (id: string) => [...mediaKeys.details(), id] as const,\n};\n\n/** Query-key factory for connections (lists keyed by owning profile). */\nexport const connectionKeys = {\n all: [ROOT, 'connections'] as const,\n lists: () => [...connectionKeys.all, 'list'] as const,\n list: (profileId: string, filter?: ConnectionsFilter) =>\n [...connectionKeys.lists(), profileId, filter ?? {}] as const,\n details: () => [...connectionKeys.all, 'detail'] as const,\n detail: (id: string) => [...connectionKeys.details(), id] as const,\n accounts: (id: string) => [...connectionKeys.all, 'accounts', id] as const,\n};\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n profilesCreate,\n profilesDelete,\n profilesGet,\n profilesList,\n profilesUpdate,\n} from '@postrun/js';\nimport type {\n CreateProfileInput,\n ListProfilesQuery,\n Profile,\n UpdateProfileInput,\n} from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { useInfiniteList } from './infinite-list';\nimport { profileKeys } from './keys';\n\n/**\n * List the account's profiles (client/brand workspaces), filtered and paginated.\n * `data` is the typed `ProfileList` envelope — inferred straight from the SDK\n * call, never hand-typed. Caching, dedup, and revalidation come from the\n * provider's private QueryClient.\n */\nexport function useProfiles(query?: ListProfilesQuery) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: profileKeys.list(query),\n queryFn: async () =>\n (await profilesList({ client, query })).data,\n },\n queryClient,\n );\n}\n\n/**\n * List profiles with append-style (\"load more\") pagination. Returns\n * `{ items, loadMore, hasMore, isLoading, isLoadingMore, total }`: render\n * `items`, call `loadMore()` while `hasMore`. `pageSize` defaults to 20. Filters\n * match `useProfiles` minus paging, which the hook owns. Shares list-cache\n * invalidation with the other profile hooks.\n */\nexport function useProfilesInfinite(\n filters?: Omit<ListProfilesQuery, 'limit' | 'offset'>,\n options?: { pageSize?: number },\n) {\n const { client } = usePostrun();\n return useInfiniteList<Profile>({\n queryKey: profileKeys.infinite(filters),\n limit: options?.pageSize,\n fetchPage: async ({ limit, offset }) =>\n (await profilesList({ client, query: { ...filters, limit, offset } }))\n .data,\n });\n}\n\n/** Retrieve a single profile by id. Disabled until an id is provided. */\nexport function useProfile(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: profileKeys.detail(id),\n queryFn: async () =>\n (await profilesGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** Create a profile; on success the profile lists are refetched. */\nexport function useCreateProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (body: CreateProfileInput) =>\n (await profilesCreate({ client, body })).data,\n onSuccess: () =>\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() }),\n },\n queryClient,\n );\n}\n\n/** Update a profile by id; on success the lists and that profile are refreshed. */\nexport function useUpdateProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & UpdateProfileInput) =>\n (await profilesUpdate({ client, path: { id }, body })).data,\n onSuccess: (_result, { id }) => {\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() });\n queryClient.invalidateQueries({ queryKey: profileKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n\n/** Delete a profile by id; on success the lists refresh and its detail is dropped. */\nexport function useDeleteProfile() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await profilesDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: profileKeys.lists() });\n queryClient.removeQueries({ queryKey: profileKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","/**\n * Navigate the browser to a URL. The single impure browser call behind the\n * connect redirect, isolated here so it can be mocked in tests and swapped if a\n * host ever needs custom navigation.\n */\nexport function navigate(url: string): void {\n window.location.assign(url);\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n connectionsConnect,\n connectionsDelete,\n connectionsGet,\n connectionsListAccounts,\n connectionsListByProfile,\n connectionsSelect,\n} from '@postrun/js';\nimport type { ConnectablePlatform, SelectAccountInput } from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { connectionKeys } from './keys';\nimport type { ConnectionsFilter } from './keys';\nimport { navigate } from './navigate';\n\nexport interface ConnectParams {\n /** The profile to attach the new connection to. */\n profileId: string;\n /** The platform to connect (X, LinkedIn, Meta, …). */\n platform: ConnectablePlatform;\n}\n\n/**\n * Start a connect flow: mint a session and redirect the browser to the hosted\n * connect URL on postrun.ai, where the full white-labeled OAuth journey runs and\n * the user is returned to the host app. Bare-bones by design — the OAuth UI is\n * ours and hosted, so the host app just calls `mutate({ profileId, platform })`.\n * On return, the new connection appears via `useConnections`.\n */\nexport function useConnect() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ profileId, platform }: ConnectParams) => {\n const session = (\n await connectionsConnect({\n client,\n path: { id: profileId },\n body: { platform },\n })\n ).data;\n navigate(session.hosted_connect_url);\n return session;\n },\n },\n queryClient,\n );\n}\n\n/**\n * List a profile's connected accounts. Pass a `filter` to narrow by `kind`\n * (`posting` = social, `ads`) or `status` — e.g. a composer fetches\n * `{ kind: 'posting' }` to show only the social accounts it can publish to.\n */\nexport function useConnections(profileId: string, filter?: ConnectionsFilter) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.list(profileId, filter),\n queryFn: async () =>\n (\n await connectionsListByProfile({\n client,\n path: { id: profileId },\n query: filter,\n })\n ).data,\n enabled: Boolean(profileId),\n },\n queryClient,\n );\n}\n\n/** Retrieve a single connection by id. */\nexport function useConnection(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.detail(id),\n queryFn: async () =>\n (await connectionsGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** List the accounts discoverable on a pending connection (for selection). */\nexport function useDiscoverableAccounts(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: connectionKeys.accounts(id),\n queryFn: async () =>\n (await connectionsListAccounts({ client, path: { id } })).data,\n enabled: Boolean(id),\n },\n queryClient,\n );\n}\n\n/** Select an account on a pending connection, activating it. */\nexport function useSelectAccount() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & SelectAccountInput) =>\n (await connectionsSelect({ client, path: { id }, body })).data,\n onSuccess: (_result, { id }) => {\n queryClient.invalidateQueries({ queryKey: connectionKeys.lists() });\n queryClient.invalidateQueries({ queryKey: connectionKeys.detail(id) });\n queryClient.invalidateQueries({ queryKey: connectionKeys.accounts(id) });\n },\n },\n queryClient,\n );\n}\n\n/** Disconnect (delete) a connection by id. */\nexport function useDisconnect() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await connectionsDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: connectionKeys.lists() });\n queryClient.removeQueries({ queryKey: connectionKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","import axios, { isAxiosError } from 'axios';\n\nimport type { UploadTarget } from '@postrun/js';\n\n/** A failed direct-to-storage upload, carrying the HTTP status (0 = network). */\nexport class UploadError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'UploadError';\n this.status = status;\n }\n}\n\nexport interface UploadBytesOptions {\n /** Fraction uploaded, 0..1. Called as bytes flow and once with 1 on success. */\n onProgress?: (fraction: number) => void;\n /** Abort the in-flight upload. */\n signal?: AbortSignal;\n}\n\n/**\n * PUT a file's bytes to a signed upload target, with progress and cancellation.\n * axios drives the XHR (the Fetch API can't report upload progress in browsers);\n * retry/poll are composed on top via p-retry/p-wait-for.\n */\nexport async function uploadBytes(\n target: UploadTarget,\n file: Blob,\n options: UploadBytesOptions = {},\n): Promise<void> {\n const { onProgress, signal } = options;\n\n try {\n await axios.request({\n method: target.method,\n url: target.url,\n data: file,\n headers: target.headers,\n signal,\n onUploadProgress: (event) => {\n if (event.total) {\n onProgress?.(event.loaded / event.total);\n }\n },\n });\n onProgress?.(1);\n } catch (error) {\n // A cancellation propagates as-is so callers (and p-retry) treat it as abort.\n if (signal?.aborted) {\n throw error;\n }\n if (isAxiosError(error)) {\n const status = error.response?.status ?? 0;\n throw new UploadError(\n status,\n status ? `Upload failed (HTTP ${status}).` : 'Upload failed: network error.',\n );\n }\n throw error;\n }\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\nimport pRetry, { AbortError } from 'p-retry';\nimport pWaitFor from 'p-wait-for';\nimport { useCallback, useRef, useState } from 'react';\n\nimport {\n mediaCreate,\n mediaDelete,\n mediaGet,\n mediaList,\n mediaUpdate,\n} from '@postrun/js';\nimport type {\n ListMediaQuery,\n MediaKind,\n MediaResource,\n MediaTarget,\n Metadata,\n PostrunClient,\n UpdateMediaInput,\n} from '@postrun/js';\n\nimport { usePostrun } from './context';\nimport { useInfiniteList } from './infinite-list';\nimport { mediaKeys } from './keys';\nimport { UploadError, uploadBytes } from './upload-bytes';\n\nconst DOCUMENT_MIME =\n /^application\\/(pdf|msword|vnd\\.(openxmlformats-officedocument\\.(wordprocessingml\\.document|presentationml\\.presentation)|ms-powerpoint))$/;\n\n/** Map a file's MIME to a media kind so callers pass a File, not metadata. */\nfunction inferKind(contentType: string): MediaKind {\n if (contentType === 'image/gif') return 'gif';\n if (contentType.startsWith('image/')) return 'image';\n if (contentType.startsWith('video/')) return 'video';\n if (DOCUMENT_MIME.test(contentType)) return 'document';\n throw new Error(\n `Could not infer media kind from \"${contentType}\". Pass { kind } explicitly.`,\n );\n}\n\n/** Poll the asset until it settles (ready/failed), respecting cancellation. */\nasync function pollUntilSettled(\n client: PostrunClient,\n id: string,\n signal: AbortSignal,\n): Promise<MediaResource> {\n let latest: MediaResource | undefined;\n await pWaitFor(\n async () => {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n latest = (await mediaGet({ client, path: { id } })).data;\n return latest.status === 'ready' || latest.status === 'failed';\n },\n { interval: 1500, timeout: 300_000 },\n );\n\n if (!latest) {\n throw new Error('Media polling returned no result.');\n }\n return latest;\n}\n\nexport type MediaUploadStatus =\n | 'idle'\n | 'uploading'\n | 'processing'\n | 'ready'\n | 'failed';\n\nexport interface MediaUploadOptions {\n /** Profile that owns the asset. */\n profileId: string;\n /** Platforms to validate + render for (omit to add later via useUpdateMedia). */\n targets?: MediaTarget[];\n /** Override the kind inferred from the file's MIME. */\n kind?: MediaKind;\n /** The file's MIME type. Defaults to `file.type`; required when that's empty. */\n contentType?: string;\n /** Store as-is with zero processing. */\n raw?: boolean;\n altText?: string;\n externalId?: string;\n metadata?: Metadata;\n}\n\n/**\n * Upload a file and get back a platform-validated asset. The hook owns the whole\n * journey: infer kind/content_type from the `File`, create the asset, PUT the\n * bytes with live `progress` + retry, poll until processing settles, and expose\n * `media.per_platform` (per-target status, url, warnings, errors). `cancel()`\n * aborts an in-flight upload.\n */\nexport function useMediaUpload() {\n const { client, queryClient } = usePostrun();\n const [status, setStatus] = useState<MediaUploadStatus>('idle');\n const [progress, setProgress] = useState(0);\n const [media, setMedia] = useState<MediaResource | null>(null);\n const [error, setError] = useState<unknown>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const upload = useCallback(\n async (file: File, options: MediaUploadOptions): Promise<MediaResource> => {\n // Resolve the MIME up front (before touching state) — the API rejects a\n // fabricated `application/octet-stream`, so fail clearly instead.\n const contentType = options.contentType || file.type;\n if (!contentType) {\n throw new Error(\n \"Could not determine the file's content type. Pass { contentType } explicitly.\",\n );\n }\n const kind = options.kind ?? inferKind(contentType);\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('uploading');\n setProgress(0);\n setMedia(null);\n setError(null);\n\n try {\n const created = (\n await mediaCreate({\n client,\n body: {\n profile_id: options.profileId,\n kind,\n content_type: contentType,\n targets: options.targets,\n raw: options.raw,\n alt_text: options.altText,\n external_id: options.externalId,\n metadata: options.metadata,\n },\n })\n ).data;\n\n if (created.upload) {\n const target = created.upload;\n await pRetry(\n async () => {\n try {\n await uploadBytes(target, file, {\n onProgress: setProgress,\n signal: controller.signal,\n });\n } catch (uploadError) {\n // A client error (e.g. an expired signed URL) won't fix on retry.\n if (\n uploadError instanceof UploadError &&\n uploadError.status >= 400 &&\n uploadError.status < 500\n ) {\n throw new AbortError(uploadError);\n }\n throw uploadError;\n }\n },\n { retries: 3, signal: controller.signal },\n );\n }\n\n setStatus('processing');\n const settled = await pollUntilSettled(\n client,\n created.id,\n controller.signal,\n );\n queryClient.setQueryData(mediaKeys.detail(created.id), settled);\n void queryClient.invalidateQueries({ queryKey: mediaKeys.lists() });\n setMedia(settled);\n setStatus(settled.status === 'failed' ? 'failed' : 'ready');\n return settled;\n } catch (caught) {\n setError(caught);\n setStatus('failed');\n throw caught;\n } finally {\n if (abortRef.current === controller) {\n abortRef.current = null;\n }\n }\n },\n [client, queryClient],\n );\n\n const cancel = useCallback(() => abortRef.current?.abort(), []);\n const reset = useCallback(() => {\n setStatus('idle');\n setProgress(0);\n setMedia(null);\n setError(null);\n }, []);\n\n return { upload, cancel, reset, status, progress, media, error };\n}\n\n/** Retrieve a media asset; auto-polls while it is still uploading/processing. */\nexport function useMedia(id: string) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: mediaKeys.detail(id),\n queryFn: async () =>\n (await mediaGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n refetchInterval: (query) => {\n const current = query.state.data;\n return current?.status === 'uploading' || current?.status === 'processing'\n ? 2000\n : false;\n },\n },\n queryClient,\n );\n}\n\n/**\n * List media assets under the account, newest first. Filter by `profile_id`,\n * `status`, `kind`, your own `external_id`, or `metadata` (exact-match\n * containment), with offset `limit`/`offset` pagination. Returns one page; use\n * `useMediaInfinite` for a load-more feed.\n */\nexport function useMediaList(query?: ListMediaQuery) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: mediaKeys.list(query),\n queryFn: async () => (await mediaList({ client, query })).data,\n },\n queryClient,\n );\n}\n\n/**\n * Load-more / infinite-scroll view over the media list — same filters as\n * `useMediaList` minus pagination, which the helper drives. Returns\n * `{ items, total, loadMore, hasMore, … }`.\n */\nexport function useMediaInfinite(\n filters?: Omit<ListMediaQuery, 'limit' | 'offset'>,\n options?: { pageSize?: number },\n) {\n const { client } = usePostrun();\n return useInfiniteList<MediaResource>({\n queryKey: mediaKeys.infinite(filters),\n limit: options?.pageSize,\n fetchPage: async ({ limit, offset }) =>\n (await mediaList({ client, query: { ...filters, limit, offset } })).data,\n });\n}\n\n/** Update a media asset: alt text / metadata / external_id, or extend targets. */\nexport function useUpdateMedia() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async ({ id, ...body }: { id: string } & UpdateMediaInput) =>\n (await mediaUpdate({ client, path: { id }, body })).data,\n onSuccess: (result, { id }) => {\n queryClient.setQueryData(mediaKeys.detail(id), result);\n void queryClient.invalidateQueries({ queryKey: mediaKeys.lists() });\n },\n },\n queryClient,\n );\n}\n\n/** Delete a media asset and its stored renditions. */\nexport function useDeleteMedia() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await mediaDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.removeQueries({ queryKey: mediaKeys.detail(id) });\n void queryClient.invalidateQueries({ queryKey: mediaKeys.lists() });\n },\n },\n queryClient,\n );\n}\n","import { useMutation, useQuery } from '@tanstack/react-query';\n\nimport {\n buildCreatePost,\n isPostPlatform,\n postsCreate,\n postsDelete,\n postsGet,\n postsList,\n postsUpdate,\n} from '@postrun/js';\nimport type {\n ComposePostInput,\n ListPostsQuery,\n Post,\n UpdatePostInput,\n} from '@postrun/js';\n\n/**\n * The calendar/queue filter surface — a date window over `schedule_at` plus a\n * derived-status multi-select, scoped to an optional profile. Picked straight\n * from the generated `ListPostsQuery` contract (no hand-typed shapes), so it\n * can never drift from the API. Pagination still rides through via `usePosts`.\n */\nexport type CalendarFilters = Pick<\n ListPostsQuery,\n 'profile_id' | 'scheduled_after' | 'scheduled_before' | 'status'\n>;\n\nimport { useConnections } from './connections';\nimport { usePostrun } from './context';\nimport { useInfiniteList } from './infinite-list';\nimport { postKeys } from './keys';\n\n/**\n * A post's status as it appears on the RESPONSE (not the list `status` filter) —\n * the value a live poll actually inspects. Sourced from `Post['status']` so the\n * predicate below is type-correct against `query.state.data?.status`, and a\n * future contract change to the status set surfaces at compile time here.\n */\ntype PostResponseStatus = Post['status'];\n\n/**\n * Statuses that are still moving on their own and warrant polling: `scheduled`\n * (fires at its time with no user action → must be caught transitioning) and\n * `publishing` (mid-flight by definition). Everything else is terminal and stops\n * the poll: `published` / `failed` (end states), `partially_published` (no\n * further automatic movement), and `draft` (only an explicit update — which\n * already invalidates lists — moves it). Modelling in-flight as the small set\n * means any future status defaults to \"terminal/stop\" — the safe, no-runaway\n * default.\n */\nconst IN_FLIGHT: ReadonlySet<PostResponseStatus> = new Set([\n 'scheduled',\n 'publishing',\n]);\n\nconst isLivePostStatus = (status: PostResponseStatus): boolean =>\n IN_FLIGHT.has(status);\n\n/** Per-hook live-poll control: live is on by default; `{ live: false }` opts out. */\nexport interface LiveOptions {\n /** Auto-poll while a post is in-flight (default `true`). Set `false` for one-shot. */\n live?: boolean;\n}\n\n/**\n * List posts — the calendar/queue data, filtered (profile_id / external_id /\n * metadata) and paginated. `data` is the typed `PostList` envelope, with each\n * post's derived status (draft / scheduled / publishing / published / failed).\n */\nexport function usePosts(query?: ListPostsQuery) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.list(query),\n queryFn: async () =>\n (await postsList({ client, query })).data,\n },\n queryClient,\n );\n}\n\n/**\n * List posts with append-style (\"load more\") pagination — the calendar/queue\n * feed. Returns `{ items, loadMore, hasMore, isLoading, isLoadingMore, total }`:\n * render `items`, call `loadMore()` (on a button or scroll end) while `hasMore`.\n * `pageSize` defaults to 20. Filters are the same as `usePosts` minus paging,\n * which the hook owns. Shares list-cache invalidation with the other post hooks,\n * so a create/update/delete refreshes it automatically.\n */\nexport function usePostsInfinite(\n filters?: Omit<ListPostsQuery, 'limit' | 'offset'>,\n options?: { pageSize?: number },\n) {\n const { client } = usePostrun();\n return useInfiniteList<Post>({\n queryKey: postKeys.infinite(filters),\n limit: options?.pageSize,\n fetchPage: async ({ limit, offset }) =>\n (await postsList({ client, query: { ...filters, limit, offset } })).data,\n });\n}\n\n/**\n * Calendar/queue view — list posts in a `schedule_at` date window, optionally\n * narrowed to a profile and to one or more derived statuses (e.g. only\n * `scheduled` + `failed`). Forwards the date-range + multi-status filters (and\n * any `limit`/`offset`) to the generated `postsList` and returns the same typed\n * `PostList` envelope. It shares the `postKeys.list(filters)` cache identity with\n * `usePosts` but owns its own self-terminating poll: while ANY post in the\n * window is in-flight it refetches (5s — a list is heavier than one detail), and\n * stops once every item is terminal (or the window is empty). `live` is a\n * separate option, never mixed into the API filter object; default-on, opt out\n * with `{ live: false }`.\n */\nexport function useCalendar(\n filters?: CalendarFilters & Pick<ListPostsQuery, 'limit' | 'offset'>,\n options?: LiveOptions,\n) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.list(filters),\n queryFn: async () => (await postsList({ client, query: filters })).data,\n refetchInterval: (query) => {\n if (options?.live === false) return false;\n const posts = query.state.data?.data ?? [];\n return posts.some((post) => isLivePostStatus(post.status)) ? 5000 : false;\n },\n },\n queryClient,\n );\n}\n\n/**\n * Retrieve a single post by id (its variants, schedule, and derived status).\n * Auto-polls (2s) while the post is in-flight (`scheduled` / `publishing`) and\n * stops once it reaches a terminal status — so a scheduled post visibly\n * transitions with no manual refetch. `live` is on by default; pass\n * `{ live: false }` to force a one-shot.\n */\nexport function usePost(id: string, options?: LiveOptions) {\n const { client, queryClient } = usePostrun();\n return useQuery(\n {\n queryKey: postKeys.detail(id),\n queryFn: async () =>\n (await postsGet({ client, path: { id } })).data,\n enabled: Boolean(id),\n refetchInterval: (query) => {\n if (options?.live === false) return false;\n const status = query.state.data?.status;\n return status && isLivePostStatus(status) ? 2000 : false;\n },\n },\n queryClient,\n );\n}\n\n/**\n * Compose and create a post. Resolves the profile's connections, builds the full\n * variant set from `{ content, channels }` (per the `buildCreatePost` rules), and\n * sends it — the customer never assembles variants or passes a `connection_id`.\n * `connectedChannels` is the set of posting platforms this profile can reach.\n */\nexport function useCreatePost(profileId: string) {\n const { client, queryClient } = usePostrun();\n const connections = useConnections(profileId);\n const connected = connections.data?.data ?? [];\n\n const mutation = useMutation(\n {\n mutationFn: async (input: Omit<ComposePostInput, 'profileId'>) =>\n (\n await postsCreate({\n client,\n body: buildCreatePost({ ...input, profileId }, connected),\n })\n ).data,\n onSuccess: () =>\n queryClient.invalidateQueries({ queryKey: postKeys.lists() }),\n },\n queryClient,\n );\n\n return {\n create: mutation.mutateAsync,\n isPending: mutation.isPending,\n error: mutation.error,\n data: mutation.data,\n reset: mutation.reset,\n // The profile's connections must load before `create` can resolve a channel;\n // gate on this so a call during loading isn't mislabeled \"not connected\".\n isReady: connections.isSuccess,\n connectedChannels: connected\n .map((connection) => connection.platform)\n .filter(isPostPlatform),\n };\n}\n\n/**\n * Update a post by id. Pass a light edit directly (`{ schedule_at }`,\n * `{ tags }`, …) or a rebuilt body from `buildUpdatePost(input, connections)`\n * for content edits (the API's PATCH replaces the variant set).\n */\nexport function useUpdatePost(postId: string) {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (body: UpdatePostInput) =>\n (await postsUpdate({ client, path: { id: postId }, body })).data,\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: postKeys.lists() });\n queryClient.setQueryData(postKeys.detail(postId), result);\n },\n },\n queryClient,\n );\n}\n\n/** Delete a post by id; on success the lists refresh and its detail is dropped. */\nexport function useDeletePost() {\n const { client, queryClient } = usePostrun();\n return useMutation(\n {\n mutationFn: async (id: string) =>\n (await postsDelete({ client, path: { id } })).data,\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: postKeys.lists() });\n queryClient.removeQueries({ queryKey: postKeys.detail(id) });\n },\n },\n queryClient,\n );\n}\n","'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\n\nimport type { PreviewMedia, ResolvedMedia } from './types';\n\n/**\n * Shared media resolution for every platform preview. URL-backed items resolve\n * SYNCHRONOUSLY (the common, processed-asset path — no first-paint flash);\n * compose-time `File` items get an object URL minted in an effect and revoked on\n * change/unmount. Keyed on a content signature, so the resolved array is stable\n * across parent re-renders that don't change the media — the heavy work (object\n * URLs) never churns and downstream mapping stays memoized. Alt text falls back\n * to the variant media's `alt_text_override`.\n */\n\n/** Per-item alt-text fallback source (the variant's media refs). */\nexport type AltFallbacks =\n | readonly { alt_text_override?: string | null }[]\n | undefined;\n\nfunction fileKey(file: File | undefined): string {\n return file ? `${file.name}:${file.size}:${file.lastModified}` : '';\n}\n\n/** A content signature so object-URL work only re-runs when the media actually\n * changes — not on every parent re-render that passes a new array. */\nexport function mediaSignature(\n media: readonly PreviewMedia[] | undefined,\n): string {\n return (media ?? [])\n .map((item) => {\n const source = item.url ?? fileKey(item.file);\n const size = `${item.width ?? ''}x${item.height ?? ''}`;\n return `${item.kind}|${source}|${item.posterUrl ?? ''}|${size}|${item.alt ?? ''}`;\n })\n .join('§');\n}\n\n/** Stable string of the per-item alt fallbacks, for memo keying. */\nexport function altSignatureOf(media: AltFallbacks): string {\n return (media ?? []).map((m) => m?.alt_text_override ?? '').join('§');\n}\n\nexport function useResolvedMedia(\n media: readonly PreviewMedia[] | undefined,\n altFallbacks: AltFallbacks,\n altSignature: string,\n): ResolvedMedia[] {\n const signature = mediaSignature(media);\n const [objectUrls, setObjectUrls] = useState<Record<number, string>>({});\n\n useEffect(() => {\n const created: string[] = [];\n const next: Record<number, string> = {};\n (media ?? []).forEach((item, index) => {\n if (!item.url && item.file) {\n const url = URL.createObjectURL(item.file);\n created.push(url);\n next[index] = url;\n }\n });\n setObjectUrls(next);\n return () => {\n for (const url of created) {\n URL.revokeObjectURL(url);\n }\n };\n // `signature` captures every File identity that needs an object URL.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature]);\n\n return useMemo(\n () =>\n (media ?? []).flatMap((item, index): ResolvedMedia[] => {\n const src = item.url ?? objectUrls[index];\n if (!src) {\n return [];\n }\n return [\n {\n kind: item.kind,\n src,\n width: item.width,\n height: item.height,\n alt: item.alt ?? altFallbacks?.[index]?.alt_text_override ?? undefined,\n posterSrc: item.posterUrl,\n },\n ];\n }),\n // `signature` + `altSignature` capture the content; `objectUrls` flips once\n // File blobs resolve. Referencing `media`/`altFallbacks` directly is safe.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [signature, altSignature, objectUrls],\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { IconType } from 'react-icons';\nimport {\n FiBarChart2,\n FiHeart,\n FiMessageCircle,\n FiRepeat,\n FiShare,\n} from 'react-icons/fi';\n\n/**\n * A static, honest action row for the X preview: reply, repost, like, views, and\n * share — real Feather icons (via react-icons), NO fabricated counts and no\n * outbound links (a draft hasn't been engaged with). We render our own row rather\n * than react-tweet's `TweetActions` because that one prints a `0` like-count,\n * which would be a lie on an unpublished post.\n *\n * Color inherits react-tweet's CSS variable, so it matches the card in light and\n * dark and restyles with the same variable the rest of the card uses.\n */\n\nconst ROW: CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n maxWidth: 425,\n marginTop: 12,\n color: 'var(--tweet-color-gray-secondary, #536471)',\n};\n\nconst ACTIONS: { label: string; Icon: IconType }[] = [\n { label: 'Reply', Icon: FiMessageCircle },\n { label: 'Repost', Icon: FiRepeat },\n { label: 'Like', Icon: FiHeart },\n { label: 'Views', Icon: FiBarChart2 },\n { label: 'Share', Icon: FiShare },\n];\n\nexport function XPreviewActions() {\n return (\n <div style={ROW}>\n {ACTIONS.map(({ label, Icon }) => (\n <Icon key={label} size={18} aria-label={label} role=\"img\" />\n ))}\n </div>\n );\n}\n","import twitterText from 'twitter-text';\nimport type { TweetEntities } from 'react-tweet/api';\n\n// twitter-text's ESM entry exposes a single default object (no named exports),\n// so a default import is the only form that resolves across bundlers — named\n// imports compile under @types but break in esbuild/rollup at the consumer.\nconst {\n extractCashtagsWithIndices,\n extractHashtagsWithIndices,\n extractMentionsWithIndices,\n extractUrlsWithIndices,\n modifyIndicesFromUTF16ToUnicode,\n} = twitterText;\n\n/**\n * Extract the X text entities (hashtags, @mentions, URLs, $cashtags) from a post\n * body, in the shape `react-tweet`'s `enrichTweet` consumes to rebuild the rich\n * body. Indices come straight from `twitter-text` — the reference implementation\n * X itself uses — so highlighting matches the real platform exactly (Unicode,\n * punctuation boundaries, and all). We never hand-roll the parsing.\n *\n * Fields X's syndication payload carries that a compose-time preview cannot know\n * (a mention's numeric `id_str` / display `name`) are filled with honest stand-ins\n * (`screen_name`), which is all the renderer needs to draw the entity.\n */\nexport function extractEntities(text: string): TweetEntities {\n const hashtags = extractHashtagsWithIndices(text);\n const mentions = extractMentionsWithIndices(text);\n const urls = extractUrlsWithIndices(text);\n const cashtags = extractCashtagsWithIndices(text);\n\n // twitter-text's regex indices are UTF-16; react-tweet slices `Array.from(text)`\n // (codepoint-aware), so convert in place — otherwise any astral char (emoji)\n // before an entity shifts every later highlight. Converting one combined array\n // keeps the per-list references in sync (the helper mutates `.indices`).\n modifyIndicesFromUTF16ToUnicode(text, [\n ...hashtags,\n ...mentions,\n ...urls,\n ...cashtags,\n ]);\n\n return {\n hashtags: hashtags.map((h) => ({ text: h.hashtag, indices: h.indices })),\n user_mentions: mentions.map((m) => ({\n id_str: '',\n name: m.screenName,\n screen_name: m.screenName,\n indices: m.indices,\n })),\n urls: urls.map((u) => ({\n display_url: u.url,\n expanded_url: u.url,\n url: u.url,\n indices: u.indices,\n })),\n symbols: cashtags.map((c) => ({ text: c.cashtag, indices: c.indices })),\n };\n}\n","import type { XPostVariant } from '@postrun/js';\nimport type {\n MediaAnimatedGif,\n MediaDetails,\n MediaPhoto,\n MediaVideo,\n QuotedTweet,\n Tweet,\n TweetUser,\n VideoInfo,\n} from 'react-tweet/api';\n\nimport type { ResolvedMedia, XPreviewAuthor } from '../types';\nimport { extractEntities } from './entities';\n\n/**\n * Maps a Postrun X variant (+ the customer-supplied author/media) into the\n * `Tweet` object `react-tweet` renders. This is the whole \"schema → exact X\n * preview\" brain: a PURE function, no DOM, no network, no `File` handling (the\n * component resolves pixels to URLs before calling this). Every field\n * `react-tweet` reads is filled with a real value — no casts — and engagement\n * metrics are honest zeros (a draft has no likes).\n */\n\n/** Quoted-card content with media already resolved. */\nexport interface ResolvedQuotedTweet {\n author: XPreviewAuthor;\n body?: string;\n media?: ResolvedMedia[];\n}\n\nexport interface ToTweetInput {\n variant: XPostVariant;\n author: XPreviewAuthor;\n media?: ResolvedMedia[];\n quotedTweet?: ResolvedQuotedTweet;\n /** The replied-to account's handle (our schema only stores the parent id). */\n replyToHandle?: string;\n}\n\n/** Neutral placeholder avatar (a grey circle) for when no avatar is supplied —\n * keeps the header from showing a broken image. */\nconst PLACEHOLDER_AVATAR =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\">' +\n '<circle cx=\"24\" cy=\"24\" r=\"24\" fill=\"#cfd9de\"/></svg>',\n );\n\n/** Fallback pixel dimensions when the customer doesn't know the asset's size —\n * a 3:2 frame keeps react-tweet's aspect-ratio math from dividing by zero. */\nconst FALLBACK_WIDTH = 1200;\nconst FALLBACK_HEIGHT = 800;\n\n/** Length in Unicode codepoints (astral-aware), matching how react-tweet slices\n * the body via `Array.from(text)`. */\nfunction codepointLength(text: string): number {\n return Array.from(text).length;\n}\n\nfunction buildUser(author: XPreviewAuthor): TweetUser {\n const verified = author.verified ?? false;\n return {\n id_str: '',\n name: author.name,\n profile_image_url_https: author.avatarUrl ?? PLACEHOLDER_AVATAR,\n profile_image_shape: 'Circle',\n screen_name: author.handle,\n verified: false,\n is_blue_verified: verified,\n };\n}\n\n/** The fields shared by every media kind, contextually typed (derived from\n * `MediaPhoto`) so tuple/literal fields infer correctly without a cast. */\nfunction mediaBase(\n src: string,\n width?: number,\n height?: number,\n): Omit<MediaPhoto, 'type' | 'ext_alt_text'> {\n const w = width ?? FALLBACK_WIDTH;\n const h = height ?? FALLBACK_HEIGHT;\n const size = { h, w, resize: 'fit' };\n return {\n display_url: '',\n expanded_url: '',\n ext_media_availability: { status: 'available' },\n ext_media_color: { palette: [] },\n indices: [0, 0],\n media_url_https: src,\n original_info: { height: h, width: w, focus_rects: [] },\n sizes: { large: size, medium: size, small: size, thumb: size },\n url: src,\n };\n}\n\nfunction buildPhoto(media: ResolvedMedia): MediaPhoto {\n return {\n ...mediaBase(media.src, media.width, media.height),\n type: 'photo',\n ext_alt_text: media.alt,\n };\n}\n\nfunction buildVideo(media: ResolvedMedia): MediaVideo | MediaAnimatedGif {\n const poster = media.posterSrc ?? media.src;\n const videoInfo: VideoInfo = {\n aspect_ratio: [media.width ?? 16, media.height ?? 9],\n variants: [{ content_type: 'video/mp4', url: media.src }],\n };\n const base = mediaBase(poster, media.width, media.height);\n return media.kind === 'gif'\n ? { ...base, type: 'animated_gif', video_info: videoInfo }\n : { ...base, type: 'video', video_info: videoInfo };\n}\n\nfunction buildMediaDetails(media: readonly ResolvedMedia[]): MediaDetails[] {\n return media.map((item) =>\n item.kind === 'image' ? buildPhoto(item) : buildVideo(item),\n );\n}\n\n/** The static, draft-honest scaffolding every synthesized tweet shares. */\nfunction tweetScaffold(): Pick<\n Tweet,\n | 'lang'\n | 'created_at'\n | 'edit_control'\n | 'isEdited'\n | 'isStaleEdit'\n | 'favorite_count'\n | 'conversation_count'\n | 'news_action_type'\n> {\n return {\n lang: 'en',\n created_at: '',\n edit_control: {\n edit_tweet_ids: [],\n editable_until_msecs: '0',\n is_edit_eligible: false,\n edits_remaining: '0',\n },\n isEdited: false,\n isStaleEdit: false,\n favorite_count: 0,\n conversation_count: 0,\n news_action_type: 'conversation',\n };\n}\n\nfunction buildQuoted(\n quote: ResolvedQuotedTweet | undefined,\n hasQuoteId: boolean,\n): QuotedTweet | undefined {\n if (!quote && !hasQuoteId) {\n return undefined;\n }\n\n const author = quote?.author ?? { name: 'Quoted post', handle: '' };\n const body = quote?.body ?? '';\n const media = quote?.media ?? [];\n\n return {\n lang: 'en',\n created_at: '',\n display_text_range: [0, codepointLength(body)],\n entities: extractEntities(body),\n id_str: '',\n text: body,\n user: buildUser(author),\n edit_control: {\n edit_tweet_ids: [],\n editable_until_msecs: '0',\n is_edit_eligible: false,\n edits_remaining: '0',\n },\n isEdited: false,\n isStaleEdit: false,\n reply_count: 0,\n retweet_count: 0,\n favorite_count: 0,\n self_thread: { id_str: '' },\n ...(media.length > 0 ? { mediaDetails: buildMediaDetails(media) } : {}),\n };\n}\n\nexport function toTweet(input: ToTweetInput): Tweet {\n const { variant, author, media = [], quotedTweet, replyToHandle } = input;\n const text = variant.body ?? '';\n const mediaDetails = buildMediaDetails(media);\n const quoted = buildQuoted(\n quotedTweet,\n variant.settings?.quote_tweet_id !== undefined,\n );\n const reply = variant.settings?.reply;\n\n return {\n __typename: 'Tweet',\n ...tweetScaffold(),\n // Codepoint length, not `text.length` (UTF-16) — react-tweet renders the\n // body off `Array.from(text)`, so emoji must not shift the range.\n display_text_range: [0, codepointLength(text)],\n entities: extractEntities(text),\n id_str: '',\n text,\n user: buildUser(author),\n ...(mediaDetails.length > 0 ? { mediaDetails } : {}),\n ...(quoted ? { quoted_tweet: quoted } : {}),\n // Both the handle AND the parent id are needed: enrichTweet builds the\n // reply link as `…/${screen_name}/status/${status_id_str}`, so omitting the\n // id yields a `/status/undefined` href.\n ...(reply && replyToHandle\n ? {\n in_reply_to_screen_name: replyToHandle,\n in_reply_to_status_id_str: reply.in_reply_to_tweet_id,\n }\n : {}),\n };\n}\n","'use client';\n\nimport type { XPostVariant } from '@postrun/js';\nimport { memo, useMemo } from 'react';\nimport type { CSSProperties } from 'react';\nimport {\n QuotedTweet,\n TweetBody,\n TweetContainer,\n TweetHeader,\n TweetInReplyTo,\n TweetMedia,\n type TwitterComponents,\n enrichTweet,\n} from 'react-tweet';\n\nimport type {\n PreviewMedia,\n XPreviewAuthor,\n XPreviewQuotedTweet,\n} from '../types';\nimport { altSignatureOf, useResolvedMedia } from '../use-resolved-media';\nimport { XPreviewActions } from './XPreviewActions';\nimport { toTweet } from './to-tweet';\n\nexport interface XPostPreviewProps {\n /** The X variant from our schema — the content source, untouched. */\n variant: XPostVariant;\n /** Author identity (not stored on our connection — supplied by you). */\n author: XPreviewAuthor;\n /** Resolved media pixels (URLs or compose-time File blobs). */\n media?: PreviewMedia[];\n /** Content for the quoted card when `settings.quote_tweet_id` is set. */\n quotedTweet?: XPreviewQuotedTweet;\n /** The replied-to account's handle (our schema only stores the parent id). */\n replyToHandle?: string;\n /** Color scheme. `auto` (default) inherits the host's theme. */\n theme?: 'light' | 'dark' | 'auto';\n /** Show the static action row (icons, no counts). Default true. */\n showActions?: boolean;\n /** Class applied to the wrapper — your hook for sizing, shadows, etc. */\n className?: string;\n /** Inline styles on the wrapper — e.g. react-tweet CSS variables\n * (`{ ['--tweet-container-margin']: '0' }`). */\n style?: CSSProperties;\n /** Override react-tweet's internal pieces (e.g. `next/image` avatars). */\n components?: TwitterComponents;\n}\n\n/**\n * A faithful, pixel-accurate preview of how an X post will look once published,\n * rendered straight from a Postrun X variant. Built on `react-tweet` (the same\n * card X itself ships), so you write zero card UI — pass the schema, render the\n * preview. Fully customizable: restyle via `className`/`style` (CSS variables)\n * or swap internals via `components`; theme light/dark/auto.\n */\nfunction XPostPreviewImpl({\n variant,\n author,\n media,\n quotedTweet,\n replyToHandle,\n theme = 'auto',\n showActions = true,\n className,\n style,\n components,\n}: XPostPreviewProps) {\n const resolvedMedia = useResolvedMedia(\n media,\n variant.media,\n altSignatureOf(variant.media),\n );\n const resolvedQuotedMedia = useResolvedMedia(quotedTweet?.media, undefined, '');\n\n const tweet = useMemo(() => {\n const resolvedQuoted = quotedTweet\n ? {\n author: quotedTweet.author,\n body: quotedTweet.body,\n media: resolvedQuotedMedia,\n }\n : undefined;\n\n return enrichTweet(\n toTweet({\n variant,\n author,\n media: resolvedMedia,\n quotedTweet: resolvedQuoted,\n replyToHandle,\n }),\n );\n }, [\n variant,\n author,\n resolvedMedia,\n quotedTweet,\n resolvedQuotedMedia,\n replyToHandle,\n ]);\n\n return (\n <div\n data-theme={theme === 'auto' ? undefined : theme}\n className={className}\n style={style}\n >\n <TweetContainer>\n <TweetHeader tweet={tweet} components={components} />\n {tweet.in_reply_to_screen_name ? <TweetInReplyTo tweet={tweet} /> : null}\n <TweetBody tweet={tweet} />\n {tweet.mediaDetails?.length ? (\n <TweetMedia tweet={tweet} components={components} />\n ) : null}\n {tweet.quoted_tweet ? <QuotedTweet tweet={tweet.quoted_tweet} /> : null}\n {showActions ? <XPreviewActions /> : null}\n </TweetContainer>\n </div>\n );\n}\n\n/** Memoized: re-renders only when its props change (the resolved-media hook\n * already absorbs unstable media arrays). */\nexport const XPostPreview = memo(XPostPreviewImpl);\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * LinkedIn preview theming. Unlike the X preview (which inherits react-tweet's\n * CSS), we own the LinkedIn card, so we expose a small set of CSS custom\n * properties on the wrapper. The resolved palette sets their default values;\n * a customer can override any of them via `style`/`className`. Components read\n * `var(--pr-li-*)`, so restyling needs no fork.\n */\n\nexport type LinkedInTheme = 'light' | 'dark' | 'auto';\n\nexport const LI_VAR = {\n bg: '--pr-li-bg',\n text: '--pr-li-text',\n muted: '--pr-li-muted',\n border: '--pr-li-border',\n accent: '--pr-li-accent',\n};\n\ninterface Palette {\n bg: string;\n text: string;\n muted: string;\n border: string;\n accent: string;\n}\n\nconst LIGHT: Palette = {\n bg: '#ffffff',\n text: 'rgba(0,0,0,0.9)',\n muted: 'rgba(0,0,0,0.6)',\n border: 'rgba(0,0,0,0.08)',\n accent: 'rgb(10,102,194)',\n};\n\nconst DARK: Palette = {\n bg: '#1b1f23',\n text: 'rgba(255,255,255,0.9)',\n muted: 'rgba(255,255,255,0.6)',\n border: 'rgba(255,255,255,0.15)',\n accent: 'rgb(112,181,249)',\n};\n\n/** A CSS `var(...)` reference to one of the LinkedIn theme variables. */\nexport function varRef(name: string): string {\n return `var(${name})`;\n}\n\n/** The CSS custom-property declarations for a resolved scheme. Typed as a plain\n * string record (React's `CSSProperties` doesn't model `--custom` keys); it is\n * spread into the card's `style`, where React forwards it to the DOM. */\nexport function paletteVars(dark: boolean): Record<string, string> {\n const p = dark ? DARK : LIGHT;\n return {\n '--pr-li-bg': p.bg,\n '--pr-li-text': p.text,\n '--pr-li-muted': p.muted,\n '--pr-li-border': p.border,\n '--pr-li-accent': p.accent,\n };\n}\n\n/** Track the OS color scheme for `theme=\"auto\"`. Starts light (SSR-safe, no\n * hydration mismatch) and updates after mount. */\nexport function usePrefersDark(): boolean {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return;\n }\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n setDark(mq.matches);\n const onChange = (event: MediaQueryListEvent) => setDark(event.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n\n return dark;\n}\n\n/** Resolve whether the card should render dark for a given theme prop. */\nexport function useIsDark(theme: LinkedInTheme): boolean {\n const prefersDark = usePrefersDark();\n if (theme === 'auto') {\n return prefersDark;\n }\n return theme === 'dark';\n}\n","import type { CSSProperties } from 'react';\nimport type { IconType } from 'react-icons';\nimport { FiMessageSquare, FiRepeat, FiSend, FiThumbsUp } from 'react-icons/fi';\n\nimport { LI_VAR, varRef } from './theme';\n\n/**\n * The static LinkedIn action bar — Like / Comment / Repost / Send. Real Feather\n * icons (via react-icons) + labels, no fabricated reaction counts (a draft has\n * none). Honest, like the X preview's footer.\n */\n\nconst ROW: CSSProperties = {\n display: 'flex',\n justifyContent: 'space-around',\n borderTop: `1px solid ${varRef(LI_VAR.border)}`,\n marginTop: 8,\n padding: '4px 8px',\n};\n\nconst ITEM: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px',\n color: varRef(LI_VAR.muted),\n fontSize: 14,\n fontWeight: 600,\n};\n\nconst ACTIONS: { label: string; Icon: IconType }[] = [\n { label: 'Like', Icon: FiThumbsUp },\n { label: 'Comment', Icon: FiMessageSquare },\n { label: 'Repost', Icon: FiRepeat },\n { label: 'Send', Icon: FiSend },\n];\n\nexport function EngagementBar() {\n return (\n <div style={ROW}>\n {ACTIONS.map(({ label, Icon }) => (\n <span key={label} style={ITEM}>\n <Icon size={20} aria-hidden />\n {label}\n </span>\n ))}\n </div>\n );\n}\n","import { FiGlobe, FiUsers } from 'react-icons/fi';\nimport { LuBadgeCheck } from 'react-icons/lu';\n\nimport type { LinkedInPreviewAuthor } from '../types';\nimport { LI_VAR, varRef } from './theme';\n\n/**\n * The LinkedIn post header: avatar, actor name (+ optional verified badge),\n * one-line headline, then a muted row with a relative time and the audience icon\n * (globe = public, people = connections-only). Real Feather/Lucide icons via\n * react-icons — no hand-drawn paths.\n */\n\nexport type LinkedInVisibility = 'PUBLIC' | 'CONNECTIONS';\n\nconst PLACEHOLDER_AVATAR =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\">' +\n '<circle cx=\"24\" cy=\"24\" r=\"24\" fill=\"#9aa6b2\"/></svg>',\n );\n\nexport interface HeaderProps {\n author: LinkedInPreviewAuthor;\n visibility: LinkedInVisibility;\n /** Relative time label, e.g. \"Now\". */\n time?: string;\n}\n\nexport function Header({ author, visibility, time = 'Now' }: HeaderProps) {\n return (\n <div style={{ display: 'flex', gap: 8, padding: '12px 16px 0' }}>\n <img\n src={author.avatarUrl ?? PLACEHOLDER_AVATAR}\n alt=\"\"\n width={48}\n height={48}\n style={{ width: 48, height: 48, borderRadius: '50%', objectFit: 'cover', flex: '0 0 auto' }}\n />\n <div style={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n fontSize: 14,\n fontWeight: 600,\n color: varRef(LI_VAR.text),\n lineHeight: 1.3,\n }}\n >\n {author.name}\n {author.verified ? (\n <LuBadgeCheck\n size={16}\n aria-label=\"Verified\"\n role=\"img\"\n style={{ color: varRef(LI_VAR.accent), marginLeft: 3, flex: '0 0 auto' }}\n />\n ) : null}\n </span>\n {author.headline ? (\n <span style={{ fontSize: 12, color: varRef(LI_VAR.muted), lineHeight: 1.3 }}>\n {author.headline}\n </span>\n ) : null}\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 12,\n color: varRef(LI_VAR.muted),\n lineHeight: 1.3,\n }}\n >\n {time} •{' '}\n {visibility === 'PUBLIC' ? (\n <FiGlobe size={13} aria-label=\"Public\" role=\"img\" />\n ) : (\n <FiUsers size={13} aria-label=\"Connections\" role=\"img\" />\n )}\n </span>\n </div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\n\nimport type { ResolvedMedia } from '../types';\n\n/**\n * LinkedIn's image layout: a single full-bleed image, or the 2/3/4 mosaic with a\n * \"+N\" overlay on the fourth tile when there are more than four. Edge-to-edge,\n * 2px gutters — matching the in-feed look.\n */\n\nconst MAX_TILES = 4;\nconst MOSAIC_HEIGHT = 272;\n\nconst GRID_BASE: CSSProperties = {\n display: 'grid',\n gap: 2,\n height: MOSAIC_HEIGHT,\n overflow: 'hidden',\n};\n\n/** Grid template for a given visible-tile count (2, 3 or 4). */\nfunction gridStyle(tiles: number): CSSProperties {\n if (tiles === 2) {\n return { ...GRID_BASE, gridTemplateColumns: '1fr 1fr' };\n }\n if (tiles === 3) {\n // One tall image on the left, two stacked on the right.\n return {\n ...GRID_BASE,\n gridTemplateColumns: '1fr 1fr',\n gridTemplateRows: '1fr 1fr',\n gridTemplateAreas: '\"a b\" \"a c\"',\n };\n }\n return {\n ...GRID_BASE,\n gridTemplateColumns: '1fr 1fr',\n gridTemplateRows: '1fr 1fr',\n };\n}\n\nconst IMG_STYLE: CSSProperties = {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n};\n\nconst AREAS = ['a', 'b', 'c'];\n\nfunction Tile({\n item,\n area,\n overlay,\n}: {\n item: ResolvedMedia;\n area?: string;\n overlay?: number;\n}) {\n return (\n <div style={{ position: 'relative', gridArea: area, overflow: 'hidden' }}>\n <img src={item.src} alt={item.alt ?? ''} style={IMG_STYLE} />\n {overlay ? (\n <div\n aria-hidden={false}\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.5)',\n color: '#fff',\n fontSize: 28,\n fontWeight: 600,\n }}\n >\n {`+${overlay}`}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface ImageMosaicProps {\n media: readonly ResolvedMedia[];\n}\n\nexport function ImageMosaic({ media }: ImageMosaicProps) {\n if (media.length === 0) {\n return null;\n }\n\n if (media.length === 1) {\n const only = media[0]!;\n return (\n <img\n src={only.src}\n alt={only.alt ?? ''}\n style={{ width: '100%', height: 'auto', display: 'block' }}\n />\n );\n }\n\n const tiles = media.slice(0, MAX_TILES);\n const hidden = media.length - MAX_TILES;\n\n return (\n <div style={gridStyle(tiles.length)}>\n {tiles.map((item, index) => (\n <Tile\n key={item.src + index}\n item={item}\n area={tiles.length === 3 ? AREAS[index] : undefined}\n overlay={\n hidden > 0 && index === MAX_TILES - 1 ? hidden : undefined\n }\n />\n ))}\n </div>\n );\n}\n","import type { ResolvedMedia } from '../types';\nimport { ImageMosaic } from './ImageMosaic';\n\n/**\n * The media area of a LinkedIn post (v1: images + video). A post carries either\n * a video or images; a video wins if present and renders as a playable element\n * with its poster, otherwise the image mosaic. Edge-to-edge, like the feed.\n */\n\nfunction VideoTile({ item }: { item: ResolvedMedia }) {\n return (\n <video\n src={item.src}\n poster={item.posterSrc}\n controls\n style={{ width: '100%', display: 'block', background: '#000' }}\n />\n );\n}\n\nexport interface MediaProps {\n media: readonly ResolvedMedia[];\n}\n\nexport function Media({ media }: MediaProps) {\n if (media.length === 0) {\n return null;\n }\n\n const video = media.find(\n (item) => item.kind === 'video' || item.kind === 'gif',\n );\n if (video) {\n return <VideoTile item={video} />;\n }\n\n const images = media.filter((item) => item.kind === 'image');\n return <ImageMosaic media={images} />;\n}\n","'use client';\n\nimport { Fragment, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\n/**\n * The LinkedIn post body: entity-highlighted text with the platform's faithful\n * \"…more\" fold. LinkedIn truncates a long post to a few lines with an inline\n * \"…more\" toggle; we mirror that. Hashtags, URLs, and supplied @mention names\n * render in the accent color, exactly as they appear in-feed.\n */\n\n/** Roughly the in-feed fold point — long posts collapse here behind \"…more\". */\nconst FOLD_CHARS = 200;\n\nexport interface PostBodyColors {\n accent: string;\n muted: string;\n}\n\nexport interface PostBodyProps {\n text: string;\n /** Names to highlight as @mentions (from `settings.mentions[].name`). */\n mentionNames?: readonly string[];\n colors: PostBodyColors;\n}\n\nconst BODY_STYLE: CSSProperties = {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n fontSize: 14,\n lineHeight: 1.43,\n};\n\n/** Truncate to at most `max` characters, backing up to the last word boundary. */\nfunction truncateAtWord(text: string, max: number): string {\n if (text.length <= max) {\n return text;\n }\n const slice = text.slice(0, max);\n const lastSpace = slice.lastIndexOf(' ');\n return slice.slice(0, lastSpace > 0 ? lastSpace : max);\n}\n\n/** Escape a string for safe use inside a RegExp. */\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/** Build the tokenizer: hashtags, URLs, then any supplied mention names. */\nfunction buildPattern(mentionNames: readonly string[]): RegExp {\n const mentionAlt = mentionNames\n .filter((name) => name.trim().length > 0)\n .map(escapeRegExp)\n .join('|');\n const parts = [\n 'https?:\\\\/\\\\/[^\\\\s]+', // urls\n '#[\\\\p{L}\\\\p{N}_]+', // hashtags (unicode-aware)\n ...(mentionAlt ? [mentionAlt] : []),\n ];\n return new RegExp(`(${parts.join('|')})`, 'gu');\n}\n\nfunction linkStyle(color: string): CSSProperties {\n return { color, textDecoration: 'none', fontWeight: 500 };\n}\n\n/** Split text into plain runs and highlighted entity nodes. */\nfunction linkify(\n text: string,\n colors: PostBodyColors,\n mentionNames: readonly string[],\n): ReactNode[] {\n const pattern = buildPattern(mentionNames);\n const nodes: ReactNode[] = [];\n let lastIndex = 0;\n let key = 0;\n\n for (const match of text.matchAll(pattern)) {\n const token = match[0];\n const start = match.index;\n if (start > lastIndex) {\n nodes.push(\n <Fragment key={key++}>{text.slice(lastIndex, start)}</Fragment>,\n );\n }\n if (token.startsWith('http')) {\n nodes.push(\n <a\n key={key++}\n href={token}\n style={linkStyle(colors.accent)}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {token}\n </a>,\n );\n } else if (token.startsWith('#')) {\n nodes.push(\n <a key={key++} href=\"#\" style={linkStyle(colors.accent)}>\n {token}\n </a>,\n );\n } else {\n nodes.push(\n <span key={key++} style={linkStyle(colors.accent)}>\n {token}\n </span>,\n );\n }\n lastIndex = start + token.length;\n }\n\n if (lastIndex < text.length) {\n nodes.push(<Fragment key={key++}>{text.slice(lastIndex)}</Fragment>);\n }\n return nodes;\n}\n\nexport function PostBody({ text, mentionNames = [], colors }: PostBodyProps) {\n const [expanded, setExpanded] = useState(false);\n const isLong = text.length > FOLD_CHARS;\n const shown = isLong && !expanded ? truncateAtWord(text, FOLD_CHARS) : text;\n\n return (\n <div style={BODY_STYLE}>\n {linkify(shown, colors, mentionNames)}\n {isLong && !expanded ? (\n <>\n {'…'}{' '}\n <button\n type=\"button\"\n onClick={() => setExpanded(true)}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n color: colors.muted,\n fontWeight: 600,\n fontSize: 14,\n }}\n >\n more\n </button>\n </>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport type { LinkedInPostVariant } from '@postrun/js';\nimport { memo } from 'react';\nimport type { CSSProperties } from 'react';\n\nimport type { LinkedInPreviewAuthor, PreviewMedia } from '../types';\nimport { altSignatureOf, useResolvedMedia } from '../use-resolved-media';\nimport { EngagementBar } from './EngagementBar';\nimport { Header } from './Header';\nimport type { LinkedInVisibility } from './Header';\nimport { Media } from './Media';\nimport { PostBody } from './PostBody';\nimport {\n LI_VAR,\n type LinkedInTheme,\n paletteVars,\n useIsDark,\n varRef,\n} from './theme';\n\n/**\n * A faithful, schema-driven preview of how a LinkedIn post will look in-feed,\n * rendered straight from a Postrun LinkedIn variant. Clean-room components (no\n * dependency to \"buy\" exists for LinkedIn), mirroring the real feed card: header\n * with headline + audience icon, an entity-highlighted body with the \"…more\"\n * fold, the 1/2/3/4/+N image mosaic (or a video), and a static action bar.\n *\n * v1 renders text + images + video. The richer `content_kind`s (article, poll,\n * document) degrade gracefully to the text/media card and arrive next.\n *\n * Customize via `theme` (light/dark/auto), `className`/`style`, or by overriding\n * the `--pr-li-*` CSS variables the card reads.\n */\nexport interface LinkedInPostPreviewProps {\n /** The LinkedIn variant from our schema — the content source, untouched. */\n variant: LinkedInPostVariant;\n /** Author identity (LinkedIn stores no avatar/headline on our connection). */\n author: LinkedInPreviewAuthor;\n /** Resolved media pixels (URLs or compose-time File blobs). */\n media?: PreviewMedia[];\n /** Color scheme. `auto` (default) follows the OS preference. */\n theme?: LinkedInTheme;\n /** Relative time label shown in the header. Default \"Now\". */\n time?: string;\n /** Show the static action bar (Like/Comment/Repost/Send). Default true. */\n showActions?: boolean;\n /** Class applied to the card — your hook for sizing, shadows, etc. */\n className?: string;\n /** Inline styles on the card — including `--pr-li-*` variable overrides. */\n style?: CSSProperties;\n}\n\nconst FONT_STACK =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\nfunction LinkedInPostPreviewImpl({\n variant,\n author,\n media,\n theme = 'auto',\n time,\n showActions = true,\n className,\n style,\n}: LinkedInPostPreviewProps) {\n const dark = useIsDark(theme);\n const resolvedMedia = useResolvedMedia(\n media,\n variant.media,\n altSignatureOf(variant.media),\n );\n\n const visibility: LinkedInVisibility =\n variant.settings?.visibility ?? 'PUBLIC';\n const mentionNames = (variant.settings?.mentions ?? []).map((m) => m.name);\n const bodyColors = {\n accent: varRef(LI_VAR.accent),\n muted: varRef(LI_VAR.muted),\n };\n\n const cardStyle: CSSProperties = {\n ...paletteVars(dark),\n background: varRef(LI_VAR.bg),\n color: varRef(LI_VAR.text),\n border: `1px solid ${varRef(LI_VAR.border)}`,\n borderRadius: 10,\n maxWidth: 552,\n overflow: 'hidden',\n fontFamily: FONT_STACK,\n ...style,\n };\n\n return (\n <div className={className} style={cardStyle}>\n <Header author={author} visibility={visibility} time={time} />\n {variant.body ? (\n <div style={{ padding: '8px 16px 0' }}>\n <PostBody\n text={variant.body}\n mentionNames={mentionNames}\n colors={bodyColors}\n />\n </div>\n ) : null}\n {resolvedMedia.length > 0 ? (\n <div style={{ marginTop: 12 }}>\n <Media media={resolvedMedia} />\n </div>\n ) : null}\n {showActions ? <EngagementBar /> : null}\n </div>\n );\n}\n\n/** Memoized: re-renders only when its props change (the resolved-media hook\n * absorbs unstable media arrays). */\nexport const LinkedInPostPreview = memo(LinkedInPostPreviewImpl);\n"]}