@postrun/react 2.0.0 → 2.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.
- package/dist/index.cjs +26 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +91 -5
- package/dist/index.d.ts +91 -5
- package/dist/index.js +26 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ import { ReactNode, CSSProperties } from 'react';
|
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, QueryKey } from '@tanstack/react-query';
|
|
5
5
|
import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, MediaKind, Metadata, ComposePostInput, PostValidation, XPostVariant, LinkedInPostVariant } from '@postrun/js';
|
|
6
|
-
export { PostValidation, ValidationIssue } from '@postrun/js';
|
|
6
|
+
export { PostValidation, PostVariant, PostVariantError, TikTokCreatorInfo, ValidationIssue } from '@postrun/js';
|
|
7
7
|
import { TwitterComponents } from 'react-tweet';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -333,6 +333,11 @@ declare const connectionKeys: {
|
|
|
333
333
|
detail: (id: string) => readonly ["postrun", "connections", "detail", string];
|
|
334
334
|
accounts: (id: string) => readonly ["postrun", "connections", "accounts", string];
|
|
335
335
|
};
|
|
336
|
+
/** Query-key factory for TikTok reads (creator info keyed by connection id). */
|
|
337
|
+
declare const tiktokKeys: {
|
|
338
|
+
all: readonly ["postrun", "tiktok"];
|
|
339
|
+
creatorInfo: (connectionId: string) => readonly ["postrun", "tiktok", "creator-info", string];
|
|
340
|
+
};
|
|
336
341
|
|
|
337
342
|
interface UseConnectParams {
|
|
338
343
|
/** The profile to attach the new connection to. */
|
|
@@ -1181,6 +1186,25 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
|
|
|
1181
1186
|
* variant set from `{ content, channels }` (per the `buildCreatePost` rules), and
|
|
1182
1187
|
* sends it — the customer never assembles variants or passes a `connection_id`.
|
|
1183
1188
|
* `connectedChannels` is the set of posting platforms this profile can reach.
|
|
1189
|
+
*
|
|
1190
|
+
* ## Reading the publish outcome (do NOT stop at "it returned")
|
|
1191
|
+
* On `publish: 'now'` the API returns the created post with a rollup `status` and
|
|
1192
|
+
* a per-variant `status` + typed `error`. A 201 does NOT mean every platform
|
|
1193
|
+
* published — one can silently fail while another succeeds. Surface the outcome
|
|
1194
|
+
* via the derived fields, never assume success from a resolved `create`:
|
|
1195
|
+
*
|
|
1196
|
+
* - **`status`** — the rollup (`published | partially_published | failed |
|
|
1197
|
+
* draft | scheduled`), `undefined` until the first `create` resolves.
|
|
1198
|
+
* - **`isPublished`** — `true` ONLY when `status === 'published'`. This is the
|
|
1199
|
+
* one "fully published" state; `partially_published` and `failed` are NOT
|
|
1200
|
+
* success. Branch on this, not on the promise resolving.
|
|
1201
|
+
* - **`failedVariants`** — the variants that failed, each with its typed
|
|
1202
|
+
* `error` (`{ code, message }`); `[]` when none. Render "X failed: <message>".
|
|
1203
|
+
*
|
|
1204
|
+
* `create` still resolves with the FULL `Post` (read everything if you need to),
|
|
1205
|
+
* and it NEVER throws on a failed/partial publish — a throw would discard the
|
|
1206
|
+
* platforms that DID publish. A transport error (network / 4xx) still surfaces
|
|
1207
|
+
* via `error` (and rejects `create`), exactly as before.
|
|
1184
1208
|
*/
|
|
1185
1209
|
declare function useCreatePost(profileId: string): {
|
|
1186
1210
|
create: _tanstack_react_query.UseMutateAsyncFunction<{
|
|
@@ -1280,8 +1304,40 @@ declare function useCreatePost(profileId: string): {
|
|
|
1280
1304
|
executed: boolean;
|
|
1281
1305
|
} | undefined;
|
|
1282
1306
|
reset: () => void;
|
|
1307
|
+
status: "draft" | "scheduled" | "publishing" | "partially_published" | "published" | "failed" | undefined;
|
|
1308
|
+
isPublished: boolean;
|
|
1309
|
+
failedVariants: {
|
|
1310
|
+
id: string;
|
|
1311
|
+
object: "post_variant";
|
|
1312
|
+
connection_id: string | null;
|
|
1313
|
+
platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
|
|
1314
|
+
post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
|
|
1315
|
+
body: string | null;
|
|
1316
|
+
status: "draft" | "scheduled" | "publishing" | "published" | "failed";
|
|
1317
|
+
settings: {
|
|
1318
|
+
[key: string]: unknown;
|
|
1319
|
+
};
|
|
1320
|
+
schedule_at: string | null;
|
|
1321
|
+
result: {
|
|
1322
|
+
platform_post_id: string;
|
|
1323
|
+
permalink: string | null;
|
|
1324
|
+
published_at: string;
|
|
1325
|
+
} | null;
|
|
1326
|
+
error: {
|
|
1327
|
+
code: string;
|
|
1328
|
+
message: string;
|
|
1329
|
+
} | null;
|
|
1330
|
+
media: Array<{
|
|
1331
|
+
media_id: string;
|
|
1332
|
+
position: number;
|
|
1333
|
+
crop_box: {
|
|
1334
|
+
[key: string]: unknown;
|
|
1335
|
+
} | null;
|
|
1336
|
+
alt_text_override: string | null;
|
|
1337
|
+
}>;
|
|
1338
|
+
}[];
|
|
1283
1339
|
isReady: boolean;
|
|
1284
|
-
connectedChannels: ("
|
|
1340
|
+
connectedChannels: ("tiktok" | "x" | "linkedin" | "facebook_page" | "instagram")[];
|
|
1285
1341
|
};
|
|
1286
1342
|
/**
|
|
1287
1343
|
* Validate a composed post WITHOUT saving or publishing it — the read-scoped
|
|
@@ -1300,7 +1356,7 @@ declare function useValidatePost(profileId: string): {
|
|
|
1300
1356
|
validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
|
|
1301
1357
|
publishable: boolean | undefined;
|
|
1302
1358
|
issues: {
|
|
1303
|
-
code: "unauthorized" | "forbidden" | "not_found" | "conflict" | "validation_failed" | "rate_limited" | "internal_error" | "idempotency_key_invalid" | "idempotency_key_reused" | "idempotency_request_in_progress" | "account_not_available" | "connection_reauth_required" | "connection_not_pending" | "not_implemented" | "connection_discovery_failed" | "media_processing" | "not_publishable" | "invalid_connection" | "invalid_media" | "profile_scope_invalid" | "media_unprobeable" | "media_too_large" | "media_aspect_ratio_unsupported" | "media_resolution_too_low" | "media_gif_unsupported" | "media_format_recompressed" | "media_resolution_downscaled" | "video_container_unsupported" | "video_codec_unsupported" | "video_audio_codec_unsupported" | "video_too_large" | "video_too_small" | "video_dimensions_unsupported" | "video_dimensions_too_large" | "video_fps_unsupported" | "video_fps_too_low" | "video_aspect_unsupported" | "video_duration_too_short" | "video_duration_exceeds_max" | "video_transform_failed" | "media_fetch_failed" | "document_format_unsupported" | "document_too_large" | "document_too_many_pages" | "media_format_indeterminate" | "media_count_invalid" | "body_too_long" | "content_missing" | "content_conflict" | "content_incomplete" | "content_kind_mismatch" | "media_type_mismatch" | "tag_limit_exceeded" | "reel_field_on_non_reel" | "field_placement_invalid" | "media_not_ready" | "media_failed" | "media_unsupported" | "media_kind_mismatch" | "variant_unparseable" | "publishing_unavailable" | "x_duplicate_content" | "x_not_authorized" | "x_rate_limited" | "x_publish_failed" | "x_media_upload_failed" | "linkedin_duplicate_content" | "linkedin_auth_expired" | "linkedin_permission_denied" | "linkedin_media_processing" | "linkedin_media_upload_failed" | "linkedin_publish_failed" | "instagram_media_processing" | "instagram_container_expired" | "instagram_container_failed" | "instagram_rate_limited" | "instagram_not_authorized" | "instagram_publish_failed" | "facebook_reel_processing" | "facebook_reel_failed" | "facebook_rate_limited" | "facebook_not_authorized" | "facebook_publish_failed" | "tiktok_privacy_not_allowed" | "tiktok_duration_exceeds_max" | "tiktok_media_processing" | "tiktok_not_authorized" | "tiktok_rate_limited" | "tiktok_publish_failed" | "connection_platform_mismatch" | "connection_removed";
|
|
1359
|
+
code: "unauthorized" | "forbidden" | "not_found" | "conflict" | "validation_failed" | "rate_limited" | "internal_error" | "idempotency_key_invalid" | "idempotency_key_reused" | "idempotency_request_in_progress" | "account_not_available" | "connection_reauth_required" | "connection_not_pending" | "not_implemented" | "connection_discovery_failed" | "tiktok_creator_info_unavailable" | "media_processing" | "not_publishable" | "invalid_connection" | "invalid_media" | "profile_scope_invalid" | "media_unprobeable" | "media_too_large" | "media_aspect_ratio_unsupported" | "media_resolution_too_low" | "media_gif_unsupported" | "media_format_recompressed" | "media_resolution_downscaled" | "video_container_unsupported" | "video_codec_unsupported" | "video_audio_codec_unsupported" | "video_too_large" | "video_too_small" | "video_dimensions_unsupported" | "video_dimensions_too_large" | "video_fps_unsupported" | "video_fps_too_low" | "video_aspect_unsupported" | "video_duration_too_short" | "video_duration_exceeds_max" | "video_transform_failed" | "media_fetch_failed" | "document_format_unsupported" | "document_too_large" | "document_too_many_pages" | "media_format_indeterminate" | "media_count_invalid" | "body_too_long" | "content_missing" | "content_conflict" | "content_incomplete" | "content_kind_mismatch" | "media_type_mismatch" | "tag_limit_exceeded" | "reel_field_on_non_reel" | "field_placement_invalid" | "media_not_ready" | "media_failed" | "media_unsupported" | "media_kind_mismatch" | "variant_unparseable" | "publishing_unavailable" | "x_duplicate_content" | "x_not_authorized" | "x_access_not_permitted" | "x_rate_limited" | "x_publish_failed" | "x_media_upload_failed" | "linkedin_duplicate_content" | "linkedin_auth_expired" | "linkedin_permission_denied" | "linkedin_rate_limited" | "linkedin_media_processing" | "linkedin_media_failed" | "linkedin_media_upload_failed" | "linkedin_publish_failed" | "instagram_media_processing" | "instagram_container_expired" | "instagram_container_failed" | "instagram_rate_limited" | "instagram_not_authorized" | "instagram_publish_failed" | "facebook_reel_processing" | "facebook_reel_failed" | "facebook_rate_limited" | "facebook_not_authorized" | "facebook_publish_failed" | "tiktok_privacy_not_allowed" | "tiktok_duration_exceeds_max" | "tiktok_media_processing" | "tiktok_not_authorized" | "tiktok_rate_limited" | "tiktok_publish_failed" | "post_publish_failed" | "post_partially_published" | "connection_platform_mismatch" | "connection_removed";
|
|
1304
1360
|
message: string;
|
|
1305
1361
|
hint?: string;
|
|
1306
1362
|
allowed?: Array<string>;
|
|
@@ -1311,7 +1367,7 @@ declare function useValidatePost(profileId: string): {
|
|
|
1311
1367
|
isPending: boolean;
|
|
1312
1368
|
error: Error | null;
|
|
1313
1369
|
isReady: boolean;
|
|
1314
|
-
connectedChannels: ("
|
|
1370
|
+
connectedChannels: ("tiktok" | "x" | "linkedin" | "facebook_page" | "instagram")[];
|
|
1315
1371
|
};
|
|
1316
1372
|
/**
|
|
1317
1373
|
* Update a post by id. Pass a light edit directly (`{ schedule_at }`,
|
|
@@ -1517,6 +1573,36 @@ declare function useDeletePost(): _tanstack_react_query.UseMutationResult<{
|
|
|
1517
1573
|
deleted: true;
|
|
1518
1574
|
}, Error, string, unknown>;
|
|
1519
1575
|
|
|
1576
|
+
/**
|
|
1577
|
+
* Fetch a TikTok connection's live creator info — the data TikTok's Content
|
|
1578
|
+
* Posting policy REQUIRES the publishing UI to render before a post: the
|
|
1579
|
+
* `creator` (nickname + avatar), the `privacy_options` to offer (with NO default
|
|
1580
|
+
* selected — render each with `tiktokPrivacyLabel`), the positive `interaction`
|
|
1581
|
+
* (allowed) flags for the Comment/Duet/Stitch toggles, and the per-account video
|
|
1582
|
+
* length cap (`max_video_duration_sec`).
|
|
1583
|
+
*
|
|
1584
|
+
* Pass the id of the TikTok connection the composer is posting through, or `null`
|
|
1585
|
+
* when none is selected yet — the query is DISABLED while `connectionId` is null
|
|
1586
|
+
* (no request fires). The host knows which connection is TikTok (it picked it), so
|
|
1587
|
+
* only call this for a TikTok connection; a non-TikTok id surfaces a 404 as
|
|
1588
|
+
* `error` (the API never leaks the platform). Returns the standard react-query
|
|
1589
|
+
* result — read `data` (the creator info), `isLoading`, and `error`.
|
|
1590
|
+
*/
|
|
1591
|
+
declare function useTikTokCreatorInfo(connectionId: string | null): _tanstack_react_query.UseQueryResult<NoInfer<{
|
|
1592
|
+
creator: {
|
|
1593
|
+
nickname: string;
|
|
1594
|
+
username: string;
|
|
1595
|
+
avatar_url: string | null;
|
|
1596
|
+
};
|
|
1597
|
+
privacy_options: Array<"PUBLIC_TO_EVERYONE" | "MUTUAL_FOLLOW_FRIENDS" | "FOLLOWER_OF_CREATOR" | "SELF_ONLY">;
|
|
1598
|
+
interaction: {
|
|
1599
|
+
comment: boolean;
|
|
1600
|
+
duet: boolean;
|
|
1601
|
+
stitch: boolean;
|
|
1602
|
+
};
|
|
1603
|
+
max_video_duration_sec: number;
|
|
1604
|
+
}>, Error>;
|
|
1605
|
+
|
|
1520
1606
|
/**
|
|
1521
1607
|
* Public input types for the post-preview components. These describe data the
|
|
1522
1608
|
* CUSTOMER supplies for presentation — NOT shapes from our OpenAPI contract — so
|
|
@@ -1665,4 +1751,4 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
|
|
|
1665
1751
|
* absorbs unstable media arrays). */
|
|
1666
1752
|
declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
|
|
1667
1753
|
|
|
1668
|
-
export { type CalendarFilters, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, type DiscoverableAccount, type InfiniteList, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
|
1754
|
+
export { type CalendarFilters, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, type DiscoverableAccount, type InfiniteList, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ReactNode, CSSProperties } from 'react';
|
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, QueryKey } from '@tanstack/react-query';
|
|
5
5
|
import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, MediaKind, Metadata, ComposePostInput, PostValidation, XPostVariant, LinkedInPostVariant } from '@postrun/js';
|
|
6
|
-
export { PostValidation, ValidationIssue } from '@postrun/js';
|
|
6
|
+
export { PostValidation, PostVariant, PostVariantError, TikTokCreatorInfo, ValidationIssue } from '@postrun/js';
|
|
7
7
|
import { TwitterComponents } from 'react-tweet';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -333,6 +333,11 @@ declare const connectionKeys: {
|
|
|
333
333
|
detail: (id: string) => readonly ["postrun", "connections", "detail", string];
|
|
334
334
|
accounts: (id: string) => readonly ["postrun", "connections", "accounts", string];
|
|
335
335
|
};
|
|
336
|
+
/** Query-key factory for TikTok reads (creator info keyed by connection id). */
|
|
337
|
+
declare const tiktokKeys: {
|
|
338
|
+
all: readonly ["postrun", "tiktok"];
|
|
339
|
+
creatorInfo: (connectionId: string) => readonly ["postrun", "tiktok", "creator-info", string];
|
|
340
|
+
};
|
|
336
341
|
|
|
337
342
|
interface UseConnectParams {
|
|
338
343
|
/** The profile to attach the new connection to. */
|
|
@@ -1181,6 +1186,25 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
|
|
|
1181
1186
|
* variant set from `{ content, channels }` (per the `buildCreatePost` rules), and
|
|
1182
1187
|
* sends it — the customer never assembles variants or passes a `connection_id`.
|
|
1183
1188
|
* `connectedChannels` is the set of posting platforms this profile can reach.
|
|
1189
|
+
*
|
|
1190
|
+
* ## Reading the publish outcome (do NOT stop at "it returned")
|
|
1191
|
+
* On `publish: 'now'` the API returns the created post with a rollup `status` and
|
|
1192
|
+
* a per-variant `status` + typed `error`. A 201 does NOT mean every platform
|
|
1193
|
+
* published — one can silently fail while another succeeds. Surface the outcome
|
|
1194
|
+
* via the derived fields, never assume success from a resolved `create`:
|
|
1195
|
+
*
|
|
1196
|
+
* - **`status`** — the rollup (`published | partially_published | failed |
|
|
1197
|
+
* draft | scheduled`), `undefined` until the first `create` resolves.
|
|
1198
|
+
* - **`isPublished`** — `true` ONLY when `status === 'published'`. This is the
|
|
1199
|
+
* one "fully published" state; `partially_published` and `failed` are NOT
|
|
1200
|
+
* success. Branch on this, not on the promise resolving.
|
|
1201
|
+
* - **`failedVariants`** — the variants that failed, each with its typed
|
|
1202
|
+
* `error` (`{ code, message }`); `[]` when none. Render "X failed: <message>".
|
|
1203
|
+
*
|
|
1204
|
+
* `create` still resolves with the FULL `Post` (read everything if you need to),
|
|
1205
|
+
* and it NEVER throws on a failed/partial publish — a throw would discard the
|
|
1206
|
+
* platforms that DID publish. A transport error (network / 4xx) still surfaces
|
|
1207
|
+
* via `error` (and rejects `create`), exactly as before.
|
|
1184
1208
|
*/
|
|
1185
1209
|
declare function useCreatePost(profileId: string): {
|
|
1186
1210
|
create: _tanstack_react_query.UseMutateAsyncFunction<{
|
|
@@ -1280,8 +1304,40 @@ declare function useCreatePost(profileId: string): {
|
|
|
1280
1304
|
executed: boolean;
|
|
1281
1305
|
} | undefined;
|
|
1282
1306
|
reset: () => void;
|
|
1307
|
+
status: "draft" | "scheduled" | "publishing" | "partially_published" | "published" | "failed" | undefined;
|
|
1308
|
+
isPublished: boolean;
|
|
1309
|
+
failedVariants: {
|
|
1310
|
+
id: string;
|
|
1311
|
+
object: "post_variant";
|
|
1312
|
+
connection_id: string | null;
|
|
1313
|
+
platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
|
|
1314
|
+
post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
|
|
1315
|
+
body: string | null;
|
|
1316
|
+
status: "draft" | "scheduled" | "publishing" | "published" | "failed";
|
|
1317
|
+
settings: {
|
|
1318
|
+
[key: string]: unknown;
|
|
1319
|
+
};
|
|
1320
|
+
schedule_at: string | null;
|
|
1321
|
+
result: {
|
|
1322
|
+
platform_post_id: string;
|
|
1323
|
+
permalink: string | null;
|
|
1324
|
+
published_at: string;
|
|
1325
|
+
} | null;
|
|
1326
|
+
error: {
|
|
1327
|
+
code: string;
|
|
1328
|
+
message: string;
|
|
1329
|
+
} | null;
|
|
1330
|
+
media: Array<{
|
|
1331
|
+
media_id: string;
|
|
1332
|
+
position: number;
|
|
1333
|
+
crop_box: {
|
|
1334
|
+
[key: string]: unknown;
|
|
1335
|
+
} | null;
|
|
1336
|
+
alt_text_override: string | null;
|
|
1337
|
+
}>;
|
|
1338
|
+
}[];
|
|
1283
1339
|
isReady: boolean;
|
|
1284
|
-
connectedChannels: ("
|
|
1340
|
+
connectedChannels: ("tiktok" | "x" | "linkedin" | "facebook_page" | "instagram")[];
|
|
1285
1341
|
};
|
|
1286
1342
|
/**
|
|
1287
1343
|
* Validate a composed post WITHOUT saving or publishing it — the read-scoped
|
|
@@ -1300,7 +1356,7 @@ declare function useValidatePost(profileId: string): {
|
|
|
1300
1356
|
validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
|
|
1301
1357
|
publishable: boolean | undefined;
|
|
1302
1358
|
issues: {
|
|
1303
|
-
code: "unauthorized" | "forbidden" | "not_found" | "conflict" | "validation_failed" | "rate_limited" | "internal_error" | "idempotency_key_invalid" | "idempotency_key_reused" | "idempotency_request_in_progress" | "account_not_available" | "connection_reauth_required" | "connection_not_pending" | "not_implemented" | "connection_discovery_failed" | "media_processing" | "not_publishable" | "invalid_connection" | "invalid_media" | "profile_scope_invalid" | "media_unprobeable" | "media_too_large" | "media_aspect_ratio_unsupported" | "media_resolution_too_low" | "media_gif_unsupported" | "media_format_recompressed" | "media_resolution_downscaled" | "video_container_unsupported" | "video_codec_unsupported" | "video_audio_codec_unsupported" | "video_too_large" | "video_too_small" | "video_dimensions_unsupported" | "video_dimensions_too_large" | "video_fps_unsupported" | "video_fps_too_low" | "video_aspect_unsupported" | "video_duration_too_short" | "video_duration_exceeds_max" | "video_transform_failed" | "media_fetch_failed" | "document_format_unsupported" | "document_too_large" | "document_too_many_pages" | "media_format_indeterminate" | "media_count_invalid" | "body_too_long" | "content_missing" | "content_conflict" | "content_incomplete" | "content_kind_mismatch" | "media_type_mismatch" | "tag_limit_exceeded" | "reel_field_on_non_reel" | "field_placement_invalid" | "media_not_ready" | "media_failed" | "media_unsupported" | "media_kind_mismatch" | "variant_unparseable" | "publishing_unavailable" | "x_duplicate_content" | "x_not_authorized" | "x_rate_limited" | "x_publish_failed" | "x_media_upload_failed" | "linkedin_duplicate_content" | "linkedin_auth_expired" | "linkedin_permission_denied" | "linkedin_media_processing" | "linkedin_media_upload_failed" | "linkedin_publish_failed" | "instagram_media_processing" | "instagram_container_expired" | "instagram_container_failed" | "instagram_rate_limited" | "instagram_not_authorized" | "instagram_publish_failed" | "facebook_reel_processing" | "facebook_reel_failed" | "facebook_rate_limited" | "facebook_not_authorized" | "facebook_publish_failed" | "tiktok_privacy_not_allowed" | "tiktok_duration_exceeds_max" | "tiktok_media_processing" | "tiktok_not_authorized" | "tiktok_rate_limited" | "tiktok_publish_failed" | "connection_platform_mismatch" | "connection_removed";
|
|
1359
|
+
code: "unauthorized" | "forbidden" | "not_found" | "conflict" | "validation_failed" | "rate_limited" | "internal_error" | "idempotency_key_invalid" | "idempotency_key_reused" | "idempotency_request_in_progress" | "account_not_available" | "connection_reauth_required" | "connection_not_pending" | "not_implemented" | "connection_discovery_failed" | "tiktok_creator_info_unavailable" | "media_processing" | "not_publishable" | "invalid_connection" | "invalid_media" | "profile_scope_invalid" | "media_unprobeable" | "media_too_large" | "media_aspect_ratio_unsupported" | "media_resolution_too_low" | "media_gif_unsupported" | "media_format_recompressed" | "media_resolution_downscaled" | "video_container_unsupported" | "video_codec_unsupported" | "video_audio_codec_unsupported" | "video_too_large" | "video_too_small" | "video_dimensions_unsupported" | "video_dimensions_too_large" | "video_fps_unsupported" | "video_fps_too_low" | "video_aspect_unsupported" | "video_duration_too_short" | "video_duration_exceeds_max" | "video_transform_failed" | "media_fetch_failed" | "document_format_unsupported" | "document_too_large" | "document_too_many_pages" | "media_format_indeterminate" | "media_count_invalid" | "body_too_long" | "content_missing" | "content_conflict" | "content_incomplete" | "content_kind_mismatch" | "media_type_mismatch" | "tag_limit_exceeded" | "reel_field_on_non_reel" | "field_placement_invalid" | "media_not_ready" | "media_failed" | "media_unsupported" | "media_kind_mismatch" | "variant_unparseable" | "publishing_unavailable" | "x_duplicate_content" | "x_not_authorized" | "x_access_not_permitted" | "x_rate_limited" | "x_publish_failed" | "x_media_upload_failed" | "linkedin_duplicate_content" | "linkedin_auth_expired" | "linkedin_permission_denied" | "linkedin_rate_limited" | "linkedin_media_processing" | "linkedin_media_failed" | "linkedin_media_upload_failed" | "linkedin_publish_failed" | "instagram_media_processing" | "instagram_container_expired" | "instagram_container_failed" | "instagram_rate_limited" | "instagram_not_authorized" | "instagram_publish_failed" | "facebook_reel_processing" | "facebook_reel_failed" | "facebook_rate_limited" | "facebook_not_authorized" | "facebook_publish_failed" | "tiktok_privacy_not_allowed" | "tiktok_duration_exceeds_max" | "tiktok_media_processing" | "tiktok_not_authorized" | "tiktok_rate_limited" | "tiktok_publish_failed" | "post_publish_failed" | "post_partially_published" | "connection_platform_mismatch" | "connection_removed";
|
|
1304
1360
|
message: string;
|
|
1305
1361
|
hint?: string;
|
|
1306
1362
|
allowed?: Array<string>;
|
|
@@ -1311,7 +1367,7 @@ declare function useValidatePost(profileId: string): {
|
|
|
1311
1367
|
isPending: boolean;
|
|
1312
1368
|
error: Error | null;
|
|
1313
1369
|
isReady: boolean;
|
|
1314
|
-
connectedChannels: ("
|
|
1370
|
+
connectedChannels: ("tiktok" | "x" | "linkedin" | "facebook_page" | "instagram")[];
|
|
1315
1371
|
};
|
|
1316
1372
|
/**
|
|
1317
1373
|
* Update a post by id. Pass a light edit directly (`{ schedule_at }`,
|
|
@@ -1517,6 +1573,36 @@ declare function useDeletePost(): _tanstack_react_query.UseMutationResult<{
|
|
|
1517
1573
|
deleted: true;
|
|
1518
1574
|
}, Error, string, unknown>;
|
|
1519
1575
|
|
|
1576
|
+
/**
|
|
1577
|
+
* Fetch a TikTok connection's live creator info — the data TikTok's Content
|
|
1578
|
+
* Posting policy REQUIRES the publishing UI to render before a post: the
|
|
1579
|
+
* `creator` (nickname + avatar), the `privacy_options` to offer (with NO default
|
|
1580
|
+
* selected — render each with `tiktokPrivacyLabel`), the positive `interaction`
|
|
1581
|
+
* (allowed) flags for the Comment/Duet/Stitch toggles, and the per-account video
|
|
1582
|
+
* length cap (`max_video_duration_sec`).
|
|
1583
|
+
*
|
|
1584
|
+
* Pass the id of the TikTok connection the composer is posting through, or `null`
|
|
1585
|
+
* when none is selected yet — the query is DISABLED while `connectionId` is null
|
|
1586
|
+
* (no request fires). The host knows which connection is TikTok (it picked it), so
|
|
1587
|
+
* only call this for a TikTok connection; a non-TikTok id surfaces a 404 as
|
|
1588
|
+
* `error` (the API never leaks the platform). Returns the standard react-query
|
|
1589
|
+
* result — read `data` (the creator info), `isLoading`, and `error`.
|
|
1590
|
+
*/
|
|
1591
|
+
declare function useTikTokCreatorInfo(connectionId: string | null): _tanstack_react_query.UseQueryResult<NoInfer<{
|
|
1592
|
+
creator: {
|
|
1593
|
+
nickname: string;
|
|
1594
|
+
username: string;
|
|
1595
|
+
avatar_url: string | null;
|
|
1596
|
+
};
|
|
1597
|
+
privacy_options: Array<"PUBLIC_TO_EVERYONE" | "MUTUAL_FOLLOW_FRIENDS" | "FOLLOWER_OF_CREATOR" | "SELF_ONLY">;
|
|
1598
|
+
interaction: {
|
|
1599
|
+
comment: boolean;
|
|
1600
|
+
duet: boolean;
|
|
1601
|
+
stitch: boolean;
|
|
1602
|
+
};
|
|
1603
|
+
max_video_duration_sec: number;
|
|
1604
|
+
}>, Error>;
|
|
1605
|
+
|
|
1520
1606
|
/**
|
|
1521
1607
|
* Public input types for the post-preview components. These describe data the
|
|
1522
1608
|
* CUSTOMER supplies for presentation — NOT shapes from our OpenAPI contract — so
|
|
@@ -1665,4 +1751,4 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
|
|
|
1665
1751
|
* absorbs unstable media arrays). */
|
|
1666
1752
|
declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
|
|
1667
1753
|
|
|
1668
|
-
export { type CalendarFilters, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, type DiscoverableAccount, type InfiniteList, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
|
1754
|
+
export { type CalendarFilters, Connect, type ConnectErrorReason, type ConnectOutcome, type ConnectProps, type ConnectRenderApi, type ConnectState, type ConnectionsFilter, type DiscoverableAccount, type InfiniteList, LinkedInPostPreview, type LinkedInPostPreviewProps, type LinkedInPreviewAuthor, type LiveOptions, type MediaUploadItem, type MediaUploadOptions, type MediaUploadStatus, type PostrunContextValue, PostrunProvider, type PostrunProviderProps, type PreviewMedia, type PreviewMediaKind, UploadError, type UseConnectParams, type UseConnectResult, type UseMediaUploadOptions, type UseMediaUploadResult, XPostPreview, type XPostPreviewProps, type XPreviewAuthor, type XPreviewMedia, type XPreviewQuotedTweet, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createContext, memo, useMemo, useState, useEffect, Fragment as Fragment$1, useRef, createElement, useContext, useCallback } from 'react';
|
|
3
3
|
import { useInfiniteQuery, useQuery, useMutation, QueryClient } from '@tanstack/react-query';
|
|
4
|
-
import { createPostrunClient, profilesList, profilesGet, profilesCreate, profilesUpdate, profilesDelete, connectionsConnect, connectionsListByProfile, connectionsGet, connectionsListAccounts, connectionsSelect, connectionsDelete, mediaGet, mediaList, mediaUpdate, mediaDelete, postsList, postsGet, postsCreate, buildCreatePost, isPostPlatform, postsValidate, postsUpdate, postsDelete, mediaCreate, PostrunError } from '@postrun/js';
|
|
4
|
+
import { createPostrunClient, profilesList, profilesGet, profilesCreate, profilesUpdate, profilesDelete, connectionsConnect, connectionsListByProfile, connectionsGet, connectionsListAccounts, connectionsSelect, connectionsDelete, mediaGet, mediaList, mediaUpdate, mediaDelete, postsList, postsGet, postsCreate, buildCreatePost, isPostPlatform, failedVariants, isPublished, postsValidate, postsUpdate, postsDelete, tiktokCreatorInfo, mediaCreate, PostrunError } from '@postrun/js';
|
|
5
5
|
import Nango, { AuthError } from '@nangohq/frontend';
|
|
6
6
|
import pWaitFor, { TimeoutError } from 'p-wait-for';
|
|
7
7
|
import pLimit from 'p-limit';
|
|
@@ -129,6 +129,10 @@ var connectionKeys = {
|
|
|
129
129
|
detail: (id) => [...connectionKeys.details(), id],
|
|
130
130
|
accounts: (id) => [...connectionKeys.all, "accounts", id]
|
|
131
131
|
};
|
|
132
|
+
var tiktokKeys = {
|
|
133
|
+
all: [ROOT, "tiktok"],
|
|
134
|
+
creatorInfo: (connectionId) => [...tiktokKeys.all, "creator-info", connectionId]
|
|
135
|
+
};
|
|
132
136
|
|
|
133
137
|
// src/profiles.ts
|
|
134
138
|
function useProfiles(query) {
|
|
@@ -878,12 +882,18 @@ function useCreatePost(profileId) {
|
|
|
878
882
|
},
|
|
879
883
|
queryClient
|
|
880
884
|
);
|
|
885
|
+
const post = mutation.data;
|
|
881
886
|
return {
|
|
882
887
|
create: mutation.mutateAsync,
|
|
883
888
|
isPending: mutation.isPending,
|
|
884
889
|
error: mutation.error,
|
|
885
|
-
data:
|
|
890
|
+
data: post,
|
|
886
891
|
reset: mutation.reset,
|
|
892
|
+
// Derived publish outcome (see the JSDoc above) — `undefined`/`false`/`[]`
|
|
893
|
+
// until the first create resolves; computed from the returned post only.
|
|
894
|
+
status: post?.status,
|
|
895
|
+
isPublished: post ? isPublished(post) : false,
|
|
896
|
+
failedVariants: post ? failedVariants(post) : [],
|
|
887
897
|
// The profile's connections must load before `create` can resolve a channel;
|
|
888
898
|
// gate on this so a call during loading isn't mislabeled "not connected".
|
|
889
899
|
isReady: connections.isSuccess,
|
|
@@ -947,6 +957,19 @@ function useDeletePost() {
|
|
|
947
957
|
queryClient
|
|
948
958
|
);
|
|
949
959
|
}
|
|
960
|
+
function useTikTokCreatorInfo(connectionId) {
|
|
961
|
+
const { client, queryClient } = usePostrun();
|
|
962
|
+
return useQuery(
|
|
963
|
+
{
|
|
964
|
+
// `connectionId ?? ''` only ever keys the cache when the query is enabled
|
|
965
|
+
// (a non-null id), so the empty fallback is never used to fetch.
|
|
966
|
+
queryKey: tiktokKeys.creatorInfo(connectionId ?? ""),
|
|
967
|
+
queryFn: async () => (await tiktokCreatorInfo({ client, path: { id: connectionId ?? "" } })).data,
|
|
968
|
+
enabled: connectionId !== null
|
|
969
|
+
},
|
|
970
|
+
queryClient
|
|
971
|
+
);
|
|
972
|
+
}
|
|
950
973
|
function fileKey(file) {
|
|
951
974
|
return file ? `${file.name}:${file.size}:${file.lastModified}` : "";
|
|
952
975
|
}
|
|
@@ -1662,6 +1685,6 @@ function LinkedInPostPreviewImpl({
|
|
|
1662
1685
|
}
|
|
1663
1686
|
var LinkedInPostPreview = memo(LinkedInPostPreviewImpl);
|
|
1664
1687
|
|
|
1665
|
-
export { Connect, LinkedInPostPreview, PostrunProvider, UploadError, XPostPreview, connectionKeys, mediaKeys, postKeys, profileKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
|
1688
|
+
export { Connect, LinkedInPostPreview, PostrunProvider, UploadError, XPostPreview, connectionKeys, mediaKeys, postKeys, profileKeys, tiktokKeys, useCalendar, useConnect, useConnection, useConnections, useCreatePost, useCreateProfile, useDeleteMedia, useDeletePost, useDeleteProfile, useDisconnect, useDiscoverableAccounts, useInfiniteList, useMedia, useMediaInfinite, useMediaList, useMediaUpload, usePost, usePostrun, usePosts, usePostsInfinite, useProfile, useProfiles, useProfilesInfinite, useSelectAccount, useTikTokCreatorInfo, useUpdateMedia, useUpdatePost, useUpdateProfile, useValidatePost };
|
|
1666
1689
|
//# sourceMappingURL=index.js.map
|
|
1667
1690
|
//# sourceMappingURL=index.js.map
|