@blorp-labs/piefed-api-client 0.0.0-b0dfa6b → 0.0.0-cc3101d

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/README.md CHANGED
@@ -10,18 +10,70 @@ Includes:
10
10
  ## Installation
11
11
 
12
12
  ```sh
13
- # .npmrc — point @blorp-labs scope to GitHub Packages
14
- echo "@blorp-labs:registry=https://npm.pkg.github.com" >> .npmrc
15
-
16
13
  pnpm add @blorp-labs/piefed-api-client
17
14
  ```
18
15
 
19
16
  ## Usage
20
17
 
18
+ ### Basic
19
+
20
+ ```ts
21
+ import { createClient } from '@blorp-labs/piefed-api-client';
22
+
23
+ const client = createClient('https://piefed.social');
24
+ const site = await client.getApiAlphaSite();
25
+ ```
26
+
27
+ ### With authentication
28
+
21
29
  ```ts
22
- import { getCommunity, GetCommunityParams } from '@blorp-labs/piefed-api-client';
30
+ const client = createClient('https://piefed.social', {
31
+ headers: { Authorization: 'Bearer <token>' },
32
+ });
33
+ ```
34
+
35
+ ### With default fetch options
36
+
37
+ Any [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) option (except `body` and `method`) can be set as a default:
38
+
39
+ ```ts
40
+ const client = createClient('https://piefed.social', {
41
+ cache: 'no-store',
42
+ headers: { Authorization: 'Bearer <token>' },
43
+ });
44
+ ```
45
+
46
+ Per-call options override the defaults; headers are merged.
23
47
 
