@crosspost/sdk 0.1.5 → 0.1.7
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 +380 -624
- package/dist/index.d.cts +29 -84
- package/dist/index.d.ts +29 -84
- package/dist/index.js +375 -599
- package/package.json +1 -1
- package/src/api/auth.ts +7 -7
- package/src/api/post.ts +3 -15
- package/src/api/system.ts +3 -3
- package/src/core/request.ts +33 -32
- package/src/index.ts +0 -10
- package/src/utils/error.ts +158 -199
package/package.json
CHANGED
package/src/api/auth.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import type {
|
2
|
+
ApiResponse,
|
2
3
|
AuthRevokeResponse,
|
3
4
|
AuthStatusResponse,
|
4
5
|
ConnectedAccountsResponse,
|
5
|
-
EnhancedApiResponse,
|
6
6
|
NearAuthorizationResponse,
|
7
7
|
Platform,
|
8
8
|
} from '@crosspost/types';
|
@@ -57,8 +57,8 @@ export class AuthApi {
|
|
57
57
|
async loginToPlatform(
|
58
58
|
platform: Platform,
|
59
59
|
options?: { successUrl?: string; errorUrl?: string },
|
60
|
-
): Promise<
|
61
|
-
return makeRequest<
|
60
|
+
): Promise<ApiResponse<any>> { // TODO: Refine response type based on actual API
|
61
|
+
return makeRequest<ApiResponse<any>>(
|
62
62
|
'POST',
|
63
63
|
`/auth/${platform}/login`,
|
64
64
|
this.options,
|
@@ -71,8 +71,8 @@ export class AuthApi {
|
|
71
71
|
* @param platform The target platform.
|
72
72
|
* @returns A promise resolving with the refresh response.
|
73
73
|
*/
|
74
|
-
async refreshToken(platform: Platform): Promise<
|
75
|
-
return makeRequest<
|
74
|
+
async refreshToken(platform: Platform): Promise<ApiResponse<any>> { // TODO: Refine response type
|
75
|
+
return makeRequest<ApiResponse<any>>(
|
76
76
|
'POST',
|
77
77
|
`/auth/${platform}/refresh`,
|
78
78
|
this.options,
|
@@ -84,8 +84,8 @@ export class AuthApi {
|
|
84
84
|
* @param platform The target platform.
|
85
85
|
* @returns A promise resolving with the profile refresh response.
|
86
86
|
*/
|
87
|
-
async refreshProfile(platform: Platform): Promise<
|
88
|
-
return makeRequest<
|
87
|
+
async refreshProfile(platform: Platform): Promise<ApiResponse<any>> { // TODO: Refine response type
|
88
|
+
return makeRequest<ApiResponse<any>>(
|
89
89
|
'POST',
|
90
90
|
`/auth/${platform}/refresh-profile`,
|
91
91
|
this.options,
|
package/src/api/post.ts
CHANGED
@@ -14,7 +14,6 @@ import type {
|
|
14
14
|
UnlikePostRequest,
|
15
15
|
UnlikePostResponse,
|
16
16
|
} from '@crosspost/types';
|
17
|
-
import { ApiError, ApiErrorCode } from '@crosspost/types';
|
18
17
|
import { makeRequest, type RequestOptions } from '../core/request.ts';
|
19
18
|
|
20
19
|
/**
|
@@ -93,10 +92,9 @@ export class PostApi {
|
|
93
92
|
* @returns A promise resolving with the like response.
|
94
93
|
*/
|
95
94
|
async likePost(request: LikePostRequest): Promise<LikePostResponse> {
|
96
|
-
// API endpoint uses postId in the path
|
97
95
|
return makeRequest<LikePostResponse>(
|
98
96
|
'POST',
|
99
|
-
`/api/post/like
|
97
|
+
`/api/post/like`,
|
100
98
|
this.options,
|
101
99
|
request,
|
102
100
|
);
|
@@ -108,10 +106,9 @@ export class PostApi {
|
|
108
106
|
* @returns A promise resolving with the unlike response.
|
109
107
|
*/
|
110
108
|
async unlikePost(request: UnlikePostRequest): Promise<UnlikePostResponse> {
|
111
|
-
// API endpoint uses postId in the path
|
112
109
|
return makeRequest<UnlikePostResponse>(
|
113
110
|
'DELETE',
|
114
|
-
`/api/post/like
|
111
|
+
`/api/post/like`,
|
115
112
|
this.options,
|
116
113
|
request,
|
117
114
|
);
|
@@ -123,18 +120,9 @@ export class PostApi {
|
|
123
120
|
* @returns A promise resolving with the delete response.
|
124
121
|
*/
|
125
122
|
async deletePost(request: DeletePostRequest): Promise<DeletePostResponse> {
|
126
|
-
// API endpoint uses postId in the path, assuming the first post ID for the URL
|
127
|
-
const postId = request.posts[0]?.postId || '';
|
128
|
-
if (!postId) {
|
129
|
-
throw new ApiError(
|
130
|
-
'Post ID is required for deletion path',
|
131
|
-
ApiErrorCode.VALIDATION_ERROR,
|
132
|
-
400,
|
133
|
-
);
|
134
|
-
}
|
135
123
|
return makeRequest<DeletePostResponse>(
|
136
124
|
'DELETE',
|
137
|
-
`/api/post
|
125
|
+
`/api/post`,
|
138
126
|
this.options,
|
139
127
|
request,
|
140
128
|
);
|
package/src/api/system.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { EndpointRateLimitResponse, RateLimitResponse } from '@crosspost/types';
|
1
|
+
import type { ApiResponse, EndpointRateLimitResponse, RateLimitResponse } from '@crosspost/types';
|
2
2
|
import { makeRequest, type RequestOptions } from '../core/request.ts';
|
3
3
|
|
4
4
|
/**
|
@@ -45,8 +45,8 @@ export class SystemApi {
|
|
45
45
|
* Gets the health status of the API
|
46
46
|
* @returns A promise resolving with the health status
|
47
47
|
*/
|
48
|
-
async getHealthStatus(): Promise<{ status: string }
|
49
|
-
return makeRequest<{ status: string }
|
48
|
+
async getHealthStatus(): Promise<ApiResponse<{ status: string }>> {
|
49
|
+
return makeRequest<ApiResponse<{ status: string }>>(
|
50
50
|
'GET',
|
51
51
|
'/health',
|
52
52
|
this.options,
|
package/src/core/request.ts
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
import {
|
1
|
+
import { ApiErrorCode, type StatusCode } from '@crosspost/types';
|
2
2
|
import { createAuthToken, type NearAuthData } from 'near-sign-verify';
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
apiWrapper,
|
5
|
+
createNetworkError,
|
6
|
+
CrosspostError,
|
7
|
+
handleErrorResponse,
|
8
|
+
} from '../utils/error.ts';
|
4
9
|
|
5
10
|
/**
|
6
11
|
* Options for making a request to the API
|
@@ -56,10 +61,6 @@ export async function makeRequest<T>(
|
|
56
61
|
url += `?${queryString}`;
|
57
62
|
}
|
58
63
|
}
|
59
|
-
// Check if authentication data is available
|
60
|
-
if (!options.nearAuthData) {
|
61
|
-
throw ApiError.unauthorized('Authentication required. Please provide NEAR signature.');
|
62
|
-
}
|
63
64
|
|
64
65
|
// Create a context object for error enrichment
|
65
66
|
const context = {
|
@@ -97,32 +98,30 @@ export async function makeRequest<T>(
|
|
97
98
|
try {
|
98
99
|
responseData = await response.json();
|
99
100
|
} catch (jsonError) {
|
100
|
-
// If JSON parsing fails, throw
|
101
|
+
// If JSON parsing fails, did API throw an error?
|
101
102
|
if (!response.ok) {
|
102
|
-
throw new
|
103
|
+
throw new CrosspostError(
|
103
104
|
`API request failed with status ${response.status} and non-JSON response`,
|
104
105
|
ApiErrorCode.NETWORK_ERROR,
|
105
|
-
response.status as
|
106
|
+
response.status as StatusCode,
|
106
107
|
{ originalStatusText: response.statusText },
|
107
108
|
);
|
108
109
|
}
|
109
|
-
// If response was ok but JSON failed, maybe it was an empty 204 response?
|
110
|
-
if (response.status === 204) return {} as T; // Handle No Content
|
111
110
|
// Otherwise, throw a custom error
|
112
|
-
throw new
|
111
|
+
throw new CrosspostError(
|
113
112
|
`Failed to parse JSON response: ${
|
114
113
|
jsonError instanceof Error ? jsonError.message : String(jsonError)
|
115
114
|
}`,
|
116
115
|
ApiErrorCode.INTERNAL_ERROR,
|
117
|
-
response.status as
|
116
|
+
response.status as StatusCode,
|
118
117
|
);
|
119
118
|
}
|
120
119
|
|
121
120
|
if (!response.ok) {
|
122
121
|
lastError = handleErrorResponse(responseData, response.status);
|
123
|
-
//
|
124
|
-
const shouldRetry =
|
125
|
-
|
122
|
+
// Only retry rate limit errors
|
123
|
+
const shouldRetry = lastError instanceof CrosspostError &&
|
124
|
+
lastError.code === ApiErrorCode.RATE_LIMITED;
|
126
125
|
if (shouldRetry && attempt < options.retries) {
|
127
126
|
await new Promise((resolve) => setTimeout(resolve, 1000 * Math.pow(2, attempt))); // Exponential backoff
|
128
127
|
continue; // Retry
|
@@ -130,22 +129,24 @@ export async function makeRequest<T>(
|
|
130
129
|
throw lastError; // Throw error if not retrying or retries exhausted
|
131
130
|
}
|
132
131
|
|
133
|
-
// Handle
|
134
|
-
if (
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
132
|
+
// Handle response based on success flag
|
133
|
+
if (responseData && typeof responseData === 'object' && 'success' in responseData) {
|
134
|
+
if (responseData.success) {
|
135
|
+
// Success response - return the data
|
136
|
+
return responseData.data as T;
|
137
|
+
} else {
|
138
|
+
// Error response - handle with our error utilities
|
139
|
+
lastError = handleErrorResponse(responseData, response.status);
|
140
|
+
// Only retry rate limit errors
|
141
|
+
const shouldRetry = lastError instanceof CrosspostError &&
|
142
|
+
lastError.code === ApiErrorCode.RATE_LIMITED;
|
143
|
+
if (shouldRetry && attempt < options.retries) {
|
144
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * Math.pow(2, attempt))); // Exponential backoff
|
145
|
+
continue; // Retry
|
146
|
+
}
|
147
|
+
throw lastError;
|
144
148
|
}
|
145
|
-
throw lastError;
|
146
149
|
}
|
147
|
-
|
148
|
-
return responseData as T;
|
149
150
|
} catch (error) {
|
150
151
|
clearTimeout(timeoutId); // Clear timeout on error
|
151
152
|
lastError = error instanceof Error ? error : new Error(String(error)); // Store the error
|
@@ -159,7 +160,7 @@ export async function makeRequest<T>(
|
|
159
160
|
}
|
160
161
|
|
161
162
|
// If it's not a known ApiError/PlatformError, wrap it
|
162
|
-
if (!(error instanceof
|
163
|
+
if (!(error instanceof CrosspostError)) {
|
163
164
|
throw createNetworkError(error, url, options.timeout);
|
164
165
|
}
|
165
166
|
|
@@ -169,6 +170,6 @@ export async function makeRequest<T>(
|
|
169
170
|
|
170
171
|
// Should not be reachable if retries >= 0, but needed for type safety
|
171
172
|
throw lastError ||
|
172
|
-
new
|
173
|
+
new CrosspostError('Request failed after multiple retries', ApiErrorCode.INTERNAL_ERROR, 500);
|
173
174
|
}, context);
|
174
175
|
}
|
package/src/index.ts
CHANGED
@@ -1,30 +1,20 @@
|
|
1
|
-
/**
|
2
|
-
* @crosspost/sdk
|
3
|
-
* SDK for interacting with the Crosspost API
|
4
|
-
*/
|
5
|
-
|
6
|
-
// Export main client
|
7
1
|
export { CrosspostClient } from './core/client.ts';
|
8
2
|
export type { CrosspostClientConfig } from './core/config.ts';
|
9
3
|
|
10
|
-
// Export API modules for advanced usage
|
11
4
|
export { ActivityApi } from './api/activity.ts';
|
12
5
|
export { AuthApi } from './api/auth.ts';
|
13
6
|
export { PostApi } from './api/post.ts';
|
14
7
|
export { SystemApi } from './api/system.ts';
|
15
8
|
|
16
|
-
// Export utility functions
|
17
9
|
export {
|
18
10
|
apiWrapper,
|
19
11
|
createNetworkError,
|
20
12
|
enrichErrorWithContext,
|
21
|
-
ERROR_CATEGORIES,
|
22
13
|
getErrorDetails,
|
23
14
|
getErrorMessage,
|
24
15
|
handleErrorResponse,
|
25
16
|
isAuthError,
|
26
17
|
isContentError,
|
27
|
-
isErrorOfCategory,
|
28
18
|
isMediaError,
|
29
19
|
isNetworkError,
|
30
20
|
isPlatformError,
|