@postrun/react 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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, ValidationIssue } from '@postrun/js';
7
7
  import { TwitterComponents } from 'react-tweet';
8
8
 
9
9
  /**
@@ -970,7 +970,7 @@ declare function usePosts(query?: ListPostsQuery): _tanstack_react_query.UseQuer
970
970
  variants: Array<{
971
971
  id: string;
972
972
  object: "post_variant";
973
- connection_id: string;
973
+ connection_id: string | null;
974
974
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
975
975
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
976
976
  body: string | null;
@@ -1030,7 +1030,7 @@ declare function usePostsInfinite(filters?: Omit<ListPostsQuery, 'limit' | 'offs
1030
1030
  variants: Array<{
1031
1031
  id: string;
1032
1032
  object: "post_variant";
1033
- connection_id: string;
1033
+ connection_id: string | null;
1034
1034
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1035
1035
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1036
1036
  body: string | null;
@@ -1089,7 +1089,7 @@ declare function useCalendar(filters?: CalendarFilters & Pick<ListPostsQuery, 'l
1089
1089
  variants: Array<{
1090
1090
  id: string;
1091
1091
  object: "post_variant";
1092
- connection_id: string;
1092
+ connection_id: string | null;
1093
1093
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1094
1094
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1095
1095
  body: string | null;
@@ -1146,7 +1146,7 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
1146
1146
  variants: Array<{
1147
1147
  id: string;
1148
1148
  object: "post_variant";
1149
- connection_id: string;
1149
+ connection_id: string | null;
1150
1150
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1151
1151
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1152
1152
  body: string | null;
@@ -1181,6 +1181,25 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
1181
1181
  * variant set from `{ content, channels }` (per the `buildCreatePost` rules), and
1182
1182
  * sends it — the customer never assembles variants or passes a `connection_id`.
1183
1183
  * `connectedChannels` is the set of posting platforms this profile can reach.
1184
+ *
1185
+ * ## Reading the publish outcome (do NOT stop at "it returned")
1186
+ * On `publish: 'now'` the API returns the created post with a rollup `status` and
1187
+ * a per-variant `status` + typed `error`. A 201 does NOT mean every platform
1188
+ * published — one can silently fail while another succeeds. Surface the outcome
1189
+ * via the derived fields, never assume success from a resolved `create`:
1190
+ *
1191
+ * - **`status`** — the rollup (`published | partially_published | failed |
1192
+ * draft | scheduled`), `undefined` until the first `create` resolves.
1193
+ * - **`isPublished`** — `true` ONLY when `status === 'published'`. This is the
1194
+ * one "fully published" state; `partially_published` and `failed` are NOT
1195
+ * success. Branch on this, not on the promise resolving.
1196
+ * - **`failedVariants`** — the variants that failed, each with its typed
1197
+ * `error` (`{ code, message }`); `[]` when none. Render "X failed: <message>".
1198
+ *
1199
+ * `create` still resolves with the FULL `Post` (read everything if you need to),
1200
+ * and it NEVER throws on a failed/partial publish — a throw would discard the
1201
+ * platforms that DID publish. A transport error (network / 4xx) still surfaces
1202
+ * via `error` (and rejects `create`), exactly as before.
1184
1203
  */
