@postrun/react 1.2.0 → 1.3.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 +32 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +33 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, QueryKey } from '@tanstack/react-query';
|
|
5
|
-
import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, MediaKind, Metadata, ComposePostInput, XPostVariant, LinkedInPostVariant } from '@postrun/js';
|
|
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
7
|
import { TwitterComponents } from 'react-tweet';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -1282,6 +1283,36 @@ declare function useCreatePost(profileId: string): {
|
|
|
1282
1283
|
isReady: boolean;
|
|
1283
1284
|
connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
|
|
1284
1285
|
};
|
|
1286
|
+
/**
|
|
1287
|
+
* Validate a composed post WITHOUT saving or publishing it — the read-scoped
|
|
1288
|
+
* `POST /v1/posts/validate`. Builds the same best-effort variant set as
|
|
1289
|
+
* `useCreatePost` (via `buildCreatePost`), sends it, and relays the SERVER's
|
|
1290
|
+
* verdict: `publishable` (the single gate boolean) + `issues` (typed, per-variant
|
|
1291
|
+
* problems to render inline). The SDK makes NO validity judgment — the server is
|
|
1292
|
+
* the sole authority.
|
|
1293
|
+
*
|
|
1294
|
+
* It is a READ: no query-cache invalidation, no mutation handle. `validate` is a
|
|
1295
|
+
* stable callback (safe in deps); the caller debounces for live-as-you-type — the
|
|
1296
|
+
* hook never debounces internally. One call, no waterfall (connections are loaded
|
|
1297
|
+
* once by the shared `useConnections`).
|
|
1298
|
+
*/
|
|
1299
|
+
declare function useValidatePost(profileId: string): {
|
|
1300
|
+
validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
|
|
1301
|
+
publishable: boolean | undefined;
|
|
1302
|
+
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";
|
|
1304
|
+
message: string;
|
|
1305
|
+
hint?: string;
|
|
1306
|
+
allowed?: Array<string>;
|
|
1307
|
+
got?: string;
|
|
1308
|
+
variant_index: number;
|
|
1309
|
+
path: Array<string | number>;
|
|
1310
|
+
}[];
|
|
1311
|
+
isPending: boolean;
|
|
1312
|
+
error: Error | null;
|
|
1313
|
+
isReady: boolean;
|
|
1314
|
+
connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
|
|
1315
|
+
};
|
|
1285
1316
|
/**
|
|
1286
1317
|
* Update a post by id. Pass a light edit directly (`{ schedule_at }`,
|
|
1287
1318
|
* `{ tags }`, …) or a rebuilt body from `buildUpdatePost(input, connections)`
|
|
@@ -1634,4 +1665,4 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
|
|
|
1634
1665
|
* absorbs unstable media arrays). */
|
|
1635
1666
|
declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
|
|
1636
1667
|
|
|
1637
|
-
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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, QueryKey } from '@tanstack/react-query';
|
|
5
|
-
import { PostrunClient, ListProfilesQuery, DiscoverableAccountList, Connection, ConnectionKind, ConnectionStatus, ListMediaQuery, ListPostsQuery, ConnectablePlatform, MediaResource, MediaTarget, MediaKind, Metadata, ComposePostInput, XPostVariant, LinkedInPostVariant } from '@postrun/js';
|
|
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
7
|
import { TwitterComponents } from 'react-tweet';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -1282,6 +1283,36 @@ declare function useCreatePost(profileId: string): {
|
|
|
1282
1283
|
isReady: boolean;
|
|
1283
1284
|
connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
|
|
1284
1285
|
};
|
|
1286
|
+
/**
|
|
1287
|
+
* Validate a composed post WITHOUT saving or publishing it — the read-scoped
|
|
1288
|
+
* `POST /v1/posts/validate`. Builds the same best-effort variant set as
|
|
1289
|
+
* `useCreatePost` (via `buildCreatePost`), sends it, and relays the SERVER's
|
|
1290
|
+
* verdict: `publishable` (the single gate boolean) + `issues` (typed, per-variant
|
|
1291
|
+
* problems to render inline). The SDK makes NO validity judgment — the server is
|
|
1292
|
+
* the sole authority.
|
|
1293
|
+
*
|
|
1294
|
+
* It is a READ: no query-cache invalidation, no mutation handle. `validate` is a
|
|
1295
|
+
* stable callback (safe in deps); the caller debounces for live-as-you-type — the
|
|
1296
|
+
* hook never debounces internally. One call, no waterfall (connections are loaded
|
|
1297
|
+
* once by the shared `useConnections`).
|
|
1298
|
+
*/
|
|
1299
|
+
declare function useValidatePost(profileId: string): {
|
|
1300
|
+
validate: (input: Omit<ComposePostInput, "profileId">) => Promise<PostValidation>;
|
|
1301
|
+
publishable: boolean | undefined;
|
|
1302
|
+
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";
|
|
1304
|
+
message: string;
|
|
1305
|
+
hint?: string;
|
|
1306
|
+
allowed?: Array<string>;
|
|
1307
|
+
got?: string;
|
|
1308
|
+
variant_index: number;
|
|
1309
|
+
path: Array<string | number>;
|
|
1310
|
+
}[];
|
|
1311
|
+
isPending: boolean;
|
|
1312
|
+
error: Error | null;
|
|
1313
|
+
isReady: boolean;
|
|
1314
|
+
connectedChannels: ("x" | "linkedin" | "facebook_page" | "instagram" | "tiktok")[];
|
|
1315
|
+
};
|
|
1285
1316
|
/**
|
|
1286
1317
|
* Update a post by id. Pass a light edit directly (`{ schedule_at }`,
|
|
1287
1318
|
* `{ tags }`, …) or a rebuilt body from `buildUpdatePost(input, connections)`
|
|
@@ -1634,4 +1665,4 @@ declare function LinkedInPostPreviewImpl({ variant, author, media, theme, time,
|
|
|
1634
1665
|
* absorbs unstable media arrays). */
|
|
1635
1666
|
declare const LinkedInPostPreview: react.MemoExoticComponent<typeof LinkedInPostPreviewImpl>;
|
|
1636
1667
|
|
|
1637
|
-
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 };
|
|
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 };
|
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, 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, 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';
|
|
@@ -890,6 +890,37 @@ function useCreatePost(profileId) {
|
|
|
890
890
|
connectedChannels: connected.map((connection) => connection.platform).filter(isPostPlatform)
|
|
891
891
|
};
|
|
892
892
|
}
|
|
893
|
+
function useValidatePost(profileId) {
|
|
894
|
+
const { client, queryClient } = usePostrun();
|
|
895
|
+
const connections = useConnections(profileId);
|
|
896
|
+
const connected = connections.data?.data ?? [];
|
|
897
|
+
const mutation = useMutation(
|
|
898
|
+
{
|
|
899
|
+
mutationFn: async (input) => (await postsValidate({
|
|
900
|
+
client,
|
|
901
|
+
body: buildCreatePost({ ...input, profileId }, connected)
|
|
902
|
+
})).data
|
|
903
|
+
},
|
|
904
|
+
queryClient
|
|
905
|
+
);
|
|
906
|
+
const { mutateAsync } = mutation;
|
|
907
|
+
const validate = useCallback(
|
|
908
|
+
(input) => mutateAsync(input),
|
|
909
|
+
[mutateAsync]
|
|
910
|
+
);
|
|
911
|
+
const issues = mutation.data?.issues ?? [];
|
|
912
|
+
return {
|
|
913
|
+
validate,
|
|
914
|
+
// The server's verdict (undefined until the first call resolves).
|
|
915
|
+
publishable: mutation.data?.publishable,
|
|
916
|
+
issues,
|
|
917
|
+
isPending: mutation.isPending,
|
|
918
|
+
error: mutation.error,
|
|
919
|
+
// Connections must load before `validate` can resolve a channel.
|
|
920
|
+
isReady: connections.isSuccess,
|
|
921
|
+
connectedChannels: connected.map((connection) => connection.platform).filter(isPostPlatform)
|
|
922
|
+
};
|
|
923
|
+
}
|
|
893
924
|
function useUpdatePost(postId) {
|
|
894
925
|
const { client, queryClient } = usePostrun();
|
|
895
926
|
return useMutation(
|
|
@@ -1631,6 +1662,6 @@ function LinkedInPostPreviewImpl({
|
|
|
1631
1662
|
}
|
|
1632
1663
|
var LinkedInPostPreview = memo(LinkedInPostPreviewImpl);
|
|
1633
1664
|
|
|
1634
|
-
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 };
|
|
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 };
|
|
1635
1666
|
//# sourceMappingURL=index.js.map
|
|
1636
1667
|
//# sourceMappingURL=index.js.map
|