@foru-ms/sdk 1.2.2 → 1.2.4

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
@@ -97,7 +97,7 @@ The SDK provides multiple ways to handle pagination:
97
97
  ```typescript
98
98
  // Auto-pagination with async iterator
99
99
  for await (const thread of client.pagination.paginateAll(
100
- (cursor) => client.threads.list({ cursor, filter: 'newest' })
100
+ (cursor) => client.threads.list({ cursor, filter: 'newest', limit: 25 })
101
101
  )) {
102
102
  console.log(thread.title);
103
103
  }
@@ -108,15 +108,38 @@ const allThreads = await client.pagination.fetchAllPages(
108
108
  5 // max pages
109
109
  );
110
110
 
111
- // Manual pagination
111
+ // Manual pagination with custom page size
112
112
  let cursor: string | undefined;
113
113
  do {
114
- const response = await client.threads.list({ cursor });
114
+ const response = await client.threads.list({
115
+ cursor,
116
+ limit: 50 // Request up to 50 items per page (max)
117
+ });
115
118
  // Process threads...
116
119
  cursor = response.nextThreadCursor;
117
120
  } while (cursor);
118
121
  ```
119
122
 
123
+ ### Pagination Limit Parameter
124
+
125
+ All paginated endpoints support an optional `limit` parameter to control page size:
126
+
127
+ - **Min**: 1
128
+ - **Max**: 50
129
+ - **Default**: 15
130
+
131
+ ```typescript
132
+ // Get 50 threads per page (maximum)
133
+ const threads = await client.threads.list({ limit: 50 });
134
+
135
+ // Get 10 users per page
136
+ const users = await client.users.list({ limit: 10 });
137
+
138
+ // Limit applies to all paginated endpoints
139
+ const posts = await client.posts.list({ limit: 25 });
140
+ const notifications = await client.notifications.list({ userId: 'user-123', limit: 30 });
141
+ ```
142
+
120
143
  ## Webhooks
121
144
 
122
145
  Verify webhook signatures for security. All webhooks include:
@@ -187,104 +210,118 @@ Check the `/examples` directory for detailed examples:
187
210
 
188
211
  ### Threads (`client.threads`)
189
212
 
190
-
191
- * `list(params: { limit?: number; filter?: 'newest' | 'oldest'; tagId?: string; cursor?: string })`: List threads.
213
+ **Thread Management**
214
+ * `list(params: { query?: string; tagId?: string; filter?: 'newest' | 'oldest'; type?: 'created' | 'liked' | 'disliked' | 'upvoted' | 'downvoted' | 'subscribed'; cursor?: string; userId?: string; limit?: number })`: List threads with filtering options. `limit` controls page size (1-50, default: 15).
192
215
  * `create(payload: CreateThreadPayload)`: Create a new thread.
193
216
  * `retrieve(id: string)`: Get a thread by ID.
194
217
  * `update(id: string, payload: UpdateThreadPayload)`: Update a thread.
195
218
  * `delete(id: string)`: Delete a thread.