1185
1204
  declare function useCreatePost(profileId: string): {
1186
1205
  create: _tanstack_react_query.UseMutateAsyncFunction<{
@@ -1198,7 +1217,7 @@ declare function useCreatePost(profileId: string): {
1198
1217
  variants: Array<{
1199
1218
  id: string;
1200
1219
  object: "post_variant";
1201
- connection_id: string;
1220
+ connection_id: string | null;
1202
1221
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1203
1222
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1204
1223
  body: string | null;
@@ -1247,7 +1266,7 @@ declare function useCreatePost(profileId: string): {
1247
1266
  variants: Array<{
1248
1267
  id: string;
1249
1268
  object: "post_variant";
1250
- connection_id: string;
1269
+ connection_id: string | null;
1251
1270
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1252
1271
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1253
1272
  body: string | null;
@@ -1280,6 +1299,38 @@ declare function useCreatePost(profileId: string): {
1280
1299
  executed: boolean;
1281
1300
  } | undefined;
1282
1301
  reset: () => void;
1302
+ status: "draft" | "scheduled" | "publishing" | "partially_published" | "published" | "failed" | undefined;
1303
+ isPublished: boolean;
1304
+ failedVariants: {
1305
+ id: string;
1306
+ object: "post_variant";
1307
+ connection_id: string | null;
1308
+ platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1309
+ post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1310
+ body: string | null;
1311
+ status: "draft" | "scheduled" | "publishing" | "published" | "failed";
1312
+ settings: {
1313
+ [key: string]: unknown;
1314
+ };
1315
+ schedule_at: string | null;
1316
+ result: {
1317
+ platform_post_id: string;
1318
+ permalink: string | null;
1319
+ published_at: string;
1320
+ } | null;
1321
+ error: {
1322
+ code: string;
1323
+ message: string;
1324
+ } | null;
1325
+ media: Array<{
1326
+ media_id: string;
1327
+ position: number;
1328
+ crop_box: {
1329
+ [key: string]: unknown;
1330
+ } | null;
1331
+ alt_text_override: string | null;
1332
+ }>;
1333
+ }[];
1283
1334
  isReady: boolean;
1284
1335
  connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
1285
1336
  };
@@ -1300,7 +1351,7 @@ declare function useValidatePost(profileId: string): {
1300
1351
  validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
1301
1352
  publishable: boolean | undefined;
1302
1353
  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" | "connection_in_use" | "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" | "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";
1354
+ 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_access_not_permitted" | "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";
1304
1355
  message: string;
1305
1356
  hint?: string;
1306
1357
  allowed?: Array<string>;
@@ -1333,7 +1384,7 @@ declare function useUpdatePost(postId: string): _tanstack_react_query.UseMutatio
1333
1384
  variants: Array<{
1334
1385
  id: string;
1335
1386
  object: "post_variant";
1336
- connection_id: string;
1387
+ connection_id: string | null;
1337
1388
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1338
1389
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1339
1390
  body: string | null;
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, ValidationIssue } from '@postrun/js';
7
7
  import { TwitterComponents } from 'react-tweet';
8
8
 
9
9
  /**
@@ -970,7 +970,7 @@ declare function usePosts(query?: ListPostsQuery): _tanstack_react_query.UseQuer
970
970
  variants: Array<{
971
971
  id: string;
972
972
  object: "post_variant";
973
- connection_id: string;
973
+ connection_id: string | null;
974
974
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
975
975
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
976
976
  body: string | null;
@@ -1030,7 +1030,7 @@ declare function usePostsInfinite(filters?: Omit<ListPostsQuery, 'limit' | 'offs
1030
1030
  variants: Array<{
1031
1031
  id: string;
1032
1032
  object: "post_variant";
1033
- connection_id: string;
1033
+ connection_id: string | null;
1034
1034
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1035
1035
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1036
1036
  body: string | null;
@@ -1089,7 +1089,7 @@ declare function useCalendar(filters?: CalendarFilters & Pick<ListPostsQuery, 'l
1089
1089
  variants: Array<{
1090
1090
  id: string;
1091
1091
  object: "post_variant";
1092
- connection_id: string;
1092
+ connection_id: string | null;
1093
1093
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1094
1094
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1095
1095
  body: string | null;
@@ -1146,7 +1146,7 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
1146
1146
  variants: Array<{
1147
1147
  id: string;
1148
1148
  object: "post_variant";
1149
- connection_id: string;
1149
+ connection_id: string | null;
1150
1150
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1151
1151
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1152
1152
  body: string | null;
@@ -1181,6 +1181,25 @@ declare function usePost(id: string, options?: LiveOptions): _tanstack_react_que
1181
1181
  * variant set from `{ content, channels }` (per the `buildCreatePost` rules), and
1182
1182
  * sends it — the customer never assembles variants or passes a `connection_id`.
1183
1183
  * `connectedChannels` is the set of posting platforms this profile can reach.
1184
+ *
1185
+ * ## Reading the publish outcome (do NOT stop at "it returned")
1186
+ * On `publish: 'now'` the API returns the created post with a rollup `status` and
1187
+ * a per-variant `status` + typed `error`. A 201 does NOT mean every platform
1188
+ * published — one can silently fail while another succeeds. Surface the outcome
1189
+ * via the derived fields, never assume success from a resolved `create`:
1190
+ *
1191
+ * - **`status`** — the rollup (`published | partially_published | failed |
1192
+ * draft | scheduled`), `undefined` until the first `create` resolves.
1193
+ * - **`isPublished`** — `true` ONLY when `status === 'published'`. This is the
1194
+ * one "fully published" state; `partially_published` and `failed` are NOT
1195
+ * success. Branch on this, not on the promise resolving.
1196
+ * - **`failedVariants`** — the variants that failed, each with its typed
1197
+ * `error` (`{ code, message }`); `[]` when none. Render "X failed: <message>".
1198
+ *
1199
+ * `create` still resolves with the FULL `Post` (read everything if you need to),
1200
+ * and it NEVER throws on a failed/partial publish — a throw would discard the
1201
+ * platforms that DID publish. A transport error (network / 4xx) still surfaces
1202
+ * via `error` (and rejects `create`), exactly as before.
1184
1203
  */
1185
1204
  declare function useCreatePost(profileId: string): {
1186
1205
  create: _tanstack_react_query.UseMutateAsyncFunction<{
@@ -1198,7 +1217,7 @@ declare function useCreatePost(profileId: string): {
1198
1217
  variants: Array<{
1199
1218
  id: string;
1200
1219
  object: "post_variant";
1201
- connection_id: string;
1220
+ connection_id: string | null;
1202
1221
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1203
1222
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1204
1223
  body: string | null;
@@ -1247,7 +1266,7 @@ declare function useCreatePost(profileId: string): {
1247
1266
  variants: Array<{
1248
1267
  id: string;
1249
1268
  object: "post_variant";
1250
- connection_id: string;
1269
+ connection_id: string | null;
1251
1270
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1252
1271
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1253
1272
  body: string | null;
@@ -1280,6 +1299,38 @@ declare function useCreatePost(profileId: string): {
1280
1299
  executed: boolean;
1281
1300
  } | undefined;
1282
1301
  reset: () => void;
1302
+ status: "draft" | "scheduled" | "publishing" | "partially_published" | "published" | "failed" | undefined;
1303
+ isPublished: boolean;
1304
+ failedVariants: {
1305
+ id: string;
1306
+ object: "post_variant";
1307
+ connection_id: string | null;
1308
+ platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1309
+ post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1310
+ body: string | null;
1311
+ status: "draft" | "scheduled" | "publishing" | "published" | "failed";
1312
+ settings: {
1313
+ [key: string]: unknown;
1314
+ };
1315
+ schedule_at: string | null;
1316
+ result: {
1317
+ platform_post_id: string;
1318
+ permalink: string | null;
1319
+ published_at: string;
1320
+ } | null;
1321
+ error: {
1322
+ code: string;
1323
+ message: string;
1324
+ } | null;
1325
+ media: Array<{
1326
+ media_id: string;
1327
+ position: number;
1328
+ crop_box: {
1329
+ [key: string]: unknown;
1330
+ } | null;
1331
+ alt_text_override: string | null;
1332
+ }>;
1333
+ }[];
1283
1334
  isReady: boolean;
1284
1335
  connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
1285
1336
  };
@@ -1300,7 +1351,7 @@ declare function useValidatePost(profileId: string): {
1300
1351
  validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
1301
1352
  publishable: boolean | undefined;
1302
1353
  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" | "connection_in_use" | "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" | "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";
1354
+ 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_access_not_permitted" | "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";
1304
1355
  message: string;
1305
1356
  hint?: string;
1306
1357
  allowed?: Array<string>;
@@ -1333,7 +1384,7 @@ declare function useUpdatePost(postId: string): _tanstack_react_query.UseMutatio
1333
1384
  variants: Array<{
1334
1385
  id: string;
1335
1386
  object: "post_variant";
1336
- connection_id: string;
1387
+ connection_id: string | null;
1337
1388
  platform: "x" | "linkedin" | "facebook_page" | "instagram" | "tiktok";
1338
1389
  post_type: "text" | "single_image" | "multi_image" | "video" | "reel" | "carousel";
1339
1390
  body: string | null;
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, 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';
@@ -878,12 +878,18 @@ function useCreatePost(profileId) {
878
878
  },
879
879
  queryClient
880
880
  );
881
+ const post = mutation.data;
881
882
  return {
882
883
  create: mutation.mutateAsync,
883
884
  isPending: mutation.isPending,
884
885
  error: mutation.error,
885
- data: mutation.data,
886
+ data: post,
886
887
  reset: mutation.reset,
888
+ // Derived publish outcome (see the JSDoc above) — `undefined`/`false`/`[]`
889
+ // until the first create resolves; computed from the returned post only.
890
+ status: post?.status,
891
+ isPublished: post ? isPublished(post) : false,
892
+ failedVariants: post ? failedVariants(post) : [],
887
893
  // The profile's connections must load before `create` can resolve a channel;
888
894
  // gate on this so a call during loading isn't mislabeled "not connected".
889
895
  isReady: connections.isSuccess,