24
- const community = await getCommunity({ id: 123 });
48
+ ### Multiple instances
49
+
50
+ ```ts
51
+ const a = createClient('https://instance-a.com');
52
+ const b = createClient('https://instance-b.com');
53
+ ```
54
+
55
+ ### Error handling
56
+
57
+ Errors throw an `ApiError` with `.status` and `.data`:
58
+
59
+ ```ts
60
+ import { createClient, ApiError } from '@blorp-labs/piefed-api-client';
61
+
62
+ try {
63
+ const site = await client.getApiAlphaSite();
64
+ } catch (e) {
65
+ if (e instanceof ApiError) {
66
+ console.error(e.status, e.data);
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### Zod schemas
72
+
73
+ Zod schemas are exported from the `/zod` subpath:
74
+
75
+ ```ts
76
+ import { getApiAlphaSiteQueryParams } from '@blorp-labs/piefed-api-client/zod';
25
77
  ```
26
78
 
27
79
  ## Development
@@ -37,8 +89,7 @@ pnpm build # compile TypeScript → dist/
37
89
 
38
90
  ## Automation
39
91
 
40
- A GitHub Actions workflow runs daily and on `workflow_dispatch`. If the OpenAPI spec has changed, it:
41
- 1. Regenerates `src/`
42
- 2. Bumps the patch version
43
- 3. Commits & tags the change
44
- 4. Publishes to GitHub Packages
92
+ A GitHub Actions workflow triggers on every push to `main`. It:
93
+ 1. Regenerates `src/` from the live OpenAPI spec
94
+ 2. Sets the version to `0.0.0-{commit-sha}`
95
+ 3. Builds and publishes to npm
@@ -1,232 +1,20 @@
1
- declare const allFns: {
2
- getPostApiAlphaDomainBlockUrl: () => string;
3
- postApiAlphaDomainBlock: (domainBlockRequest: import("./schemas").DomainBlockRequest, options?: RequestInit) => Promise<import("./schemas").DomainBlockResponse>;
4
- getGetApiAlphaUserUrl: (params?: import("./schemas").GetApiAlphaUserParams) => string;
5
- getApiAlphaUser: (params?: import("./schemas").GetApiAlphaUserParams, options?: RequestInit) => Promise<import("./schemas").GetUserResponse>;
6
- getGetApiAlphaUserMeUrl: () => string;
7
- getApiAlphaUserMe: (options?: RequestInit) => Promise<import("./schemas").UserMeResponse>;
8
- getPostApiAlphaUserLoginUrl: () => string;
9
- postApiAlphaUserLogin: (userLoginRequest: import("./schemas").UserLoginRequest, options?: RequestInit) => Promise<import("./schemas").UserLoginResponse>;
10
- getGetApiAlphaUserUnreadCountUrl: () => string;
11
- getApiAlphaUserUnreadCount: (options?: RequestInit) => Promise<import("./schemas").UserUnreadCountsResponse>;
12
- getGetApiAlphaUserRepliesUrl: (params?: import("./schemas").GetApiAlphaUserRepliesParams) => string;
13
- getApiAlphaUserReplies: (params?: import("./schemas").GetApiAlphaUserRepliesParams, options?: RequestInit) => Promise<import("./schemas").UserRepliesResponse>;
14
- getGetApiAlphaUserMentionsUrl: (params?: import("./schemas").GetApiAlphaUserMentionsParams) => string;
15
- getApiAlphaUserMentions: (params?: import("./schemas").GetApiAlphaUserMentionsParams, options?: RequestInit) => Promise<import("./schemas").UserMentionsResponse>;
16
- getGetApiAlphaUserMediaUrl: (params?: import("./schemas").GetApiAlphaUserMediaParams) => string;
17
- getApiAlphaUserMedia: (params?: import("./schemas").GetApiAlphaUserMediaParams, options?: RequestInit) => Promise<import("./schemas").UserMediaResponse>;
18
- getPostApiAlphaUserBlockUrl: () => string;
19
- postApiAlphaUserBlock: (userBlockRequest: import("./schemas").UserBlockRequest, options?: RequestInit) => Promise<import("./schemas").UserBlockResponse>;
20
- getPostApiAlphaUserMarkAllAsReadUrl: () => string;
21
- postApiAlphaUserMarkAllAsRead: (options?: RequestInit) => Promise<import("./schemas").UserMarkAllReadResponse>;
22
- getPutApiAlphaUserSubscribeUrl: () => string;
23
- putApiAlphaUserSubscribe: (userSubscribeRequest: import("./schemas").UserSubscribeRequest, options?: RequestInit) => Promise<import("./schemas").UserSubscribeResponse>;
24
- getPutApiAlphaUserSaveUserSettingsUrl: () => string;
25
- putApiAlphaUserSaveUserSettings: (userSaveSettingsRequest: import("./schemas").UserSaveSettingsRequest, options?: RequestInit) => Promise<import("./schemas").UserSaveSettingsResponse>;
26
- getGetApiAlphaUserNotificationsUrl: (params: import("./schemas").GetApiAlphaUserNotificationsParams) => string;
27
- getApiAlphaUserNotifications: (params: import("./schemas").GetApiAlphaUserNotificationsParams, options?: RequestInit) => Promise<import("./schemas").UserNotificationsResponse>;
28
- getPutApiAlphaUserNotificationStateUrl: () => string;
29
- putApiAlphaUserNotificationState: (userNotificationStateRequest: import("./schemas").UserNotificationStateRequest, options?: RequestInit) => Promise<import("./schemas").UserNotificationItemView>;
30
- getGetApiAlphaUserNotificationsCountUrl: () => string;
31
- getApiAlphaUserNotificationsCount: (options?: RequestInit) => Promise<import("./schemas").UserNotificationsCountResponse>;
32
- getPutApiAlphaUserMarkAllNotificationsReadUrl: () => string;
33
- putApiAlphaUserMarkAllNotificationsRead: (options?: RequestInit) => Promise<import("./schemas").UserMarkAllNotifsReadResponse>;
34
- getPostApiAlphaUserVerifyCredentialsUrl: () => string;
35
- postApiAlphaUserVerifyCredentials: (userLoginRequest: import("./schemas").UserLoginRequest, options?: RequestInit) => Promise<void>;
36
- getPostApiAlphaUserSetFlairUrl: () => string;
37
- postApiAlphaUserSetFlair: (userSetFlairRequest: import("./schemas").UserSetFlairRequest, options?: RequestInit) => Promise<import("./schemas").UserSetFlairResponse>;
38
- getPostApiAlphaUserNoteUrl: () => string;
39
- postApiAlphaUserNote: (userSetNoteRequest: import("./schemas").UserSetNoteRequest, options?: RequestInit) => Promise<import("./schemas").UserSetNoteResponse>;
40
- getPostApiAlphaUserBanUrl: () => string;
41
- postApiAlphaUserBan: (userBanRequest: import("./schemas").UserBanRequest, options?: RequestInit) => Promise<import("./schemas").UserBanResponse>;
42
- getPostApiAlphaUserUnbanUrl: () => string;
43
- postApiAlphaUserUnban: (userUnbanRequest: import("./schemas").UserUnbanRequest, options?: RequestInit) => Promise<import("./schemas").UserBanResponse>;
44
- getPostApiAlphaUploadImageUrl: () => string;
45
- postApiAlphaUploadImage: (imageUploadRequest: import("./schemas").ImageUploadRequest, options?: RequestInit) => Promise<import("./schemas").ImageUploadResponse>;
46
- getPostApiAlphaUploadCommunityImageUrl: () => string;
47
- postApiAlphaUploadCommunityImage: (imageUploadRequest: import("./schemas").ImageUploadRequest, options?: RequestInit) => Promise<import("./schemas").ImageUploadResponse>;
48
- getPostApiAlphaUploadUserImageUrl: () => string;
49
- postApiAlphaUploadUserImage: (imageUploadRequest: import("./schemas").ImageUploadRequest, options?: RequestInit) => Promise<import("./schemas").ImageUploadResponse>;
50
- getPostApiAlphaImageDeleteUrl: () => string;
51
- postApiAlphaImageDelete: (imageDeleteRequest: import("./schemas").ImageDeleteRequest, options?: RequestInit) => Promise<import("./schemas").ImageDeleteResponse>;
52
- getGetApiAlphaTopicListUrl: (params?: import("./schemas").GetApiAlphaTopicListParams) => string;
53
- getApiAlphaTopicList: (params?: import("./schemas").GetApiAlphaTopicListParams, options?: RequestInit) => Promise<import("./schemas").TopicListResponse>;
54
- getGetApiAlphaSiteUrl: () => string;
55
- getApiAlphaSite: (options?: RequestInit) => Promise<import("./schemas").GetSiteResponse>;
56
- getGetApiAlphaSiteVersionUrl: () => string;
57
- getApiAlphaSiteVersion: (options?: RequestInit) => Promise<import("./schemas").GetSiteVersionResponse>;
58
- getPostApiAlphaSiteBlockUrl: () => string;
59
- postApiAlphaSiteBlock: (blockInstanceRequest: import("./schemas").BlockInstanceRequest, options?: RequestInit) => Promise<import("./schemas").BlockInstanceResponse>;
60
- getGetApiAlphaSiteInstanceChooserUrl: () => string;
61
- getApiAlphaSiteInstanceChooser: (options?: RequestInit) => Promise<import("./schemas").GetSiteInstanceChooserResponse>;
62
- getGetApiAlphaSiteInstanceChooserSearchUrl: (params?: import("./schemas").GetApiAlphaSiteInstanceChooserSearchParams) => string;
63
- getApiAlphaSiteInstanceChooserSearch: (params?: import("./schemas").GetApiAlphaSiteInstanceChooserSearchParams, options?: RequestInit) => Promise<import("./schemas").GetSiteInstanceChooserSearchResponse>;
64
- getGetApiAlphaPrivateMessageListUrl: (params?: import("./schemas").GetApiAlphaPrivateMessageListParams) => string;
65
- getApiAlphaPrivateMessageList: (params?: import("./schemas").GetApiAlphaPrivateMessageListParams, options?: RequestInit) => Promise<import("./schemas").ListPrivateMessagesResponse>;
66
- getGetApiAlphaPrivateMessageConversationUrl: (params?: import("./schemas").GetApiAlphaPrivateMessageConversationParams) => string;
67
- getApiAlphaPrivateMessageConversation: (params?: import("./schemas").GetApiAlphaPrivateMessageConversationParams, options?: RequestInit) => Promise<import("./schemas").GetPrivateMessageConversationResponse>;
68
- getPostApiAlphaPrivateMessageConversationLeaveUrl: () => string;
69
- postApiAlphaPrivateMessageConversationLeave: (leaveConversationRequest: import("./schemas").LeaveConversationRequest, options?: RequestInit) => Promise<void>;
70
- getPostApiAlphaPrivateMessageUrl: () => string;
71
- postApiAlphaPrivateMessage: (createPrivateMessageRequest: import("./schemas").CreatePrivateMessageRequest, options?: RequestInit) => Promise<import("./schemas").PrivateMessageResponse>;
72
- getPutApiAlphaPrivateMessageUrl: () => string;
73
- putApiAlphaPrivateMessage: (editPrivateMessageRequest: import("./schemas").EditPrivateMessageRequest, options?: RequestInit) => Promise<import("./schemas").PrivateMessageResponse>;
74
- getPostApiAlphaPrivateMessageMarkAsReadUrl: () => string;
75
- postApiAlphaPrivateMessageMarkAsRead: (markPrivateMessageAsReadRequest: import("./schemas").MarkPrivateMessageAsReadRequest, options?: RequestInit) => Promise<import("./schemas").PrivateMessageResponse>;
76
- getPostApiAlphaPrivateMessageDeleteUrl: () => string;
77
- postApiAlphaPrivateMessageDelete: (deletePrivateMessageRequest: import("./schemas").DeletePrivateMessageRequest, options?: RequestInit) => Promise<import("./schemas").PrivateMessageResponse>;
78
- getPostApiAlphaPrivateMessageReportUrl: () => string;
79
- postApiAlphaPrivateMessageReport: (reportPrivateMessageRequest: import("./schemas").ReportPrivateMessageRequest, options?: RequestInit) => Promise<import("./schemas").PrivateMessageResponse>;
80
- getGetApiAlphaPostListUrl: (params?: import("./schemas").GetApiAlphaPostListParams) => string;
81
- getApiAlphaPostList: (// Two instances at the same time:
82
- params?: import("./schemas").GetApiAlphaPostListParams, options?: RequestInit) => Promise<import("./schemas").ListPostsResponse>;
83
- getGetApiAlphaPostList2Url: (params?: import("./schemas").GetApiAlphaPostList2Params) => string;
84
- getApiAlphaPostList2: (params?: import("./schemas").GetApiAlphaPostList2Params, options?: RequestInit) => Promise<import("./schemas").ListPostsResponse>;
85
- getGetApiAlphaPostUrl: (params: import("./schemas").GetApiAlphaPostParams) => string;
86
- getApiAlphaPost: (params: import("./schemas").GetApiAlphaPostParams, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
87
- getPostApiAlphaPostUrl: () => string;
88
- postApiAlphaPost: (createPostRequest: import("./schemas").CreatePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
89
- getPutApiAlphaPostUrl: () => string;
90
- putApiAlphaPost: (editPostRequest: import("./schemas").EditPostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
91
- getGetApiAlphaPostRepliesUrl: (params?: import("./schemas").GetApiAlphaPostRepliesParams) => string;
92
- getApiAlphaPostReplies: (params?: import("./schemas").GetApiAlphaPostRepliesParams, options?: RequestInit) => Promise<import("./schemas").GetPostRepliesResponse>;
93
- getGetApiAlphaPostSiteMetadataUrl: (params?: import("./schemas").GetApiAlphaPostSiteMetadataParams) => string;
94
- getApiAlphaPostSiteMetadata: (params?: import("./schemas").GetApiAlphaPostSiteMetadataParams, options?: RequestInit) => Promise<import("./schemas").GetSiteMetadataResponse>;
95
- getPostApiAlphaPostLikeUrl: () => string;
96
- postApiAlphaPostLike: (likePostRequest: import("./schemas").LikePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
97
- getPutApiAlphaPostSaveUrl: () => string;
98
- putApiAlphaPostSave: (savePostRequest: import("./schemas").SavePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
99
- getPutApiAlphaPostSubscribeUrl: () => string;
100
- putApiAlphaPostSubscribe: (subscribePostRequest: import("./schemas").SubscribePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
101
- getPostApiAlphaPostDeleteUrl: () => string;
102
- postApiAlphaPostDelete: (deletePostRequest: import("./schemas").DeletePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
103
- getPostApiAlphaPostReportUrl: () => string;
104
- postApiAlphaPostReport: (reportPostRequest: import("./schemas").ReportPostRequest, options?: RequestInit) => Promise<import("./schemas").PostReportResponse>;
105
- getPostApiAlphaPostLockUrl: () => string;
106
- postApiAlphaPostLock: (lockPostRequest: import("./schemas").LockPostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
107
- getPostApiAlphaPostHideUrl: () => string;
108
- postApiAlphaPostHide: (hidePostRequest: import("./schemas").HidePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
109
- getPostApiAlphaPostFeatureUrl: () => string;
110
- postApiAlphaPostFeature: (featurePostRequest: import("./schemas").FeaturePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
111
- getPostApiAlphaPostRemoveUrl: () => string;
112
- postApiAlphaPostRemove: (removePostRequest: import("./schemas").RemovePostRequest, options?: RequestInit) => Promise<import("./schemas").GetPostResponse>;
113
- getPostApiAlphaPostMarkAsReadUrl: () => string;
114
- postApiAlphaPostMarkAsRead: (markPostAsReadRequest: import("./schemas").MarkPostAsReadRequest, options?: RequestInit) => Promise<import("./schemas").SuccessResponse>;
115
- getGetApiAlphaPostLikeListUrl: (params: import("./schemas").GetApiAlphaPostLikeListParams) => string;
116
- getApiAlphaPostLikeList: (params: import("./schemas").GetApiAlphaPostLikeListParams, options?: RequestInit) => Promise<import("./schemas").ListPostLikesResponse>;
117
- getPostApiAlphaPostAssignFlairUrl: () => string;
118
- postApiAlphaPostAssignFlair: (postSetFlairRequest: import("./schemas").PostSetFlairRequest, options?: RequestInit) => Promise<import("./schemas").PostSetFlairResponse>;
119
- getPostApiAlphaPostPollVoteUrl: () => string;
120
- postApiAlphaPostPollVote: (pollVoteRequest: import("./schemas").PollVoteRequest, options?: RequestInit) => Promise<import("./schemas").PollVoteResponse>;
121
- getGetApiAlphaSearchUrl: (params: import("./schemas").GetApiAlphaSearchParams) => string;
122
- getApiAlphaSearch: (params: import("./schemas").GetApiAlphaSearchParams, options?: RequestInit) => Promise<import("./schemas").SearchResponse>;
123
- getGetApiAlphaResolveObjectUrl: (params: import("./schemas").GetApiAlphaResolveObjectParams) => string;
124
- getApiAlphaResolveObject: (params: import("./schemas").GetApiAlphaResolveObjectParams, // options is always the last argument; inject baseUrl and defaults into it
125
- options?: RequestInit) => Promise<import("./schemas").ResolveObjectResponse>;
126
- getGetApiAlphaFederatedInstancesUrl: () => string;
127
- getApiAlphaFederatedInstances: (options?: RequestInit) => Promise<import("./schemas").GetFederatedInstancesResponse>;
128
- getGetApiAlphaSuggestCompletionUrl: (params?: import("./schemas").GetApiAlphaSuggestCompletionParams) => string;
129
- getApiAlphaSuggestCompletion: (params?: import("./schemas").GetApiAlphaSuggestCompletionParams, options?: RequestInit) => Promise<import("./schemas").GetSuggestCompletionResponse>;
130
- getGetApiAlphaModlogUrl: (params?: import("./schemas").GetApiAlphaModlogParams) => string;
131
- getApiAlphaModlog: (params?: import("./schemas").GetApiAlphaModlogParams, options?: RequestInit) => Promise<import("./schemas").GetModLogResponse>;
132
- getGetApiAlphaFeedUrl: (params?: import("./schemas").GetApiAlphaFeedParams) => string;
133
- getApiAlphaFeed: (params?: import("./schemas").GetApiAlphaFeedParams, options?: RequestInit) => Promise<import("./schemas").FeedView>;
134
- getPostApiAlphaFeedUrl: () => string;
135
- postApiAlphaFeed: (createFeedRequest: import("./schemas").CreateFeedRequest, options?: RequestInit) => Promise<import("./schemas").FeedView>;
136
- getPutApiAlphaFeedUrl: () => string;
137
- putApiAlphaFeed: (editFeedRequest: import("./schemas").EditFeedRequest, options?: RequestInit) => Promise<import("./schemas").FeedView>;
138
- getGetApiAlphaFeedListUrl: (params?: import("./schemas").GetApiAlphaFeedListParams) => string;
139
- getApiAlphaFeedList: (params?: import("./schemas").GetApiAlphaFeedListParams, options?: RequestInit) => Promise<import("./schemas").FeedListResponse>;
140
- getPostApiAlphaFeedFollowUrl: () => string;
141
- postApiAlphaFeedFollow: (followFeedRequest: import("./schemas").FollowFeedRequest, options?: RequestInit) => Promise<import("./schemas").FeedView>;
142
- getPostApiAlphaFeedDeleteUrl: () => string;
143
- postApiAlphaFeedDelete: (deleteFeedRequest: import("./schemas").DeleteFeedRequest, options?: RequestInit) => Promise<import("./schemas").FeedView>;
144
- getGetApiAlphaCommunityUrl: (params?: import("./schemas").GetApiAlphaCommunityParams) => string;
145
- getApiAlphaCommunity: (params?: import("./schemas").GetApiAlphaCommunityParams, options?: RequestInit) => Promise<import("./schemas").GetCommunityResponse>;
146
- getPostApiAlphaCommunityUrl: () => string;
147
- postApiAlphaCommunity: (createCommunityRequest: import("./schemas").CreateCommunityRequest, options?: RequestInit) => Promise<import("./schemas").CommunityResponse>;
148
- getPutApiAlphaCommunityUrl: () => string;
149
- putApiAlphaCommunity: (editCommunityRequest: import("./schemas").EditCommunityRequest, options?: RequestInit) => Promise<import("./schemas").CommunityResponse>;
150
- getGetApiAlphaCommunityListUrl: (params?: import("./schemas").GetApiAlphaCommunityListParams) => string;
151
- getApiAlphaCommunityList: (params?: import("./schemas").GetApiAlphaCommunityListParams, options?: RequestInit) => Promise<import("./schemas").ListCommunitiesResponse>;
152
- getPostApiAlphaCommunityFollowUrl: () => string;
153
- postApiAlphaCommunityFollow: (followCommunityRequest: import("./schemas").FollowCommunityRequest, options?: RequestInit) => Promise<import("./schemas").CommunityResponse>;
154
- getPostApiAlphaCommunityLeaveAllUrl: () => string;
155
- postApiAlphaCommunityLeaveAll: (options?: RequestInit) => Promise<import("./schemas").UserMeResponse>;
156
- getPostApiAlphaCommunityBlockUrl: () => string;
157
- postApiAlphaCommunityBlock: (blockCommunityRequest: import("./schemas").BlockCommunityRequest, options?: RequestInit) => Promise<import("./schemas").BlockCommunityResponse>;
158
- getPutApiAlphaCommunitySubscribeUrl: () => string;
159
- putApiAlphaCommunitySubscribe: (subscribeCommunityRequest: import("./schemas").SubscribeCommunityRequest, options?: RequestInit) => Promise<import("./schemas").CommunityResponse>;
160
- getPostApiAlphaCommunityDeleteUrl: () => string;
161
- postApiAlphaCommunityDelete: (deleteCommunityRequest: import("./schemas").DeleteCommunityRequest, options?: RequestInit) => Promise<import("./schemas").CommunityResponse>;
162
- getPostApiAlphaCommunityModUrl: () => string;
163
- postApiAlphaCommunityMod: (modCommunityRequest: import("./schemas").ModCommunityRequest, options?: RequestInit) => Promise<import("./schemas").ModCommunityResponse>;
164
- getGetApiAlphaCommunityModerateBansUrl: (params: import("./schemas").GetApiAlphaCommunityModerateBansParams) => string;
165
- getApiAlphaCommunityModerateBans: (params: import("./schemas").GetApiAlphaCommunityModerateBansParams, options?: RequestInit) => Promise<import("./schemas").CommunityModerationBansListResponse>;
166
- getPutApiAlphaCommunityModerateUnbanUrl: () => string;
167
- putApiAlphaCommunityModerateUnban: (communityModerationUnbanRequest: import("./schemas").CommunityModerationUnbanRequest, options?: RequestInit) => Promise<import("./schemas").CommunityModerationBanItem>;
168
- getPostApiAlphaCommunityModerateBanUrl: () => string;
169
- postApiAlphaCommunityModerateBan: (communityModerationBanRequest: import("./schemas").CommunityModerationBanRequest, options?: RequestInit) => Promise<import("./schemas").CommunityModerationBanItem>;
170
- getPostApiAlphaCommunityModeratePostNsfwUrl: () => string;
171
- postApiAlphaCommunityModeratePostNsfw: (communityModerationNsfwRequest: import("./schemas").CommunityModerationNsfwRequest, options?: RequestInit) => Promise<import("./schemas").PostView>;
172
- getPostApiAlphaCommunityFlairUrl: () => string;
173
- postApiAlphaCommunityFlair: (communityFlairCreateRequest: import("./schemas").CommunityFlairCreateRequest, options?: RequestInit) => Promise<import("./schemas").CommunityFlairCreateResponse>;
174
- getPutApiAlphaCommunityFlairUrl: () => string;
175
- putApiAlphaCommunityFlair: (communityFlairEditRequest: import("./schemas").CommunityFlairEditRequest, options?: RequestInit) => Promise<import("./schemas").CommunityFlairEditResponse>;
176
- getPostApiAlphaCommunityFlairDeleteUrl: () => string;
177
- postApiAlphaCommunityFlairDelete: (communityFlairDeleteRequest: import("./schemas").CommunityFlairDeleteRequest, options?: RequestInit) => Promise<import("./schemas").CommunityFlairDeleteResponse>;
178
- getGetApiAlphaCommentListUrl: (params?: import("./schemas").GetApiAlphaCommentListParams) => string;
179
- getApiAlphaCommentList: (params?: import("./schemas").GetApiAlphaCommentListParams, options?: RequestInit) => Promise<import("./schemas").ListCommentsResponse>;
180
- getPostApiAlphaCommentLikeUrl: () => string;
181
- postApiAlphaCommentLike: (likeCommentRequest: import("./schemas").LikeCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
182
- getPutApiAlphaCommentSaveUrl: () => string;
183
- putApiAlphaCommentSave: (saveCommentRequest: import("./schemas").SaveCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
184
- getPutApiAlphaCommentSubscribeUrl: () => string;
185
- putApiAlphaCommentSubscribe: (subscribeCommentRequest: import("./schemas").SubscribeCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
186
- getPostApiAlphaCommentUrl: () => string;
187
- postApiAlphaComment: (createCommentRequest: import("./schemas").CreateCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
188
- getPutApiAlphaCommentUrl: () => string;
189
- putApiAlphaComment: (editCommentRequest: import("./schemas").EditCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
190
- getGetApiAlphaCommentUrl: (params: import("./schemas").GetApiAlphaCommentParams) => string;
191
- getApiAlphaComment: (params: import("./schemas").GetApiAlphaCommentParams, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
192
- getPostApiAlphaCommentDeleteUrl: () => string;
193
- postApiAlphaCommentDelete: (deleteCommentRequest: import("./schemas").DeleteCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
194
- getPostApiAlphaCommentReportUrl: () => string;
195
- postApiAlphaCommentReport: (reportCommentRequest: import("./schemas").ReportCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentReportResponse>;
196
- getPostApiAlphaCommentRemoveUrl: () => string;
197
- postApiAlphaCommentRemove: (removeCommentRequest: import("./schemas").RemoveCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
198
- getPostApiAlphaCommentMarkAsReadUrl: () => string;
199
- postApiAlphaCommentMarkAsRead: (markCommentAsReadRequest: import("./schemas").MarkCommentAsReadRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentReplyResponse>;
200
- getPostApiAlphaCommentMarkAsAnswerUrl: () => string;
201
- postApiAlphaCommentMarkAsAnswer: (markCommentAsAnswerRequest: import("./schemas").MarkCommentAsAnswerRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentReplyResponse>;
202
- getPostApiAlphaCommentLockUrl: () => string;
203
- postApiAlphaCommentLock: (lockCommentRequest: import("./schemas").LockCommentRequest, options?: RequestInit) => Promise<import("./schemas").GetCommentResponse>;
204
- getGetApiAlphaCommentLikeListUrl: (params: import("./schemas").GetApiAlphaCommentLikeListParams) => string;
205
- getApiAlphaCommentLikeList: (params: import("./schemas").GetApiAlphaCommentLikeListParams, options?: RequestInit) => Promise<import("./schemas").ListCommentLikesResponse>;
206
- getGetApiAlphaAdminRegistrationApplicationListUrl: (params?: import("./schemas").GetApiAlphaAdminRegistrationApplicationListParams) => string;
207
- getApiAlphaAdminRegistrationApplicationList: (params?: import("./schemas").GetApiAlphaAdminRegistrationApplicationListParams, options?: RequestInit /**
208
- * Create a client bound to a specific PieFed instance.
209
- *
210
- * @example
211
- * const client = createClient('https://piefed.social');
212
- * const site = await client.getApiAlphaSite();
213
- *
214
- * // With auth:
215
- * const client = createClient('https://piefed.social', {
216
- * headers: { Authorization: 'Bearer <token>' },
217
- * });
218
- *
219
- * // Two instances at the same time:
220
- * const a = createClient('https://instance-a.com');
221
- * const b = createClient('https://instance-b.com');
222
- */) => Promise<import("./schemas").GetRegistrationListResponse>;
223
- getPutApiAlphaAdminRegistrationApplicationApproveUrl: () => string;
224
- putApiAlphaAdminRegistrationApplicationApprove: (registrationApproveRequest: import("./schemas").RegistrationApproveRequest, options?: RequestInit) => Promise<void>;
225
- };
1
+ import * as admin from './client/admin/admin';
2
+ import * as comment from './client/comment/comment';
3
+ import * as community from './client/community/community';
4
+ import * as feed from './client/feed/feed';
5
+ import * as misc from './client/misc/misc';
6
+ import * as post from './client/post/post';
7
+ import * as privateMessage from './client/private-message/private-message';
8
+ import * as site from './client/site/site';
9
+ import * as topic from './client/topic/topic';
10
+ import * as upload from './client/upload/upload';
11
+ import * as user from './client/user/user';
226
12
  type AsyncFn = (...args: any[]) => Promise<any>;
227
- type ApiFunctions = {
228
- [K in keyof typeof allFns as (typeof allFns)[K] extends AsyncFn ? K : never]: (typeof allFns)[K];
229
- };
13
+ type AllModules = typeof admin & typeof comment & typeof community & typeof feed & typeof misc & typeof post & typeof privateMessage & typeof site & typeof topic & typeof upload & typeof user;
14
+ type AsyncKeys = {
15
+ [K in keyof AllModules]: AllModules[K] extends AsyncFn ? K : never;
16
+ }[keyof AllModules];
17
+ type ApiFunctions = Pick<AllModules, AsyncKeys>;
230
18
  interface CreateClientOptions extends Omit<RequestInit, 'body' | 'method'> {
231
19
  /** Default headers merged into every request (e.g. Authorization). */
232
20
  headers?: Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,SAAS,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,cAAc,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAiB3C,KAAK,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAChD,KAAK,UAAU,GACb,OAAO,KAAK,GAAG,OAAO,OAAO,GAAG,OAAO,SAAS,GAAG,OAAO,IAAI,GAAG,OAAO,IAAI,GAC5E,OAAO,IAAI,GAAG,OAAO,cAAc,GAAG,OAAO,IAAI,GAAG,OAAO,KAAK,GAAG,OAAO,MAAM,GAAG,OAAO,IAAI,CAAC;AACjG,KAAK,SAAS,GAAG;KAAG,CAAC,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC,MAAM,UAAU,CAAC,CAAC;AAC1G,KAAK,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEhD,UAAU,mBAAoB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxE,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,YAAY,CA+B7F"}
@@ -79,31 +79,23 @@ function createClient(baseUrl, options = {}) {
79
79
  for (const [key, fn] of Object.entries(allFns)) {
80
80
  if (typeof fn !== 'function')
81
81
  continue;
82
+ // fn.length is the total param count; options is always the last param
83
+ const optionsIndex = fn.length - 1;
82
84
  boundFns[key] = (...args) => {
83
- // options is always the last argument; inject baseUrl and defaults into it
84
- const last = args[args.length - 1];
85
+ // Pad args so options index is always reachable
86
+ while (args.length <= optionsIndex)
87
+ args.push(undefined);
85
88
  const { headers: defaultHeaders, ...defaultInit } = options;
86
89
  const extra = { ...defaultInit, baseUrl };
87
- if (last !== null && typeof last === 'object' && !Array.isArray(last)) {
88
- const lastObj = last;
89
- args[args.length - 1] = {
90
- ...extra,
91
- ...lastObj,
92
- // per-call headers win, but default headers fill in any gaps
93
- headers: { ...defaultHeaders, ...lastObj.headers },
94
- };
95
- }
96
- else if (last === undefined || args.length === 0) {
97
- if (args.length > 0) {
98
- args[args.length - 1] = { ...extra, headers: defaultHeaders };
99
- }
100
- else {
101
- args.push({ ...extra, headers: defaultHeaders });
102
- }
103
- }
104
- else {
105
- args.push({ ...extra, headers: defaultHeaders });
106
- }
90
+ const existing = args[optionsIndex];
91
+ args[optionsIndex] = {
92
+ ...extra,
93
+ ...existing,
94
+ headers: {
95
+ ...defaultHeaders,
96
+ ...existing?.headers,
97
+ },
98
+ };
107
99
  return fn(...args);
108
100
  };
109
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-client.js","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,oCAiCC;AAtFD,4DAA8C;AAC9C,kEAAoD;AACpD,wEAA0D;AAC1D,yDAA2C;AAC3C,yDAA2C;AAC3C,yDAA2C;AAC3C,yFAA2E;AAC3E,yDAA2C;AAC3C,4DAA8C;AAC9C,+DAAiD;AACjD,yDAA2C;AAE3C,MAAM,MAAM,GAAG;IACb,GAAG,KAAK;IACR,GAAG,OAAO;IACV,GAAG,SAAS;IACZ,GAAG,IAAI;IACP,GAAG,IAAI;IACP,GAAG,IAAI;IACP,GAAG,cAAc;IACjB,GAAG,IAAI;IACP,GAAG,KAAK;IACR,GAAG,MAAM;IACT,GAAG,IAAI;CACR,CAAC;AAaF;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,YAAY,CAAC,OAAe,EAAE,UAA+B,EAAE;IAC7E,MAAM,QAAQ,GAAG,EAA6B,CAAC;IAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,EAAE,KAAK,UAAU;YAAE,SAAS;QAEvC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;YACrC,2EAA2E;YAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;YAC5D,MAAM,KAAK,GAAsC,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC;YAC7E,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtE,MAAM,OAAO,GAAG,IAA0C,CAAC;gBAC3D,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;oBACtB,GAAG,KAAK;oBACR,GAAG,OAAO;oBACV,6DAA6D;oBAC7D,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,GAAI,OAAO,CAAC,OAA8C,EAAE;iBAC3F,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;gBAChE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,OAAQ,EAAc,CAAC,GAAG,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,QAAwB,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"create-client.js","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,oCA+BC;AAtFD,4DAA8C;AAC9C,kEAAoD;AACpD,wEAA0D;AAC1D,yDAA2C;AAC3C,yDAA2C;AAC3C,yDAA2C;AAC3C,yFAA2E;AAC3E,yDAA2C;AAC3C,4DAA8C;AAC9C,+DAAiD;AACjD,yDAA2C;AAE3C,MAAM,MAAM,GAAG;IACb,GAAG,KAAK;IACR,GAAG,OAAO;IACV,GAAG,SAAS;IACZ,GAAG,IAAI;IACP,GAAG,IAAI;IACP,GAAG,IAAI;IACP,GAAG,cAAc;IACjB,GAAG,IAAI;IACP,GAAG,KAAK;IACR,GAAG,MAAM;IACT,GAAG,IAAI;CACR,CAAC;AAeF;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,YAAY,CAAC,OAAe,EAAE,UAA+B,EAAE;IAC7E,MAAM,QAAQ,GAAG,EAA6B,CAAC;IAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,EAAE,KAAK,UAAU;YAAE,SAAS;QAEvC,uEAAuE;QACvE,MAAM,YAAY,GAAI,EAAc,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhD,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;YACrC,gDAAgD;YAChD,OAAO,IAAI,CAAC,MAAM,IAAI,YAAY;gBAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEzD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;YAC5D,MAAM,KAAK,GAAsC,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC;YAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAqD,CAAC;YAExF,IAAI,CAAC,YAAY,CAAC,GAAG;gBACnB,GAAG,KAAK;gBACR,GAAG,QAAQ;gBACX,OAAO,EAAE;oBACP,GAAG,cAAc;oBACjB,GAAI,QAAQ,EAAE,OAA8C;iBAC7D;aACF,CAAC;YAEF,OAAQ,EAAc,CAAC,GAAG,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,QAAwB,CAAC;AAClC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { configure, ApiError } from './mutator/custom-fetch';
1
+ export { ApiError } from './mutator/custom-fetch';
2
2
  export { createClient } from './create-client';
3
3
  export * from './schemas/index';
4
4
  export * from './client/admin/admin';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,cAAc,iBAAiB,CAAC;AAGhC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,cAAc,iBAAiB,CAAC;AAGhC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -14,10 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.createClient = exports.ApiError = exports.configure = void 0;
17
+ exports.createClient = exports.ApiError = void 0;
18
18
  // Configuration and client factory
19
19
  var custom_fetch_1 = require("./mutator/custom-fetch");
20
- Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return custom_fetch_1.configure; } });
21
20
  Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return custom_fetch_1.ApiError; } });
22
21
  var create_client_1 = require("./create-client");
23
22
  Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return create_client_1.createClient; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAmC;AACnC,uDAA6D;AAApD,yGAAA,SAAS,OAAA;AAAE,wGAAA,QAAQ,OAAA;AAC5B,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,+CAA+C;AAC/C,kDAAgC;AAEhC,0DAA0D;AAC1D,uDAAqC;AACrC,2DAAyC;AACzC,+DAA6C;AAC7C,qDAAmC;AACnC,qDAAmC;AACnC,qDAAmC;AACnC,2EAAyD;AACzD,qDAAmC;AACnC,uDAAqC;AACrC,yDAAuC;AACvC,qDAAmC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAmC;AACnC,uDAAkD;AAAzC,wGAAA,QAAQ,OAAA;AACjB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,+CAA+C;AAC/C,kDAAgC;AAEhC,0DAA0D;AAC1D,uDAAqC;AACrC,2DAAyC;AACzC,+DAA6C;AAC7C,qDAAmC;AACnC,qDAAmC;AACnC,qDAAmC;AACnC,2EAAyD;AACzD,qDAAmC;AACnC,uDAAqC;AACrC,yDAAuC;AACvC,qDAAmC"}
@@ -4,9 +4,6 @@ declare global {
4
4
  baseUrl?: string;
5
5
  }
6
6
  }
7
- export declare function configure(options: {
8
- baseUrl: string;
9
- }): void;
10
7
  export declare class ApiError extends Error {
11
8
  readonly status: number;
12
9
  readonly data: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-fetch.d.ts","sourceRoot":"","sources":["../../src/mutator/custom-fetch.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;CACF;AAID,wBAAgB,SAAS,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,QAErD;AAED,qBAAa,QAAS,SAAQ,KAAK;aAEf,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;gBADb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO;CAKhC;AAED,eAAO,MAAM,WAAW,GAAU,CAAC,EACjC,KAAK,MAAM,EACX,UAAU,WAAW,KACpB,OAAO,CAAC,CAAC,CAaX,CAAC"}
1
+ {"version":3,"file":"custom-fetch.d.ts","sourceRoot":"","sources":["../../src/mutator/custom-fetch.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;CACF;AAED,qBAAa,QAAS,SAAQ,KAAK;aAEf,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;gBADb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO;CAKhC;AAED,eAAO,MAAM,WAAW,GAAU,CAAC,EACjC,KAAK,MAAM,EACX,UAAU,WAAW,KACpB,OAAO,CAAC,CAAC,CAcX,CAAC"}
@@ -1,11 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.customFetch = exports.ApiError = void 0;
4
- exports.configure = configure;
5
- let _defaultBaseUrl = 'https://piefed.social';
6
- function configure(options) {
7
- _defaultBaseUrl = options.baseUrl.replace(/\/$/, '');
8
- }
9
4
  class ApiError extends Error {
10
5
  status;
11
6
  data;
@@ -18,7 +13,9 @@ class ApiError extends Error {
18
13
  }
19
14
  exports.ApiError = ApiError;
20
15
  const customFetch = async (url, options) => {
21
- const { baseUrl = _defaultBaseUrl, ...fetchOptions } = options ?? {};
16
+ const { baseUrl, ...fetchOptions } = options ?? {};
17
+ if (!baseUrl)
18
+ throw new Error('baseUrl is required — use createClient() to make requests');
22
19
  const base = baseUrl.replace(/\/$/, '');
23
20
  const res = await fetch(`${base}${url}`, fetchOptions);
24
21
  const body = [204, 205, 304].includes(res.status) ? null : await res.text();
@@ -1 +1 @@
1
- {"version":3,"file":"custom-fetch.js","sourceRoot":"","sources":["../../src/mutator/custom-fetch.ts"],"names":[],"mappings":";;;AAWA,8BAEC;AAJD,IAAI,eAAe,GAAG,uBAAuB,CAAC;AAE9C,SAAgB,SAAS,CAAC,OAA4B;IACpD,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAa,QAAS,SAAQ,KAAK;IAEf;IACA;IAFlB,YACkB,MAAc,EACd,IAAa;QAE7B,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;QAHb,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AARD,4BAQC;AAEM,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAW,EACX,OAAqB,EACT,EAAE;IACd,MAAM,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,IAAS,CAAC;AACnB,CAAC,CAAC;AAhBW,QAAA,WAAW,eAgBtB"}
1
+ {"version":3,"file":"custom-fetch.js","sourceRoot":"","sources":["../../src/mutator/custom-fetch.ts"],"names":[],"mappings":";;;AASA,MAAa,QAAS,SAAQ,KAAK;IAEf;IACA;IAFlB,YACkB,MAAc,EACd,IAAa;QAE7B,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;QAHb,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AARD,4BAQC;AAEM,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAW,EACX,OAAqB,EACT,EAAE;IACd,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,IAAS,CAAC;AACnB,CAAC,CAAC;AAjBW,QAAA,WAAW,eAiBtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blorp-labs/piefed-api-client",
3
- "version": "0.0.0-b0dfa6b",
3
+ "version": "0.0.0-cc3101d",
4
4
  "description": "Typed TypeScript client for the PieFed API, generated from the OpenAPI spec",
5
5
  "packageManager": "pnpm@10.6.5",
6
6
  "main": "./dist/index.js",
@@ -22,14 +22,16 @@
22
22
  "scripts": {
23
23
  "generate": "orval --config orval.config.ts",
24
24
  "build": "tsc",
25
- "prepublishOnly": "pnpm build"
25
+ "prepublishOnly": "pnpm build",
26
+ "test": "vitest run"
26
27
  },
27
28
  "dependencies": {
28
29
  "zod": "^3.23.8"
29
30
  },
30
31
  "devDependencies": {
31
32
  "orval": "^7.3.0",
32
- "typescript": "^5.7.3"
33
+ "typescript": "^5.7.3",
34
+ "vitest": "^2.0.0"
33
35
  },
34
36
  "repository": {
35
37
  "type": "git",
@@ -0,0 +1,269 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { createClient } from '../create-client';
3
+ import { ApiError } from '../mutator/custom-fetch';
4
+
5
+ const BASE_URL = 'https://test.example.com';
6
+
7
+ function makeResponse(body: unknown, status = 200) {
8
+ return new Response(JSON.stringify(body), {
9
+ status,
10
+ headers: { 'Content-Type': 'application/json' },
11
+ });
12
+ }
13
+
14
+ let fetchSpy: ReturnType<typeof vi.fn>;
15
+
16
+ beforeEach(() => {
17
+ fetchSpy = vi.fn().mockImplementation(() => Promise.resolve(makeResponse({ ok: true })));
18
+ vi.stubGlobal('fetch', fetchSpy);
19
+ });
20
+
21
+ afterEach(() => vi.unstubAllGlobals());
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Helpers
25
+ // ---------------------------------------------------------------------------
26
+
27
+ function lastCall() {
28
+ return fetchSpy.mock.calls[fetchSpy.mock.calls.length - 1] as [string, RequestInit];
29
+ }
30
+
31
+ function lastUrl() {
32
+ return lastCall()[0];
33
+ }
34
+
35
+ function lastOptions() {
36
+ return lastCall()[1];
37
+ }
38
+
39
+ function lastHeaders(): Record<string, string> {
40
+ return (lastOptions().headers ?? {}) as Record<string, string>;
41
+ }
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // GET no-params (fn.length = 1): getApiAlphaSite(options?)
45
+ // ---------------------------------------------------------------------------
46
+
47
+ describe('getApiAlphaSite — GET, no params', () => {
48
+ it('forwards default headers', async () => {
49
+ const client = createClient(BASE_URL, {
50
+ headers: { Authorization: 'Bearer tok' },
51
+ });
52
+ await client.getApiAlphaSite();
53
+ expect(lastHeaders()['Authorization']).toBe('Bearer tok');
54
+ });
55
+
56
+ it('merges per-call headers on top of defaults (per-call wins)', async () => {
57
+ const client = createClient(BASE_URL, {
58
+ headers: { Authorization: 'Bearer default', 'X-Custom': 'base' },
59
+ });
60
+ await client.getApiAlphaSite({ headers: { Authorization: 'Bearer override' } });
61
+ expect(lastHeaders()['Authorization']).toBe('Bearer override');
62
+ expect(lastHeaders()['X-Custom']).toBe('base');
63
+ });
64
+
65
+ it('forwards default RequestInit options (e.g. cache)', async () => {
66
+ const client = createClient(BASE_URL, { cache: 'no-store' });
67
+ await client.getApiAlphaSite();
68
+ expect(lastOptions().cache).toBe('no-store');
69
+ });
70
+
71
+ it('per-call RequestInit options override defaults', async () => {
72
+ const client = createClient(BASE_URL, { cache: 'no-store' });
73
+ await client.getApiAlphaSite({ cache: 'force-cache' });
74
+ expect(lastOptions().cache).toBe('force-cache');
75
+ });
76
+
77
+ it('prepends baseUrl to the path', async () => {
78
+ const client = createClient(BASE_URL);
79
+ await client.getApiAlphaSite();
80
+ expect(lastUrl()).toBe(`${BASE_URL}/api/alpha/site`);
81
+ });
82
+ });
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // GET optional-params (fn.length = 2): getApiAlphaPostList(params?, options?)
86
+ // ---------------------------------------------------------------------------
87
+
88
+ describe('getApiAlphaPostList — GET, optional params', () => {
89
+ it('forwards default headers when params are provided', async () => {
90
+ const client = createClient(BASE_URL, {
91
+ headers: { Authorization: 'Bearer tok' },
92
+ });
93
+ await client.getApiAlphaPostList({ page: 1 });
94
+ expect(lastHeaders()['Authorization']).toBe('Bearer tok');
95
+ });
96
+
97
+ it('forwards default headers when params are omitted', async () => {
98
+ const client = createClient(BASE_URL, {
99
+ headers: { Authorization: 'Bearer tok' },
100
+ });
101
+ await client.getApiAlphaPostList();
102
+ expect(lastHeaders()['Authorization']).toBe('Bearer tok');
103
+ });
104
+
105
+ it('merges per-call headers (options as second arg)', async () => {
106
+ const client = createClient(BASE_URL, {
107
+ headers: { Authorization: 'Bearer default' },
108
+ });
109
+ await client.getApiAlphaPostList(
110
+ { page: 1 },
111
+ { headers: { Authorization: 'Bearer override' } },
112
+ );
113
+ expect(lastHeaders()['Authorization']).toBe('Bearer override');
114
+ });
115
+
116
+ it('constructs correct URL with query params', async () => {
117
+ const client = createClient(BASE_URL);
118
+ await client.getApiAlphaPostList({ page: 2 });
119
+ expect(lastUrl()).toContain(`${BASE_URL}/api/alpha/post/list`);
120
+ expect(lastUrl()).toContain('page=2');
121
+ });
122
+ });
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // GET required-params (fn.length = 2): getApiAlphaPost(params, options?)
126
+ // ---------------------------------------------------------------------------
127
+
128
+ describe('getApiAlphaPost — GET, required params', () => {
129
+ const params = { id: 42 };
130
+
131
+ it('forwards default headers', async () => {
132
+ const client = createClient(BASE_URL, {
133
+ headers: { Authorization: 'Bearer tok' },
134
+ });
135
+ await client.getApiAlphaPost(params);
136
+ expect(lastHeaders()['Authorization']).toBe('Bearer tok');
137
+ });
138
+
139
+ it('merges per-call headers', async () => {
140
+ const client = createClient(BASE_URL, {
141
+ headers: { Authorization: 'Bearer default' },
142
+ });
143
+ await client.getApiAlphaPost(params, { headers: { Authorization: 'Bearer override' } });
144
+ expect(lastHeaders()['Authorization']).toBe('Bearer override');
145
+ });
146
+
147
+ it('forwards default cache option', async () => {
148
+ const client = createClient(BASE_URL, { cache: 'no-store' });
149
+ await client.getApiAlphaPost(params);
150
+ expect(lastOptions().cache).toBe('no-store');
151
+ });
152
+ });
153
+
154
+ // ---------------------------------------------------------------------------
155
+ // POST required-body (fn.length = 2): postApiAlphaSiteBlock(body, options?)
156
+ // ---------------------------------------------------------------------------
157
+
158
+ describe('postApiAlphaSiteBlock — POST, required body', () => {
159
+ const body = { instance: 'spam.example.com', block: true };
160
+
161
+ it('sends the body correctly (not corrupted)', async () => {
162
+ const client = createClient(BASE_URL);
163
+ await client.postApiAlphaSiteBlock(body);
164
+ expect(lastOptions().body).toBe(JSON.stringify(body));
165
+ });
166
+
167
+ it('forwards default headers alongside Content-Type', async () => {
168
+ const client = createClient(BASE_URL, {
169
+ headers: { Authorization: 'Bearer tok' },
170
+ });
171
+ await client.postApiAlphaSiteBlock(body);
172
+ expect(lastHeaders()['Authorization']).toBe('Bearer tok');
173
+ expect(lastHeaders()['Content-Type']).toBe('application/json');
174
+ });
175
+
176
+ it('merges per-call headers without losing body', async () => {
177
+ const client = createClient(BASE_URL, {
178
+ headers: { Authorization: 'Bearer default' },
179
+ });
180
+ await client.postApiAlphaSiteBlock(body, {
181
+ headers: { Authorization: 'Bearer override' },
182
+ });
183
+ expect(lastHeaders()['Authorization']).toBe('Bearer override');
184
+ expect(lastOptions().body).toBe(JSON.stringify(body));
185
+ });
186
+
187
+ it('uses POST method', async () => {
188
+ const client = createClient(BASE_URL);
189
+ await client.postApiAlphaSiteBlock(body);
190
+ expect(lastOptions().method).toBe('POST');
191
+ });
192
+ });
193
+
194
+ // ---------------------------------------------------------------------------
195
+ // Error handling
196
+ // ---------------------------------------------------------------------------
197
+
198
+ describe('ApiError', () => {
199
+ it('throws ApiError with correct status and data on 4xx', async () => {
200
+ fetchSpy.mockImplementation(() => Promise.resolve(makeResponse({ error: 'not found' }, 404)));
201
+ const client = createClient(BASE_URL);
202
+
203
+ await expect(client.getApiAlphaSite()).rejects.toMatchObject({
204
+ name: 'ApiError',
205
+ status: 404,
206
+ data: { error: 'not found' },
207
+ });
208
+ });
209
+
210
+ it('throws ApiError on 5xx', async () => {
211
+ fetchSpy.mockImplementation(() => Promise.resolve(makeResponse({ error: 'server error' }, 500)));
212
+ const client = createClient(BASE_URL);
213
+
214
+ const err = await client.getApiAlphaSite().catch((e) => e);
215
+ expect(err).toBeInstanceOf(ApiError);
216
+ expect(err.status).toBe(500);
217
+ });
218
+ });
219
+
220
+ // ---------------------------------------------------------------------------
221
+ // AbortController
222
+ // ---------------------------------------------------------------------------
223
+
224
+ describe('AbortController', () => {
225
+ it('forwards signal to fetch', async () => {
226
+ const controller = new AbortController();
227
+ const client = createClient(BASE_URL);
228
+ await client.getApiAlphaSite({ signal: controller.signal });
229
+ expect(lastOptions().signal).toBe(controller.signal);
230
+ });
231
+
232
+ it('propagates abort error when signal is already aborted', async () => {
233
+ const controller = new AbortController();
234
+ controller.abort();
235
+ fetchSpy.mockImplementation((_url: string, opts: RequestInit) => {
236
+ if (opts.signal?.aborted) return Promise.reject(new DOMException('Aborted', 'AbortError'));
237
+ return Promise.resolve(makeResponse({ ok: true }));
238
+ });
239
+ const client = createClient(BASE_URL);
240
+ const err = await client.getApiAlphaSite({ signal: controller.signal }).catch((e) => e);
241
+ expect(err.name).toBe('AbortError');
242
+ });
243
+ });
244
+
245
+ // ---------------------------------------------------------------------------
246
+ // baseUrl
247
+ // ---------------------------------------------------------------------------
248
+
249
+ describe('baseUrl construction', () => {
250
+ it('trims trailing slash from baseUrl', async () => {
251
+ const client = createClient('https://test.example.com/');
252
+ await client.getApiAlphaSite();
253
+ expect(lastUrl()).toBe('https://test.example.com/api/alpha/site');
254
+ });
255
+
256
+ it('different clients use their own baseUrl', async () => {
257
+ const a = createClient('https://instance-a.com');
258
+ const b = createClient('https://instance-b.com');
259
+
260
+ await a.getApiAlphaSite();
261
+ const urlA = lastUrl();
262
+
263
+ await b.getApiAlphaSite();
264
+ const urlB = lastUrl();
265
+
266
+ expect(urlA).toBe('https://instance-a.com/api/alpha/site');
267
+ expect(urlB).toBe('https://instance-b.com/api/alpha/site');
268
+ });
269
+ });
@@ -26,9 +26,11 @@ const allFns = {
26
26
 
27
27
  // Only the async API functions (not URL helpers or type exports)
28
28
  type AsyncFn = (...args: any[]) => Promise<any>;
29
- type ApiFunctions = {
30
- [K in keyof typeof allFns as (typeof allFns)[K] extends AsyncFn ? K : never]: (typeof allFns)[K];
31
- };
29
+ type AllModules =
30
+ typeof admin & typeof comment & typeof community & typeof feed & typeof misc &
31
+ typeof post & typeof privateMessage & typeof site & typeof topic & typeof upload & typeof user;
32
+ type AsyncKeys = { [K in keyof AllModules]: AllModules[K] extends AsyncFn ? K : never }[keyof AllModules];
33
+ type ApiFunctions = Pick<AllModules, AsyncKeys>;
32
34
 
33
35
  interface CreateClientOptions extends Omit<RequestInit, 'body' | 'method'> {
34
36
  /** Default headers merged into every request (e.g. Authorization). */
@@ -57,28 +59,26 @@ export function createClient(baseUrl: string, options: CreateClientOptions = {})
57
59
  for (const [key, fn] of Object.entries(allFns)) {
58
60
  if (typeof fn !== 'function') continue;
59
61
 
62
+ // fn.length is the total param count; options is always the last param
63
+ const optionsIndex = (fn as AsyncFn).length - 1;
64
+
60
65
  boundFns[key] = (...args: unknown[]) => {
61
- // options is always the last argument; inject baseUrl and defaults into it
62
- const last = args[args.length - 1];
66
+ // Pad args so options index is always reachable
67
+ while (args.length <= optionsIndex) args.push(undefined);
68
+
63
69
  const { headers: defaultHeaders, ...defaultInit } = options;
64
70
  const extra: RequestInit & { baseUrl: string } = { ...defaultInit, baseUrl };
65
- if (last !== null && typeof last === 'object' && !Array.isArray(last)) {
66
- const lastObj = last as RequestInit & { baseUrl?: string };
67
- args[args.length - 1] = {
68
- ...extra,
69
- ...lastObj,
70
- // per-call headers win, but default headers fill in any gaps
71
- headers: { ...defaultHeaders, ...(lastObj.headers as Record<string, string> | undefined) },
72
- };
73
- } else if (last === undefined || args.length === 0) {
74
- if (args.length > 0) {
75
- args[args.length - 1] = { ...extra, headers: defaultHeaders };
76
- } else {
77
- args.push({ ...extra, headers: defaultHeaders });
78
- }
79
- } else {
80
- args.push({ ...extra, headers: defaultHeaders });
81
- }
71
+ const existing = args[optionsIndex] as (RequestInit & { baseUrl?: string }) | undefined;
72
+
73
+ args[optionsIndex] = {
74
+ ...extra,
75
+ ...existing,
76
+ headers: {
77
+ ...defaultHeaders,
78
+ ...(existing?.headers as Record<string, string> | undefined),
79
+ },
80
+ };
81
+
82
82
  return (fn as AsyncFn)(...args);
83
83
  };
84
84
  }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Configuration and client factory
2
- export { configure, ApiError } from './mutator/custom-fetch';
2
+ export { ApiError } from './mutator/custom-fetch';
3
3
  export { createClient } from './create-client';
4
4
 
5
5
  // Re-export generated TypeScript types/schemas
@@ -7,12 +7,6 @@ declare global {
7
7
  }
8
8
  }
9
9
 
10
- let _defaultBaseUrl = 'https://piefed.social';
11
-
12
- export function configure(options: { baseUrl: string }) {
13
- _defaultBaseUrl = options.baseUrl.replace(/\/$/, '');
14
- }
15
-
16
10
  export class ApiError extends Error {
17
11
  constructor(
18
12
  public readonly status: number,
@@ -27,7 +21,8 @@ export const customFetch = async <T>(
27
21
  url: string,
28
22
  options?: RequestInit,
29
23
  ): Promise<T> => {
30
- const { baseUrl = _defaultBaseUrl, ...fetchOptions } = options ?? {};
24
+ const { baseUrl, ...fetchOptions } = options ?? {};
25
+ if (!baseUrl) throw new Error('baseUrl is required — use createClient() to make requests');
31
26
  const base = baseUrl.replace(/\/$/, '');
32
27
 
33
28
  const res = await fetch(`${base}${url}`, fetchOptions);