196
- * `getPosts(id: string, params: { cursor?: string; filter?: 'newest' | 'oldest' })`: Get posts in a thread.
197
- * `like(id: string, userId: string, extendedData?: any)`: Like a thread.
198
- * `unlike(id: string, userId: string)`: Unlike a thread.
199
- * `getLikes(id: string, params?: { cursor?: string })`: Get users who liked a thread.
200
- * `dislike(id: string, userId: string, extendedData?: any)`: Dislike a thread.
201
- * `undislike(id: string, userId: string)`: Remove dislike from a thread.
202
- * `getDislikes(id: string, params?: { cursor?: string })`: Get users who disliked a thread.
203
- * `subscribe(id: string, userId: string)`: Subscribe to a thread.
204
- * `unsubscribe(id: string, userId: string)`: Unsubscribe from a thread.
205
- * `getSubscribers(id: string, params?: { cursor?: string })`: Get users subscribed to a thread.
206
- * `upvote(id: string, userId: string, extendedData?: any)`: Upvote a thread.
207
- * `unupvote(id: string, userId: string)`: Remove upvote from a thread.
208
- * `getUpvotes(id: string, params?: { cursor?: string })`: Get users who upvoted a thread.
209
- * `downvote(id: string, userId: string, extendedData?: any)`: Downvote a thread.
210
- * `undownvote(id: string, userId: string)`: Remove downvote from a thread.
211
- * `getDownvotes(id: string, params?: { cursor?: string })`: Get users who downvoted a thread.
212
- * `getPoll(id: string, userId?: string)`: Get poll results.
213
- * `vote(id: string, userId: string, optionId: string)`: Vote in a thread poll.
214
- * `voteUpdate(id: string, userId: string, optionId: string)`: Change vote.
215
- * `unvote(id: string, userId: string)`: Remove vote.
219
+ * `getPosts(id: string, params: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get posts in a thread.
220
+
221
+ **Thread Interactions**
222
+ * `like(id: string, userId?: string, extendedData?: any)`: Like a thread.
223
+ * `unlike(id: string, userId?: string)`: Unlike a thread.
224
+ * `getLikes(id: string, params?: { cursor?: string; limit?: number })`: Get users who liked a thread with pagination.
225
+ * `dislike(id: string, userId?: string, extendedData?: any)`: Dislike a thread.
226
+ * `undislike(id: string, userId?: string)`: Remove dislike from a thread.
227
+ * `getDislikes(id: string, params?: { cursor?: string; limit?: number })`: Get users who disliked a thread with pagination.
228
+ * `upvote(id: string, userId?: string, extendedData?: any)`: Upvote a thread.
229
+ * `unupvote(id: string, userId?: string)`: Remove upvote from a thread.
230
+ * `getUpvotes(id: string, params?: { cursor?: string; limit?: number })`: Get users who upvoted a thread with pagination.
231
+ * `downvote(id: string, userId?: string, extendedData?: any)`: Downvote a thread.
232
+ * `undownvote(id: string, userId?: string)`: Remove downvote from a thread.
233
+ * `getDownvotes(id: string, params?: { cursor?: string; limit?: number })`: Get users who downvoted a thread with pagination.
234
+
235
+ **Thread Subscriptions**
236
+ * `subscribe(id: string, userId?: string, extendedData?: any)`: Subscribe to a thread.
237
+ * `unsubscribe(id: string, userId?: string)`: Unsubscribe from a thread.
238
+ * `getSubscribers(id: string, params?: { cursor?: string; limit?: number })`: Get users subscribed to a thread with pagination.
239
+
240
+ **Thread Polls**
241
+ * `createPoll(id: string, payload: { title?: string; expiresAt?: string; options: Array<{ title: string; color?: string; extendedData?: any }>, extendedData?: any })`: Create a poll for a thread.
242
+ * `getPoll(id: string)`: Get poll details and configuration.
243
+ * `updatePoll(id: string, payload: { title?: string; expiresAt?: string; closed?: boolean; options?: Array<{ id?: string; title?: string; color?: string; extendedData?: any }>; extendedData?: any })`: Update poll configuration.
244
+ * `deletePoll(id: string)`: Delete a poll from a thread.
245
+ * `getPollResults(id: string, userId?: string)`: Get poll results with vote counts.
246
+ * `vote(id: string, userId?: string, optionId: string)`: Cast a vote in a thread poll.
247
+ * `voteUpdate(id: string, userId?: string, optionId: string)`: Change an existing vote.
248
+ * `unvote(id: string, userId?: string)`: Remove your vote from a poll.
216
249
 
217
250
  ### Posts (`client.posts`)
218
251
 
219
- * `list(params: { limit?: number; cursor?: string; filter?: 'newest' | 'oldest'; threadId?: string })`: List posts (flat).
220
- * `create(payload: CreatePostPayload)`: Create a reply.
252
+ **Post Management**
253
+ * `list(params: { query?: string; filter?: 'newest' | 'oldest'; type?: 'created' | 'liked' | 'disliked' | 'upvoted' | 'downvoted'; cursor?: string; userId?: string; limit?: number })`: List posts with filtering options. `limit` controls page size (1-50, default: 15).
254
+ * `create(payload: CreatePostPayload)`: Create a new post/reply.
221
255
  * `retrieve(id: string)`: Get a post by ID.
222
256
  * `update(id: string, payload: UpdatePostPayload)`: Update a post.
223
- * `delete(id: string)`: Delete a post.
224
- * `getChildren(id: string, params: { cursor?: string; filter?: 'newest' | 'oldest' })`: Get child posts (nested replies).
225
- * `like(id: string, userId: string, extendedData?: any)`: Like a post.
226
- * `unlike(id: string, userId: string)`: Unlike a post.
227
- * `getLikes(id: string, params?: { cursor?: string })`: Get users who liked a post.
228
- * `dislike(id: string, userId: string, extendedData?: any)`: Dislike a post.
229
- * `undislike(id: string, userId: string)`: Remove dislike.
230
- * `getDislikes(id: string, params?: { cursor?: string })`: Get users who disliked a post.
231
- * `upvote(id: string, userId: string, extendedData?: any)`: Upvote a post.
232
- * `unupvote(id: string, userId: string)`: Remove upvote.
233
- * `getUpvotes(id: string, params?: { cursor?: string })`: Get users who upvoted a post.
234
- * `downvote(id: string, userId: string, extendedData?: any)`: Downvote a post.
235
- * `undownvote(id: string, userId: string)`: Remove downvote.
236
- * `getDownvotes(id: string, params?: { cursor?: string })`: Get users who downvoted a post.
257
+ * `delete(id: string, payload?: { userId?: string })`: Delete a post.
258
+ * `getChildren(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get child posts (nested replies).
259
+
260
+ **Post Interactions**
261
+ * `like(id: string, userId?: string, extendedData?: any)`: Like a post.
262
+ * `unlike(id: string, userId?: string)`: Unlike a post.
263
+ * `getLikes(id: string, params?: { cursor?: string; limit?: number })`: Get users who liked a post with pagination.
264
+ * `dislike(id: string, userId?: string, extendedData?: any)`: Dislike a post.
265
+ * `undislike(id: string, userId?: string)`: Remove dislike from a post.
266
+ * `getDislikes(id: string, params?: { cursor?: string; limit?: number })`: Get users who disliked a post with pagination.
267
+ * `upvote(id: string, userId?: string, extendedData?: any)`: Upvote a post.
268
+ * `unupvote(id: string, userId?: string)`: Remove upvote from a post.
269
+ * `getUpvotes(id: string, params?: { cursor?: string; limit?: number })`: Get users who upvoted a post with pagination.
270
+ * `downvote(id: string, userId?: string, extendedData?: any)`: Downvote a post.
271
+ * `undownvote(id: string, userId?: string)`: Remove downvote from a post.
272
+ * `getDownvotes(id: string, params?: { cursor?: string; limit?: number })`: Get users who downvoted a post with pagination.
237
273
 
238
274
  ### Users (`client.users`)
239
275
 
240
- * `list(params?: { query?: string; filter?: 'newest' | 'oldest'; cursor?: string })`: List users.
276
+ * `list(params?: { query?: string; filter?: 'newest' | 'oldest'; cursor?: string; limit?: number })`: List users. `limit` controls page size (1-50, default: 15).
241
277
  * `retrieve(userId: string)`: Get user by ID.
242
278
  * `create(payload: { username: string; email: string; password: string; displayName?: string; emailVerified?: boolean; roles?: string[]; bio?: string; signature?: string; url?: string; extendedData?: Record<string, any> })`: Create a user (Admin).
243
279
  * `update(id: string, payload: { username?: string; email?: string; password?: string; displayName?: string; emailVerified?: boolean; roles?: string[]; bio?: string; signature?: string; url?: string; extendedData?: Record<string, any> })`: Update a user.
244
280
  * `delete(id: string)`: Delete a user.
245
- * `getThreads(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest' })`: Get all threads created by a user.
246
- * `getPosts(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest' })`: Get all posts created by a user.
247
- * `getFollowers(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest' })`: Get user's followers.
248
- * `getFollowing(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest' })`: Get who a user follows.
249
- * `follow(id: string, followerId: string, extendedData?: any)`: Follow a user.
250
- * `unfollow(id: string, followerId: string)`: Unfollow a user.
281
+ * `getThreads(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get all threads created by a user.
282
+ * `getPosts(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get all posts created by a user.
283
+ * `getFollowers(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get user's followers.
284
+ * `getFollowing(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get who a user follows.
285
+ * `follow(id: string, followerId?: string, extendedData?: any)`: Follow a user.
286
+ * `unfollow(id: string, followerId?: string)`: Unfollow a user.
251
287
 
252
288
 
253
289
  ### Tags (`client.tags`)
254
290
 
255
- * `list(params?: { query?: string; cursor?: string })`: List tags.
291
+ * `list(params?: { query?: string; cursor?: string; limit?: number })`: List all tags. `limit` controls page size (1-50, default: 15).
292
+ * `listSubscribed(params: { userId?: string; query?: string; cursor?: string; limit?: number })`: List tags a user is subscribed to.
256
293
  * `create(payload: { name: string; description?: string; color?: string; extendedData?: Record<string, any> })`: Create a tag.
257
- * `retrieve(id: string, params?: { userId?: string })`: Get a tag.
294
+ * `retrieve(id: string, params?: { userId?: string })`: Get a tag with optional user context.
258
295
  * `update(id: string, payload: { name?: string; description?: string; color?: string; extendedData?: Record<string, any> })`: Update a tag.
259
296
  * `delete(id: string)`: Delete a tag.
260
- * `getThreads(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest' })`: Get all threads with a specific tag.
261
- * `subscribe(id: string, userId: string)`: Subscribe to a tag.
262
- * `unsubscribe(id: string, userId: string)`: Unsubscribe from a tag.
263
- * `getSubscribers(id: string, params?: { cursor?: string })`: Get users subscribed to a tag.
264
- * `listSubscribed(params: { userId: string; query?: string; cursor?: string })`: List tags a user is subscribed to.
297
+ * `getThreads(id: string, params?: { query?: string; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: Get all threads with a specific tag.
298
+ * `subscribe(id: string, userId?: string)`: Subscribe to a tag.
299
+ * `unsubscribe(id: string, userId?: string)`: Unsubscribe from a tag.
300
+ * `getSubscribers(id: string, params?: { cursor?: string; limit?: number })`: Get users subscribed to a tag with pagination.
265
301
 
266
302
 
267
303
  ### Notifications (`client.notifications`)
268
304
 
269
- * `list(params: { userId: string; read?: boolean; filter?: 'newest' | 'oldest'; cursor?: string })`: List notifications.
270
- * `markAllAsRead(userId: string, read?: boolean)`: Bulk update read status. Default is `true`.
271
- * `create(payload: { threadId?: string; postId?: string; privateMessageId?: string; notifierId: string; notifiedId: string; type: string; description?: string; extendedData?: Record<string, any> })`: Create a notification manually.
272
- * `retrieve(id: string)`: Get a notification.
273
- * `update(id: string, payload: { read: boolean })`: Update a notification.
274
- * `delete(id: string)`: Delete a notification.
305
+ * `list(params: { userId?: string; read?: boolean; filter?: 'newest' | 'oldest'; cursor?: string; limit?: number })`: List notifications for a user. `limit` controls page size (1-50, default: 15).
306
+ * `create(payload: { threadId?: string; postId?: string; privateMessageId?: string; notifierId?: string; notifiedId: string; type: string; description?: string; extendedData?: Record<string, any> })`: Create a notification manually.
307
+ * `retrieve(id: string, userId?: string)`: Get a notification by ID.
308
+ * `update(id: string, payload: { userId?: string; read: boolean })`: Update a notification's read status.
309
+ * `delete(id: string, userId?: string)`: Delete a notification.
310
+ * `markAllAsRead(userId?: string, read?: boolean)`: Bulk update read status for all of a user's notifications. Default read status is `true`.
275
311
 
276
312
  ### Search (`client.search`)
277
313
 
278
- * `search(params: { query: string; type: 'threads' | 'posts' | 'users' | 'tags'; cursor?: string })`: Polymorphic search.
314
+ * `search(params: { query: string; type: 'threads' | 'posts' | 'users' | 'tags'; cursor?: string; limit?: number })`: Polymorphic search. `limit` controls page size (1-50, default: 15).
279
315
 
280
316
  ### Webhooks (`client.webhooks`)
281
317
 
282
- * `list()`: List webhooks.
283
- * `create(payload: { name: string; url: string; events: string[] })`: Create a webhook.
284
- * `retrieve(id: string)`: Get a webhook.
285
- * `update(id: string, payload: any)`: Update a webhook.
318
+ * `list()`: List all webhooks for your instance.
319
+ * `create(payload: { name: string; url: string; events: string[] })`: Create a new webhook subscription.
320
+ * `retrieve(id: string)`: Get a webhook by ID.
321
+ * `update(id: string, payload: { name?: string; url?: string; events?: string[]; active?: boolean })`: Update a webhook configuration.
286
322
  * `delete(id: string)`: Delete a webhook.
287
- * `getDeliveries(id: string, params: { cursor?: string })`: Get webhook delivery history.
323
+ * `getDeliveries(id: string, params?: { cursor?: string; limit?: number })`: Get webhook delivery history with pagination. Track successful and failed deliveries. `limit` controls page size (1-50, default: 15).
324
+ * `verifySignature(payload: any, signature: string, timestamp: string, secret: string, maxAge?: number)`: Verify webhook signature for security. Uses HMAC-SHA256. Default maxAge is 5 minutes to prevent replay attacks.
288
325
 
289
326
  ### Stats (`client.stats`)
290
327
 
@@ -292,46 +329,49 @@ Check the `/examples` directory for detailed examples:
292
329
 
293
330
  ### Integrations (`client.integrations`)
294
331
 
295
- * `list()`: Get all configured integrations.
296
- * `create(payload: { type: 'SLACK' | 'DISCORD' | 'SALESFORCE' | 'HUBSPOT' | 'OKTA' | 'AUTH0'; name: string; config: any })`: Configure an integration (Slack, Discord, etc.).
297
- * `retrieve(id: string)`: Get integration details.
298
- * `update(id: string, payload: { name?: string; config?: any; active?: boolean })`: Update an integration.
332
+ * `list()`: Get all configured integrations for your instance.
333
+ * `create(payload: { type: 'SLACK' | 'DISCORD' | 'SALESFORCE' | 'HUBSPOT' | 'OKTA' | 'AUTH0'; name: string; config: any })`: Configure a new integration (Slack, Discord, CRM, or SSO).
334
+ * `retrieve(id: string)`: Get integration details by ID.
335
+ * `update(id: string, payload: { name?: string; type?: string; enabled?: boolean; config?: any })`: Update an integration configuration.
299
336
  * `delete(id: string)`: Remove an integration.
337
+ * `test(integrationId: string)`: Send a test message to verify integration is working correctly.
338
+ * `oauthAuthorize(provider: 'hubspot' | 'salesforce')`: Initiate OAuth flow for a provider (redirects to provider).
339
+ * `oauthCallback(provider: string, code: string, state: string)`: Handle OAuth callback from provider.
300
340
 
301
341
  ### Private Messages (`client.privateMessages`)
302
342
 
303
- * `list(params?: { query?: string; userId?: string; filter?: 'newest' | 'oldest'; cursor?: string })`: List private messages.
304
- * `create(payload: { title?: string; body: string; recipientId: string; senderId?: string; extendedData?: Record<string, any> })`: Send a direct message.
305
- * `retrieve(id: string)`: Get a message thread.
306
- * `reply(id: string, payload: { body: string; senderId: string; recipientId: string; extendedData?: Record<string, any> })`: Reply to a message.
307
- * `update(id: string, payload: { read?: boolean; extendedData?: Record<string, any> })`: Update a message (e.g., mark as read).
308
- * `delete(id: string)`: Delete a message.
343
+ * `list(params?: { query?: string; userId?: string; filter?: 'newest' | 'oldest'; cursor?: string; limit?: number })`: List private messages. `limit` controls page size (1-50, default: 15).
344
+ * `create(payload: { title?: string; body: string; recipientId: string; senderId?: string; extendedData?: Record<string, any> })`: Send a new private message.
345
+ * `retrieve(id: string, userId?: string)`: Get a message by ID.
346
+ * `reply(id: string, payload: { body: string; senderId?: string; title?: string; extendedData?: Record<string, any> })`: Reply to a message thread.
347
+ * `update(id: string, payload: { body?: string; extendedData?: Record<string, any> })`: Update a message (only sender can update).
348
+ * `delete(id: string)`: Delete a message (participants can delete).
309
349
 
310
350
  ### Reports (`client.reports`)
311
351
 
312
- * `list(params?: { reporterId?: string; reportedId?: string; read?: boolean; cursor?: string; filter?: 'newest' | 'oldest' })`: List reports.
313
- * `create(payload: { reporterId: string; reportedId?: string; threadId?: string; postId?: string; privateMessageId?: string; type?: string; description?: string; extendedData?: Record<string, any> })`: Submit a report.
314
- * `batchUpdate(payload: { reportIds: string[]; read: boolean })`: Bulk update status.
315
- * `retrieve(id: string)`: Get a report.
316
- * `update(id: string, payload: { threadId?: string; postId?: string; privateMessageId?: string; reportedId?: string; reporterId?: string; type?: string; description?: string; read?: boolean; extendedData?: Record<string, any> })`: Update report details.
352
+ * `list(params?: { reporterId?: string; reportedId?: string; read?: boolean; cursor?: string; filter?: 'newest' | 'oldest'; limit?: number })`: List reports with filtering options. `limit` controls page size (1-50, default: 15).
353
+ * `create(payload: { reporterId?: string; reportedId?: string; threadId?: string; postId?: string; privateMessageId?: string; type?: string; description?: string; extendedData?: Record<string, any> })`: Submit a new report.
354
+ * `retrieve(id: string)`: Get a report by ID.
355
+ * `update(id: string, payload: { threadId?: string; postId?: string; privateMessageId?: string; reportedId?: string; reporterId?: string; type?: string; description?: string; read?: boolean; extendedData?: Record<string, any> })`: Update report details (full update).
356
+ * `updateStatus(id: string, read: boolean)`: Update read status of a report (partial update).
357
+ * `batchUpdate(payload: { reportIds: string[]; read: boolean })`: Bulk update read status for multiple reports.
317
358
  * `delete(id: string)`: Delete a report.
318
- * `updateStatus(id: string, read: boolean)`: Update read status of a report.
319
359
 
320
360
  ### Roles (`client.roles`)
321
361
 
322
- * `list(params?: { filter?: 'newest' | 'oldest'; cursor?: string })`: List user roles.
362
+ * `list(params?: { filter?: 'newest' | 'oldest'; cursor?: string; limit?: number })`: List user roles. `limit` controls page size (1-50, default: 15).
323
363
  * `create(payload: { name: string; description?: string; color?: string; extendedData?: Record<string, any> })`: Create a new role.
324
- * `retrieve(id: string)`: Get a role.
364
+ * `retrieve(id: string)`: Get a role by ID.
325
365
  * `update(id: string, payload: { name?: string; description?: string; color?: string; extendedData?: Record<string, any> })`: Update a role.
326
366
  * `delete(id: string)`: Delete a role.
327
367
 
328
368
  ### SSO (`client.sso`)
329
369
 
330
- * `list()`: List SSO providers.
331
- * `create(payload: { provider: 'OKTA' | 'AUTH0' | 'SAML'; domain: string; config: any })`: Configure SSO.
332
- * `retrieve(id: string)`: Get SSO provider details.
333
- * `update(id: string, payload: { domain?: string; config?: any; active?: boolean })`: Update SSO configuration.
334
- * `delete(id: string)`: Remove SSO provider.
370
+ * `list()`: List all SSO providers configured for your instance.
371
+ * `create(payload: { provider: 'OKTA' | 'AUTH0' | 'SAML'; domain: string; config: any })`: Configure a new SSO provider.
372
+ * `retrieve(id: string)`: Get SSO provider details by ID.
373
+ * `update(id: string, payload: { name?: string; type?: 'SAML' | 'OIDC' | 'OAUTH2'; enabled?: boolean; config?: any })`: Update SSO configuration.
374
+ * `delete(id: string)`: Remove an SSO provider.
335
375
 
336
376
  ## Types
337
377
 
@@ -508,11 +548,32 @@ We welcome contributions! Please see our contributing guidelines for more inform
508
548
  ## Support
509
549
 
510
550
  - Support: https://foru.ms/support
511
- - Documentation: https://docs.foru.ms
551
+ - Documentation: https://foru.ms/docs
512
552
  - Issues: https://github.com/foru-ms/sdk/issues
513
553
 
514
554
  ## Changelog
515
555
 
556
+ ### v1.2.4
557
+ - Pagination Enhancement: Added configurable `limit` query parameter to all paginated endpoints
558
+ - Allows clients to control page size (min: 1, max: 50, default: 15)
559
+ - Applied to all list operations across Threads, Posts, Users, Tags, Notifications, Private Messages, Reports, Roles, Search, and Webhooks
560
+ - Updated documentation with usage examples and parameter specifications
561
+ - Improves API flexibility for different use cases (mobile, desktop, batch processing)
562
+
563
+ ### v1.2.3
564
+ - README documentation update
565
+ - Enhanced all API reference sections with:
566
+ - Better organization with categorized subsections (Management, Interactions, Subscriptions, Polls)
567
+ - Corrected optional vs required parameters throughout
568
+ - Added missing methods documentation (poll CRUD, webhook deliveries, integration OAuth, etc.)
569
+ - Improved clarity and consistency across all resource sections
570
+ - Added detailed descriptions for complex operations
571
+
572
+ ### v1.2.2
573
+ - Added Auth resource with authentication methods
574
+ - Introduced comprehensive SDK type definitions
575
+ - Updated documentation
576
+
516
577
  ### v1.2.1
517
578
  - README.md formatting and updates
518
579
 
@@ -8,6 +8,7 @@ export declare class NotificationsResource {
8
8
  read?: boolean;
9
9
  filter?: 'newest' | 'oldest';
10
10
  cursor?: string;
11
+ limit?: number;
11
12
  }): Promise<NotificationListResponse>;
12
13
  markAllAsRead(userId: string, read?: boolean): Promise<{
13
14
  count: number;
@@ -9,6 +9,7 @@ export declare class PostsResource {
9
9
  type?: InteractionType;
10
10
  cursor?: string;
11
11
  userId?: string;
12
+ limit?: number;
12
13
  }): Promise<PostListResponse>;
13
14
  create(payload: import('../types').CreatePostPayload): Promise<import('../types').Post>;
14
15
  retrieve(postId: string): Promise<import('../types').Post>;
@@ -22,25 +23,30 @@ export declare class PostsResource {
22
23
  query?: string;
23
24
  cursor?: string;
24
25
  filter?: 'newest' | 'oldest';
26
+ limit?: number;
25
27
  }): Promise<any>;
26
28
  like(id: string, userId?: string, extendedData?: any): Promise<any>;
27
29
  unlike(id: string, userId: string): Promise<any>;
28
30
  getLikes(id: string, params?: {
29
31
  cursor?: string;
32
+ limit?: number;
30
33
  }): Promise<any>;
31
34
  dislike(id: string, userId?: string, extendedData?: any): Promise<any>;
32
35
  undislike(id: string, userId: string): Promise<any>;
33
36
  getDislikes(id: string, params?: {
34
37
  cursor?: string;
38
+ limit?: number;
35
39
  }): Promise<any>;
36
40
  upvote(id: string, userId?: string, extendedData?: any): Promise<any>;
37
41
  unupvote(id: string, userId: string): Promise<any>;
38
42
  getUpvotes(id: string, params?: {
39
43
  cursor?: string;
44
+ limit?: number;
40
45
  }): Promise<any>;
41
46
  downvote(id: string, userId?: string, extendedData?: any): Promise<any>;
42
47
  undownvote(id: string, userId: string): Promise<any>;
43
48
  getDownvotes(id: string, params?: {
44
49
  cursor?: string;
50
+ limit?: number;
45
51
  }): Promise<any>;
46
52
  }
@@ -8,6 +8,7 @@ export declare class PrivateMessagesResource {
8
8
  userId?: string;
9
9
  filter?: 'newest' | 'oldest';
10
10
  cursor?: string;
11
+ limit?: number;
11
12
  }): Promise<PrivateMessageListResponse>;
12
13
  create(payload: {
13
14
  title?: string;
@@ -9,6 +9,7 @@ export declare class ReportsResource {
9
9
  read?: boolean;
10
10
  cursor?: string;
11
11
  filter?: 'newest' | 'oldest';
12
+ limit?: number;
12
13
  }): Promise<ReportListResponse>;
13
14
  create(payload: {
14
15
  reporterId: string;
@@ -6,6 +6,7 @@ export declare class RolesResource {
6
6
  list(params?: {
7
7
  filter?: 'newest' | 'oldest';
8
8
  cursor?: string;
9
+ limit?: number;
9
10
  }): Promise<RoleListResponse>;
10
11
  create(payload: {
11
12
  name: string;
@@ -7,5 +7,6 @@ export declare class SearchResource {
7
7
  query: string;
8
8
  type: 'threads' | 'posts' | 'users' | 'tags';
9
9
  cursor?: string;
10
+ limit?: number;
10
11
  }): Promise<SearchResponse>;
11
12
  }
@@ -6,6 +6,7 @@ export declare class TagsResource {
6
6
  list(params?: {
7
7
  query?: string;
8
8
  cursor?: string;
9
+ limit?: number;
9
10
  }): Promise<TagListResponse>;
10
11
  create(payload: {
11
12
  name: string;
@@ -31,15 +32,18 @@ export declare class TagsResource {
31
32
  query?: string;
32
33
  cursor?: string;
33
34
  filter?: 'newest' | 'oldest';
35
+ limit?: number;
34
36
  }): Promise<import('../types').ThreadListResponse>;
35
37
  subscribe(id: string, userId: string): Promise<any>;
36
38
  unsubscribe(id: string, userId: string): Promise<any>;
37
39
  getSubscribers(id: string, params?: {
38
40
  cursor?: string;
41
+ limit?: number;
39
42
  }): Promise<any>;
40
43
  listSubscribed(params: {
41
44
  userId: string;
42
45
  query?: string;
43
46
  cursor?: string;
47
+ limit?: number;
44
48
  }): Promise<TagListResponse>;
45
49
  }
@@ -10,6 +10,7 @@ export declare class ThreadsResource {
10
10
  type?: InteractionType;
11
11
  cursor?: string;
12
12
  userId?: string;
13
+ limit?: number;
13
14
  }): Promise<ThreadListResponse>;
14
15
  create(payload: import('../types').CreateThreadPayload): Promise<import('../types').Thread>;
15
16
  retrieve(threadId: string): Promise<import('../types').Thread>;
@@ -23,31 +24,37 @@ export declare class ThreadsResource {
23
24
  query?: string;
24
25
  cursor?: string;
25
26
  filter?: 'newest' | 'oldest';
27
+ limit?: number;
26
28
  }): Promise<any>;
27
29
  like(id: string, userId?: string, extendedData?: any): Promise<any>;
28
30
  unlike(id: string, userId: string): Promise<any>;
29
31
  getLikes(id: string, params?: {
30
32
  cursor?: string;
33
+ limit?: number;
31
34
  }): Promise<any>;
32
35
  dislike(id: string, userId?: string, extendedData?: any): Promise<any>;
33
36
  undislike(id: string, userId: string): Promise<any>;
34
37
  getDislikes(id: string, params?: {
35
38
  cursor?: string;
39
+ limit?: number;
36
40
  }): Promise<any>;
37
41
  subscribe(id: string, userId: string, extendedData?: any): Promise<any>;
38
42
  unsubscribe(id: string, userId: string): Promise<any>;
39
43
  getSubscribers(id: string, params?: {
40
44
  cursor?: string;
45
+ limit?: number;
41
46
  }): Promise<any>;
42
47
  upvote(id: string, userId?: string, extendedData?: any): Promise<any>;
43
48
  unupvote(id: string, userId: string): Promise<any>;
44
49
  getUpvotes(id: string, params?: {
45
50
  cursor?: string;
51
+ limit?: number;
46
52
  }): Promise<any>;
47
53
  downvote(id: string, userId?: string, extendedData?: any): Promise<any>;
48
54
  undownvote(id: string, userId: string): Promise<any>;
49
55
  getDownvotes(id: string, params?: {
50
56
  cursor?: string;
57
+ limit?: number;
51
58
  }): Promise<any>;
52
59
  getPoll(threadId: string, userId?: string): Promise<any>;
53
60
  vote(id: string, optionId: string, userId: string): Promise<any>;
@@ -7,6 +7,7 @@ export declare class UsersResource {
7
7
  query?: string;
8
8
  filter?: 'newest' | 'oldest';
9
9
  cursor?: string;
10
+ limit?: number;
10
11
  }): Promise<UserListResponse>;
11
12
  retrieve(userId: string): Promise<User>;
12
13
  create(payload: {
@@ -40,16 +41,19 @@ export declare class UsersResource {
40
41
  query?: string;
41
42
  cursor?: string;
42
43
  filter?: 'newest' | 'oldest';
44
+ limit?: number;
43
45
  }): Promise<import('../types').ThreadListResponse>;
44
46
  getPosts(id: string, params?: {
45
47
  query?: string;
46
48
  cursor?: string;
47
49
  filter?: 'newest' | 'oldest';
50
+ limit?: number;
48
51
  }): Promise<import('../types').PostListResponse>;
49
52
  getFollowers(id: string, params?: {
50
53
  query?: string;
51
54
  cursor?: string;
52
55
  filter?: 'newest' | 'oldest';
56
+ limit?: number;
53
57
  }): Promise<{
54
58
  followers: User[];
55
59
  nextUserCursor?: string;
@@ -61,6 +65,7 @@ export declare class UsersResource {
61
65
  query?: string;
62
66
  cursor?: string;
63
67
  filter?: 'newest' | 'oldest';
68
+ limit?: number;
64
69
  }): Promise<{
65
70
  following: any[];
66
71
  nextUserCursor?: string;
@@ -61,6 +61,7 @@ export declare class WebhooksResource {
61
61
  */
62
62
  getDeliveries(id: string, params?: {
63
63
  cursor?: string;
64
+ limit?: number;
64
65
  }): Promise<{
65
66
  deliveries: any[];
66
67
  total: number;
@@ -70,6 +70,8 @@ class WebhooksResource {
70
70
  const searchParams = new URLSearchParams();
71
71
  if (params === null || params === void 0 ? void 0 : params.cursor)
72
72
  searchParams.append('cursor', params.cursor);
73
+ if (params === null || params === void 0 ? void 0 : params.limit)
74
+ searchParams.append('limit', params.limit.toString());
73
75
  return this.client.request(`/webhooks/${id}/deliveries?${searchParams.toString()}`, {
74
76
  method: 'GET',
75
77
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foru-ms/sdk",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "JavaScript SDK for Foru.ms",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,6 +13,7 @@ export class NotificationsResource {
13
13
  read?: boolean;
14
14
  filter?: 'newest' | 'oldest';
15
15
  cursor?: string;
16
+ limit?: number;
16
17
  }): Promise<NotificationListResponse> {
17
18
  const searchParams = new URLSearchParams();
18
19
  Object.entries(params).forEach(([key, value]) => {
@@ -14,6 +14,7 @@ export class PostsResource {
14
14
  type?: InteractionType;
15
15
  cursor?: string;
16
16
  userId?: string;
17
+ limit?: number;
17
18
  }): Promise<PostListResponse> {
18
19
  const searchParams = new URLSearchParams();
19
20
  if (params) {
@@ -59,6 +60,7 @@ export class PostsResource {
59
60
  query?: string;
60
61
  cursor?: string;
61
62
  filter?: 'newest' | 'oldest';
63
+ limit?: number;
62
64
  }): Promise<any> {
63
65
  const searchParams = new URLSearchParams();
64
66
  if (params) {
@@ -86,6 +88,7 @@ export class PostsResource {
86
88
 
87
89
  async getLikes(id: string, params?: {
88
90
  cursor?: string;
91
+ limit?: number;
89
92
  }): Promise<any> {
90
93
  const searchParams = new URLSearchParams();
91
94
  if (params) {
@@ -113,6 +116,7 @@ export class PostsResource {
113
116
 
114
117
  async getDislikes(id: string, params?: {
115
118
  cursor?: string;
119
+ limit?: number;
116
120
  }): Promise<any> {
117
121
  const searchParams = new URLSearchParams();
118
122
  if (params) {
@@ -140,6 +144,7 @@ export class PostsResource {
140
144
 
141
145
  async getUpvotes(id: string, params?: {
142
146
  cursor?: string;
147
+ limit?: number;
143
148
  }): Promise<any> {
144
149
  const searchParams = new URLSearchParams();
145
150
  if (params) {
@@ -167,6 +172,7 @@ export class PostsResource {
167
172
 
168
173
  async getDownvotes(id: string, params?: {
169
174
  cursor?: string;
175
+ limit?: number;
170
176
  }): Promise<any> {
171
177
  const searchParams = new URLSearchParams();
172
178
  if (params) {
@@ -13,6 +13,7 @@ export class PrivateMessagesResource {
13
13
  userId?: string;
14
14
  filter?: 'newest' | 'oldest';
15
15
  cursor?: string;
16
+ limit?: number;
16
17
  }): Promise<PrivateMessageListResponse> {
17
18
  const searchParams = new URLSearchParams();
18
19
  if (params) {
@@ -14,6 +14,7 @@ export class ReportsResource {
14
14
  read?: boolean;
15
15
  cursor?: string;
16
16
  filter?: 'newest' | 'oldest';
17
+ limit?: number;
17
18
  }): Promise<ReportListResponse> {
18
19
  const searchParams = new URLSearchParams();
19
20
  if (params) {
@@ -11,6 +11,7 @@ export class RolesResource {
11
11
  async list(params?: {
12
12
  filter?: 'newest' | 'oldest';
13
13
  cursor?: string;
14
+ limit?: number;
14
15
  }): Promise<RoleListResponse> {
15
16
  const searchParams = new URLSearchParams();
16
17
  if (params) {
@@ -12,6 +12,7 @@ export class SearchResource {
12
12
  query: string;
13
13
  type: 'threads' | 'posts' | 'users' | 'tags';
14
14
  cursor?: string;
15
+ limit?: number;
15
16
  }): Promise<SearchResponse> {
16
17
  const searchParams = new URLSearchParams();
17
18
  Object.entries(params).forEach(([key, value]) => {
@@ -11,6 +11,7 @@ export class TagsResource {
11
11
  async list(params?: {
12
12
  query?: string;
13
13
  cursor?: string;
14
+ limit?: number;
14
15
  }): Promise<TagListResponse> {
15
16
  const searchParams = new URLSearchParams();
16
17
  if (params) {
@@ -68,6 +69,7 @@ export class TagsResource {
68
69
  query?: string;
69
70
  cursor?: string;
70
71
  filter?: 'newest' | 'oldest';
72
+ limit?: number;
71
73
  }): Promise<import('../types').ThreadListResponse> {
72
74
  const searchParams = new URLSearchParams();
73
75
  if (params) {
@@ -97,6 +99,7 @@ export class TagsResource {
97
99
 
98
100
  async getSubscribers(id: string, params?: {
99
101
  cursor?: string;
102
+ limit?: number;
100
103
  }): Promise<any> {
101
104
  const searchParams = new URLSearchParams();
102
105
  if (params) {
@@ -113,6 +116,7 @@ export class TagsResource {
113
116
  userId: string;
114
117
  query?: string;
115
118
  cursor?: string;
119
+ limit?: number;
116
120
  }): Promise<TagListResponse> {
117
121
  const searchParams = new URLSearchParams();
118
122
  Object.entries(params).forEach(([key, value]) => {
@@ -15,6 +15,7 @@ export class ThreadsResource {
15
15
  type?: InteractionType;
16
16
  cursor?: string;
17
17
  userId?: string;
18
+ limit?: number;
18
19
  }): Promise<ThreadListResponse> {
19
20
  const searchParams = new URLSearchParams();
20
21
  if (params) {
@@ -60,6 +61,7 @@ export class ThreadsResource {
60
61
  query?: string;
61
62
  cursor?: string;
62
63
  filter?: 'newest' | 'oldest';
64
+ limit?: number;
63
65
  }): Promise<any> {
64
66
  const searchParams = new URLSearchParams();
65
67
  if (params) {
@@ -87,6 +89,7 @@ export class ThreadsResource {
87
89
 
88
90
  async getLikes(id: string, params?: {
89
91
  cursor?: string;
92
+ limit?: number;
90
93
  }): Promise<any> {
91
94
  const searchParams = new URLSearchParams();
92
95
  if (params) {
@@ -114,6 +117,7 @@ export class ThreadsResource {
114
117
 
115
118
  async getDislikes(id: string, params?: {
116
119
  cursor?: string;
120
+ limit?: number;
117
121
  }): Promise<any> {
118
122
  const searchParams = new URLSearchParams();
119
123
  if (params) {
@@ -141,6 +145,7 @@ export class ThreadsResource {
141
145
 
142
146
  async getSubscribers(id: string, params?: {
143
147
  cursor?: string;
148
+ limit?: number;
144
149
  }): Promise<any> {
145
150
  const searchParams = new URLSearchParams();
146
151
  if (params) {
@@ -168,6 +173,7 @@ export class ThreadsResource {
168
173
 
169
174
  async getUpvotes(id: string, params?: {
170
175
  cursor?: string;
176
+ limit?: number;
171
177
  }): Promise<any> {
172
178
  const searchParams = new URLSearchParams();
173
179
  if (params) {
@@ -195,6 +201,7 @@ export class ThreadsResource {
195
201
 
196
202
  async getDownvotes(id: string, params?: {
197
203
  cursor?: string;
204
+ limit?: number;
198
205
  }): Promise<any> {
199
206
  const searchParams = new URLSearchParams();
200
207
  if (params) {
@@ -12,6 +12,7 @@ export class UsersResource {
12
12
  query?: string;
13
13
  filter?: 'newest' | 'oldest';
14
14
  cursor?: string;
15
+ limit?: number;
15
16
  }): Promise<UserListResponse> {
16
17
  const searchParams = new URLSearchParams();
17
18
  if (params) {
@@ -79,6 +80,7 @@ export class UsersResource {
79
80
  query?: string;
80
81
  cursor?: string;
81
82
  filter?: 'newest' | 'oldest';
83
+ limit?: number;
82
84
  }): Promise<import('../types').ThreadListResponse> {
83
85
  const searchParams = new URLSearchParams();
84
86
  if (params) {
@@ -97,6 +99,7 @@ export class UsersResource {
97
99
  query?: string;
98
100
  cursor?: string;
99
101
  filter?: 'newest' | 'oldest';
102
+ limit?: number;
100
103
  }): Promise<import('../types').PostListResponse> {
101
104
  const searchParams = new URLSearchParams();
102
105
  if (params) {
@@ -115,6 +118,7 @@ export class UsersResource {
115
118
  query?: string;
116
119
  cursor?: string;
117
120
  filter?: 'newest' | 'oldest';
121
+ limit?: number;
118
122
  }): Promise<{ followers: User[]; nextUserCursor?: string; count: number }> {
119
123
  const searchParams = new URLSearchParams();
120
124
  if (params) {
@@ -146,6 +150,7 @@ export class UsersResource {
146
150
  query?: string;
147
151
  cursor?: string;
148
152
  filter?: 'newest' | 'oldest';
153
+ limit?: number;
149
154
  }): Promise<{ following: any[]; nextUserCursor?: string; count: number }> {
150
155
  const searchParams = new URLSearchParams();
151
156
  if (params) {
@@ -83,9 +83,10 @@ export class WebhooksResource {
83
83
  * @param params - Query parameters
84
84
  * @returns Promise resolving to delivery history
85
85
  */
86
- async getDeliveries(id: string, params?: { cursor?: string }): Promise<{ deliveries: any[]; total: number; nextCursor?: string }> {
86
+ async getDeliveries(id: string, params?: { cursor?: string; limit?: number }): Promise<{ deliveries: any[]; total: number; nextCursor?: string }> {
87
87
  const searchParams = new URLSearchParams();
88
88
  if (params?.cursor) searchParams.append('cursor', params.cursor);
89
+ if (params?.limit) searchParams.append('limit', params.limit.toString());
89
90
 
90
91
  return this.client.request<{ deliveries: any[]; total: number; nextCursor?: string }>(`/webhooks/${id}/deliveries?${searchParams.toString()}`, {
91
92
  method: 'GET',