@xpoz/xpoz 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # Xpoz TypeScript SDK
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@xpoz/xpoz)](https://www.npmjs.com/package/@xpoz/xpoz)
4
+
3
5
  TypeScript SDK for the [Xpoz](https://xpoz.ai) social media intelligence platform. Query Twitter/X, Instagram, and Reddit data through a simple, typed interface.
4
6
 
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
- npm install xpoz
10
+ npm install @xpoz/xpoz
9
11
  ```
10
12
 
11
13
  Requires Node.js 18+.
@@ -31,6 +33,7 @@ The SDK wraps Xpoz's [MCP](https://modelcontextprotocol.io) server, abstracting
31
33
  - **30 data methods** across Twitter, Instagram, and Reddit
32
34
  - **Fully async** — all methods return `Promise<T>`
33
35
  - **Automatic operation polling** — long-running queries are abstracted away
36
+ - **Response types** — choose between fast (immediate), paging (full pagination), or CSV export
34
37
  - **Server-side pagination** — `PaginatedResult<T>` with `nextPage()`, `getPage(n)`
35
38
  - **CSV export** — `exportCsv()` on any paginated result
36
39
  - **Field selection** — request only the fields you need
@@ -40,7 +43,7 @@ The SDK wraps Xpoz's [MCP](https://modelcontextprotocol.io) server, abstracting
40
43
  ## Quick Start
41
44
 
42
45
  ```typescript
43
- import { XpozClient } from "xpoz";
46
+ import { XpozClient, ResponseType } from "@xpoz/xpoz";
44
47
 
45
48
  const client = new XpozClient({ apiKey: "your-api-key" });
46
49
  await client.connect();
@@ -135,6 +138,73 @@ const user = await client.twitter.getUser("elonmusk", {
135
138
 
136
139
  Requesting fewer fields significantly improves response time.
137
140
 
141
+ ## Response Types
142
+
143
+ Search and query methods support a `responseType` option that controls how results are returned. Import the `ResponseType` enum:
144
+
145
+ ```typescript
146
+ import { XpozClient, ResponseType } from "@xpoz/xpoz";
147
+ ```
148
+
149
+ | Mode | Enum Value | Behavior | Best For |
150
+ | --- | --- | --- | --- |
151
+ | **Fast** | `ResponseType.Fast` | Returns up to 300 results immediately, no async polling (default) | Quick queries, UI previews |
152
+ | **Paging** | `ResponseType.Paging` | Async paginated query with full dataset access | Full analysis, large datasets |
153
+ | **CSV** | `ResponseType.Csv` | Async bulk export, use `exportCsv()` to get download URL | Data exports |
154
+
155
+ ### Fast mode (default)
156
+
157
+ The default behavior. Returns results immediately without polling. Use `limit` to constrain the number of results (max 300):
158
+
159
+ ```typescript
160
+ const results = await client.twitter.searchPosts("bitcoin", {
161
+ startDate: "2025-01-01",
162
+ responseType: ResponseType.Fast,
163
+ limit: 50,
164
+ });
165
+ console.log(results.data.length); // up to 50 results, returned immediately
166
+ ```
167
+
168
+ ### Paging mode
169
+
170
+ Returns paginated results with full `totalRows`, `totalPages`, and `tableName` for cursor-based navigation:
171
+
172
+ ```typescript
173
+ const results = await client.twitter.searchPosts("bitcoin", {
174
+ startDate: "2025-01-01",
175
+ responseType: ResponseType.Paging, // optional — this is the default
176
+ });
177
+ console.log(results.pagination.totalRows); // total matching rows
178
+ if (results.hasNextPage()) {
179
+ const page2 = await results.nextPage();
180
+ }
181
+ ```
182
+
183
+ ### CSV mode
184
+
185
+ Initiates an async export. Call `exportCsv()` on the result to poll the export operation and get a download URL:
186
+
187
+ ```typescript
188
+ const results = await client.twitter.searchPosts("bitcoin", {
189
+ startDate: "2025-01-01",
190
+ responseType: ResponseType.Csv,
191
+ });
192
+ const downloadUrl = await results.exportCsv();
193
+ console.log(downloadUrl); // URL to download the CSV file
194
+ ```
195
+
196
+ ### Methods supporting `responseType` and `limit`
197
+
198
+ The following methods accept both `responseType` and `limit`:
199
+
200
+ - `twitter.getPostsByAuthor()`, `twitter.searchPosts()`, `twitter.getUsersByKeywords()`
201
+ - `instagram.getPostsByUser()`, `instagram.searchPosts()`, `instagram.getUsersByKeywords()`
202
+ - `reddit.searchPosts()`
203
+
204
+ These methods accept `limit` only:
205
+
206
+ - `twitter.searchUsers()`, `instagram.searchUsers()`, `reddit.searchUsers()`, `reddit.searchSubreddits()`
207
+
138
208
  ## Query Syntax
139
209
 
140
210
  The `query` parameter on all `search*` and `get*ByKeywords` methods supports a Lucene-style full-text syntax across Twitter, Instagram, and Reddit.
@@ -189,7 +259,8 @@ import {
189
259
  OperationTimeoutError,
190
260
  OperationFailedError,
191
261
  OperationCancelledError,
192
- } from "xpoz";
262
+ ResponseType,
263
+ } from "@xpoz/xpoz";
193
264
 
194
265
  try {
195
266
  const user = await client.twitter.getUser("nonexistent_user_12345");
@@ -226,10 +297,11 @@ const user = await client.twitter.getUser("44196397", { identifierType: "id" });
226
297
 
227
298
  #### `searchUsers(name, options?) -> Promise<TwitterUser[]>`
228
299
 
229
- Search users by name or username. Returns up to 10 results.
300
+ Search users by name or username. Returns up to 10 results by default. Use `limit` to adjust.
230
301
 
231
302
  ```typescript
232
303
  const users = await client.twitter.searchUsers("elon");
304
+ const topFive = await client.twitter.searchUsers("elon", { limit: 5 });
233
305
  ```
234
306
 
235
307
  #### `getUserConnections(username, connectionType, options?) -> Promise<PaginatedResult<TwitterUser>>`
@@ -243,11 +315,13 @@ const following = await client.twitter.getUserConnections("elonmusk", "following
243
315
 
244
316
  #### `getUsersByKeywords(query, options?) -> Promise<PaginatedResult<TwitterUser>>`
245
317
 
246
- Find users who authored posts matching a keyword query.
318
+ Find users who authored posts matching a keyword query. Supports `responseType` and `limit`.
247
319
 
248
320
  ```typescript
249
321
  const users = await client.twitter.getUsersByKeywords('"machine learning"', {
250
322
  fields: ["username", "name", "followersCount"],
323
+ responseType: ResponseType.Fast,
324
+ limit: 20,
251
325
  });
252
326
  ```
253
327
 
@@ -261,17 +335,19 @@ const tweets = await client.twitter.getPostsByIds(["1234567890", "0987654321"]);
261
335
 
262
336
  #### `getPostsByAuthor(identifier, options?) -> Promise<PaginatedResult<TwitterPost>>`
263
337
 
264
- Get all posts by an author with optional date filtering.
338
+ Get all posts by an author with optional date filtering. Supports `responseType` and `limit`.
265
339
 
266
340
  ```typescript
267
341
  const results = await client.twitter.getPostsByAuthor("elonmusk", {
268
342
  startDate: "2025-01-01",
343
+ responseType: ResponseType.Fast,
344
+ limit: 100,
269
345
  });
270
346
  ```
271
347
 
272
348
  #### `searchPosts(query, options?) -> Promise<PaginatedResult<TwitterPost>>`
273
349
 
274
- Full-text search with filters. Supports exact phrases (`"machine learning"`), boolean operators (`AI AND python`), and parentheses.
350
+ Full-text search with filters. Supports exact phrases (`"machine learning"`), boolean operators (`AI AND python`), and parentheses. Supports `responseType` and `limit`.
275
351
 
276
352
  ```typescript
277
353
  const results = await client.twitter.searchPosts('"artificial intelligence" AND ethics', {
@@ -279,6 +355,8 @@ const results = await client.twitter.searchPosts('"artificial intelligence" AND
279
355
  endDate: "2025-06-01",
280
356
  language: "en",
281
357
  fields: ["id", "text", "likeCount", "authorUsername", "createdAtDate"],
358
+ responseType: ResponseType.Fast,
359
+ limit: 50,
282
360
  });
283
361
  ```
284
362
 
@@ -336,8 +414,11 @@ console.log(`${user.fullName} — ${user.followerCount?.toLocaleString()} follow
336
414
 
337
415
  #### `searchUsers(name, options?) -> Promise<InstagramUser[]>`
338
416
 
417
+ Search users by name. Use `limit` to adjust the number of results.
418
+
339
419
  ```typescript
340
420
  const users = await client.instagram.searchUsers("nasa");
421
+ const topThree = await client.instagram.searchUsers("nasa", { limit: 3 });
341
422
  ```
342
423
 
343
424
  #### `getUserConnections(username, connectionType, options?) -> Promise<PaginatedResult<InstagramUser>>`
@@ -348,8 +429,13 @@ const followers = await client.instagram.getUserConnections("instagram", "follow
348
429
 
349
430
  #### `getUsersByKeywords(query, options?) -> Promise<PaginatedResult<InstagramUser>>`
350
431
 
432
+ Find users who authored posts matching a keyword query. Supports `responseType` and `limit`.
433
+
351
434
  ```typescript
352
- const users = await client.instagram.getUsersByKeywords('"sustainable fashion"');
435
+ const users = await client.instagram.getUsersByKeywords('"sustainable fashion"', {
436
+ responseType: ResponseType.Fast,
437
+ limit: 20,
438
+ });
353
439
  ```
354
440
 
355
441
  #### `getPostsByIds(postIds, options?) -> Promise<InstagramPost[]>`
@@ -362,14 +448,24 @@ const posts = await client.instagram.getPostsByIds(["3606450040306139062_4836333
362
448
 
363
449
  #### `getPostsByUser(identifier, options?) -> Promise<PaginatedResult<InstagramPost>>`
364
450
 
451
+ Get all posts by a user. Supports `responseType` and `limit`.
452
+
365
453
  ```typescript
366
- const results = await client.instagram.getPostsByUser("nasa");
454
+ const results = await client.instagram.getPostsByUser("nasa", {
455
+ responseType: ResponseType.Fast,
456
+ limit: 50,
457
+ });
367
458
  ```
368
459
 
369
460
  #### `searchPosts(query, options?) -> Promise<PaginatedResult<InstagramPost>>`
370
461
 
462
+ Full-text search with filters. Supports `responseType` and `limit`.
463
+
371
464
  ```typescript
372
- const results = await client.instagram.searchPosts("travel photography");
465
+ const results = await client.instagram.searchPosts("travel photography", {
466
+ responseType: ResponseType.Fast,
467
+ limit: 30,
468
+ });
373
469
  ```
374
470
 
375
471
  #### `getComments(postId, options?) -> Promise<PaginatedResult<InstagramComment>>`
@@ -402,8 +498,11 @@ console.log(`${user.username} — ${user.totalKarma?.toLocaleString()} karma`);
402
498
 
403
499
  #### `searchUsers(name, options?) -> Promise<RedditUser[]>`
404
500
 
501
+ Search users by name. Use `limit` to adjust the number of results.
502
+
405
503
  ```typescript
406
504
  const users = await client.reddit.searchUsers("spez");
505
+ const topThree = await client.reddit.searchUsers("spez", { limit: 3 });
407
506
  ```
408
507
 
409
508
  #### `getUsersByKeywords(query, options?) -> Promise<PaginatedResult<RedditUser>>`
@@ -416,13 +515,15 @@ const users = await client.reddit.getUsersByKeywords('"machine learning"', {
416
515
 
417
516
  #### `searchPosts(query, options?) -> Promise<PaginatedResult<RedditPost>>`
418
517
 
419
- `sort`: `"relevance"`, `"hot"`, `"top"`, `"new"`, `"comments"`. `time`: `"hour"`, `"day"`, `"week"`, `"month"`, `"year"`, `"all"`.
518
+ `sort`: `"relevance"`, `"hot"`, `"top"`, `"new"`, `"comments"`. `time`: `"hour"`, `"day"`, `"week"`, `"month"`, `"year"`, `"all"`. Supports `responseType` and `limit`.
420
519
 
421
520
  ```typescript
422
521
  const results = await client.reddit.searchPosts("python tutorial", {
423
522
  subreddit: "learnpython",
424
523
  sort: "top",
425
524
  time: "month",
525
+ responseType: ResponseType.Fast,
526
+ limit: 25,
426
527
  });
427
528
  ```
428
529
 
@@ -448,8 +549,11 @@ const comments = await client.reddit.searchComments("helpful tip", {
448
549
 
449
550
  #### `searchSubreddits(query, options?) -> Promise<RedditSubreddit[]>`
450
551
 
552
+ Search subreddits by name. Use `limit` to adjust the number of results.
553
+
451
554
  ```typescript
452
555
  const subs = await client.reddit.searchSubreddits("machine learning");
556
+ const topFive = await client.reddit.searchSubreddits("machine learning", { limit: 5 });
453
557
  ```
454
558
 
455
559
  #### `getSubredditWithPosts(subredditName, options?) -> Promise<SubredditWithPosts>`
@@ -634,12 +738,14 @@ All fields are optional and typed as their respective TypeScript types. Unknown
634
738
  - `post: RedditPost`
635
739
  - `comments: RedditComment[]`
636
740
  - `commentsPagination: PaginationInfo | null`
741
+ - `commentsTableName: string | null`
637
742
 
638
743
  **`SubredditWithPosts`** — returned by `getSubredditWithPosts()`:
639
744
 
640
745
  - `subreddit: RedditSubreddit`
641
746
  - `posts: RedditPost[]`
642
747
  - `postsPagination: PaginationInfo | null`
748
+ - `postsTableName: string | null`
643
749
 
644
750
  ---
645
751
 
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  OperationFailedError: () => OperationFailedError,
26
26
  OperationTimeoutError: () => OperationTimeoutError,
27
27
  PaginatedResult: () => PaginatedResult,
28
+ ResponseType: () => ResponseType,
28
29
  VERSION: () => VERSION,
29
30
  XpozClient: () => XpozClient,
30
31
  XpozConnectionError: () => XpozConnectionError,
@@ -282,7 +283,7 @@ function coerce(value) {
282
283
  }
283
284
 
284
285
  // src/version.ts
285
- var VERSION = "0.1.0";
286
+ var VERSION = "0.2.0";
286
287
 
287
288
  // src/mcp/transport.ts
288
289
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -395,6 +396,12 @@ var OperationCancelledError = class extends XpozError {
395
396
  var DEFAULT_SERVER_URL = "https://mcp.xpoz.ai/mcp";
396
397
  var ENV_API_KEY = "XPOZ_API_KEY";
397
398
  var ENV_SERVER_URL = "XPOZ_SERVER_URL";
399
+ var ResponseType = /* @__PURE__ */ ((ResponseType2) => {
400
+ ResponseType2["Fast"] = "fast";
401
+ ResponseType2["Paging"] = "paging";
402
+ ResponseType2["Csv"] = "csv";
403
+ return ResponseType2;
404
+ })(ResponseType || {});
398
405
  var POLL_INTERVAL_MS = 5e3;
399
406
  var DEFAULT_TIMEOUT_MS = 3e5;
400
407
 
@@ -499,6 +506,9 @@ var BaseNamespace = class {
499
506
  }
500
507
  async callAndMaybePoll(toolName, args) {
501
508
  const result = await this.callTool(toolName, args);
509
+ if ("results" in result) {
510
+ return result;
511
+ }
502
512
  const operationId = result["operationId"];
503
513
  if (operationId) {
504
514
  return waitForResult(this.callTool, operationId, this.timeoutMs);
@@ -517,7 +527,11 @@ var BaseNamespace = class {
517
527
  return this.buildPaginatedResult(pageRaw, parseItem, toolName, baseArgs);
518
528
  };
519
529
  const fetchExport = async (opId) => {
520
- const pollResult = await waitForResult(this.callTool, opId, this.timeoutMs);
530
+ const pollResult = await waitForResult(
531
+ this.callTool,
532
+ opId,
533
+ this.timeoutMs
534
+ );
521
535
  return pollResult["downloadUrl"] ?? "";
522
536
  };
523
537
  return new PaginatedResult({
@@ -593,12 +607,13 @@ var TwitterNamespace = class extends BaseNamespace {
593
607
  }
594
608
  async getPostsByAuthor(identifier, options = {}) {
595
609
  const args = this.buildArgs({
596
- identifier,
597
- identifierType: options.identifierType ?? "username",
610
+ username: identifier,
598
611
  fields: options.fields,
599
612
  startDate: options.startDate,
600
613
  endDate: options.endDate,
601
- forceLatest: options.forceLatest
614
+ forceLatest: options.forceLatest,
615
+ responseType: options.responseType,
616
+ limit: options.limit
602
617
  });
603
618
  const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_AUTHOR, args);
604
619
  return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_POSTS_BY_AUTHOR, args);
@@ -613,9 +628,10 @@ var TwitterNamespace = class extends BaseNamespace {
613
628
  authorId: options.authorId,
614
629
  language: options.language,
615
630
  forceLatest: options.forceLatest,
616
- responseType: options.responseType
631
+ responseType: options.responseType,
632
+ limit: options.limit
617
633
  });
618
- if (options.responseType === "csv") {
634
+ if (options.responseType === "csv" /* Csv */) {
619
635
  const raw = await this.callTool(SEARCH_TWITTER_POSTS, args);
620
636
  const exportOpId = raw["operationId"] ?? raw["dataDumpExportOperationId"] ?? null;
621
637
  const csvRaw = { results: [], dataDumpExportOperationId: exportOpId };
@@ -726,7 +742,9 @@ var InstagramNamespace = class extends BaseNamespace {
726
742
  fields: options.fields,
727
743
  startDate: options.startDate,
728
744
  endDate: options.endDate,
729
- forceLatest: options.forceLatest
745
+ forceLatest: options.forceLatest,
746
+ responseType: options.responseType,
747
+ limit: options.limit
730
748
  });
731
749
  const result = await this.callAndMaybePoll(GET_INSTAGRAM_POSTS_BY_USER, args);
732
750
  return this.buildPaginatedResult(
@@ -737,7 +755,15 @@ var InstagramNamespace = class extends BaseNamespace {
737
755
  );
738
756
  }
739
757
  async searchPosts(query, options = {}) {
740
- const args = this.buildArgs({ query, ...options });
758
+ const args = this.buildArgs({
759
+ query,
760
+ fields: options.fields,
761
+ startDate: options.startDate,
762
+ endDate: options.endDate,
763
+ forceLatest: options.forceLatest,
764
+ responseType: options.responseType,
765
+ limit: options.limit
766
+ });
741
767
  const result = await this.callAndMaybePoll(SEARCH_INSTAGRAM_POSTS, args);
742
768
  return this.buildPaginatedResult(result, parsePost, SEARCH_INSTAGRAM_POSTS, args);
743
769
  }
@@ -942,6 +968,7 @@ var XpozClient = class {
942
968
  OperationFailedError,
943
969
  OperationTimeoutError,
944
970
  PaginatedResult,
971
+ ResponseType,
945
972
  VERSION,
946
973
  XpozClient,
947
974
  XpozConnectionError,
package/dist/index.d.cts CHANGED
@@ -144,17 +144,24 @@ interface TwitterUser {
144
144
  [key: string]: unknown;
145
145
  }
146
146
 
147
+ declare enum ResponseType {
148
+ Fast = "fast",
149
+ Paging = "paging",
150
+ Csv = "csv"
151
+ }
152
+
147
153
  declare class TwitterNamespace extends BaseNamespace {
148
154
  getPostsByIds(postIds: string[], options?: {
149
155
  fields?: string[];
150
156
  forceLatest?: boolean;
151
157
  }): Promise<TwitterPost[]>;
152
158
  getPostsByAuthor(identifier: string, options?: {
153
- identifierType?: string;
154
159
  fields?: string[];
155
160
  startDate?: string;
156
161
  endDate?: string;
157
162
  forceLatest?: boolean;
163
+ responseType?: ResponseType;
164
+ limit?: number;
158
165
  }): Promise<PaginatedResult<TwitterPost>>;
159
166
  searchPosts(query: string, options?: {
160
167
  fields?: string[];
@@ -164,7 +171,8 @@ declare class TwitterNamespace extends BaseNamespace {
164
171
  authorId?: string;
165
172
  language?: string;
166
173
  forceLatest?: boolean;
167
- responseType?: string;
174
+ responseType?: ResponseType;
175
+ limit?: number;
168
176
  }): Promise<PaginatedResult<TwitterPost>>;
169
177
  getRetweets(postId: string, options?: {
170
178
  fields?: string[];
@@ -206,6 +214,8 @@ declare class TwitterNamespace extends BaseNamespace {
206
214
  endDate?: string;
207
215
  language?: string;
208
216
  forceLatest?: boolean;
217
+ responseType?: ResponseType;
218
+ limit?: number;
209
219
  }): Promise<PaginatedResult<TwitterUser>>;
210
220
  }
211
221
 
@@ -300,12 +310,16 @@ declare class InstagramNamespace extends BaseNamespace {
300
310
  startDate?: string;
301
311
  endDate?: string;
302
312
  forceLatest?: boolean;
313
+ responseType?: ResponseType;
314
+ limit?: number;
303
315
  }): Promise<PaginatedResult<InstagramPost>>;
304
316
  searchPosts(query: string, options?: {
305
317
  fields?: string[];
306
318
  startDate?: string;
307
319
  endDate?: string;
308
320
  forceLatest?: boolean;
321
+ responseType?: ResponseType;
322
+ limit?: number;
309
323
  }): Promise<PaginatedResult<InstagramPost>>;
310
324
  getComments(postId: string, options?: {
311
325
  fields?: string[];
@@ -334,6 +348,8 @@ declare class InstagramNamespace extends BaseNamespace {
334
348
  startDate?: string;
335
349
  endDate?: string;
336
350
  forceLatest?: boolean;
351
+ responseType?: ResponseType;
352
+ limit?: number;
337
353
  }): Promise<PaginatedResult<InstagramUser>>;
338
354
  }
339
355
 
@@ -490,6 +506,8 @@ declare class RedditNamespace extends BaseNamespace {
490
506
  time?: string;
491
507
  subreddit?: string;
492
508
  forceLatest?: boolean;
509
+ responseType?: ResponseType;
510
+ limit?: number;
493
511
  }): Promise<PaginatedResult<RedditPost>>;
494
512
  getPostWithComments(postId: string, options?: {
495
513
  postFields?: string[];
@@ -574,6 +592,6 @@ declare class OperationCancelledError extends XpozError {
574
592
  constructor(operationId: string);
575
593
  }
576
594
 
577
- declare const VERSION = "0.1.0";
595
+ declare const VERSION = "0.2.0";
578
596
 
579
- export { AuthenticationError, type InstagramComment, type InstagramPost, type InstagramUser, OperationCancelledError, OperationFailedError, OperationTimeoutError, PaginatedResult, type PaginationInfo, type RedditComment, type RedditPost, type RedditPostWithComments, type RedditSubreddit, type RedditUser, type SubredditWithPosts, type TwitterPost, type TwitterUser, VERSION, XpozClient, XpozConnectionError, XpozError };
597
+ export { AuthenticationError, type InstagramComment, type InstagramPost, type InstagramUser, OperationCancelledError, OperationFailedError, OperationTimeoutError, PaginatedResult, type PaginationInfo, type RedditComment, type RedditPost, type RedditPostWithComments, type RedditSubreddit, type RedditUser, ResponseType, type SubredditWithPosts, type TwitterPost, type TwitterUser, VERSION, XpozClient, XpozConnectionError, XpozError };
package/dist/index.d.ts CHANGED
@@ -144,17 +144,24 @@ interface TwitterUser {
144
144
  [key: string]: unknown;
145
145
  }
146
146
 
147
+ declare enum ResponseType {
148
+ Fast = "fast",
149
+ Paging = "paging",
150
+ Csv = "csv"
151
+ }
152
+
147
153
  declare class TwitterNamespace extends BaseNamespace {
148
154
  getPostsByIds(postIds: string[], options?: {
149
155
  fields?: string[];
150
156
  forceLatest?: boolean;
151
157
  }): Promise<TwitterPost[]>;
152
158
  getPostsByAuthor(identifier: string, options?: {
153
- identifierType?: string;
154
159
  fields?: string[];
155
160
  startDate?: string;
156
161
  endDate?: string;
157
162
  forceLatest?: boolean;
163
+ responseType?: ResponseType;
164
+ limit?: number;
158
165
  }): Promise<PaginatedResult<TwitterPost>>;
159
166
  searchPosts(query: string, options?: {
160
167
  fields?: string[];
@@ -164,7 +171,8 @@ declare class TwitterNamespace extends BaseNamespace {
164
171
  authorId?: string;
165
172
  language?: string;
166
173
  forceLatest?: boolean;
167
- responseType?: string;
174
+ responseType?: ResponseType;
175
+ limit?: number;
168
176
  }): Promise<PaginatedResult<TwitterPost>>;
169
177
  getRetweets(postId: string, options?: {
170
178
  fields?: string[];
@@ -206,6 +214,8 @@ declare class TwitterNamespace extends BaseNamespace {
206
214
  endDate?: string;
207
215
  language?: string;
208
216
  forceLatest?: boolean;
217
+ responseType?: ResponseType;
218
+ limit?: number;
209
219
  }): Promise<PaginatedResult<TwitterUser>>;
210
220
  }
211
221
 
@@ -300,12 +310,16 @@ declare class InstagramNamespace extends BaseNamespace {
300
310
  startDate?: string;
301
311
  endDate?: string;
302
312
  forceLatest?: boolean;
313
+ responseType?: ResponseType;
314
+ limit?: number;
303
315
  }): Promise<PaginatedResult<InstagramPost>>;
304
316
  searchPosts(query: string, options?: {
305
317
  fields?: string[];
306
318
  startDate?: string;
307
319
  endDate?: string;
308
320
  forceLatest?: boolean;
321
+ responseType?: ResponseType;
322
+ limit?: number;
309
323
  }): Promise<PaginatedResult<InstagramPost>>;
310
324
  getComments(postId: string, options?: {
311
325
  fields?: string[];
@@ -334,6 +348,8 @@ declare class InstagramNamespace extends BaseNamespace {
334
348
  startDate?: string;
335
349
  endDate?: string;
336
350
  forceLatest?: boolean;
351
+ responseType?: ResponseType;
352
+ limit?: number;
337
353
  }): Promise<PaginatedResult<InstagramUser>>;
338
354
  }
339
355
 
@@ -490,6 +506,8 @@ declare class RedditNamespace extends BaseNamespace {
490
506
  time?: string;
491
507
  subreddit?: string;
492
508
  forceLatest?: boolean;
509
+ responseType?: ResponseType;
510
+ limit?: number;
493
511
  }): Promise<PaginatedResult<RedditPost>>;
494
512
  getPostWithComments(postId: string, options?: {
495
513
  postFields?: string[];
@@ -574,6 +592,6 @@ declare class OperationCancelledError extends XpozError {
574
592
  constructor(operationId: string);
575
593
  }
576
594
 
577
- declare const VERSION = "0.1.0";
595
+ declare const VERSION = "0.2.0";
578
596
 
579
- export { AuthenticationError, type InstagramComment, type InstagramPost, type InstagramUser, OperationCancelledError, OperationFailedError, OperationTimeoutError, PaginatedResult, type PaginationInfo, type RedditComment, type RedditPost, type RedditPostWithComments, type RedditSubreddit, type RedditUser, type SubredditWithPosts, type TwitterPost, type TwitterUser, VERSION, XpozClient, XpozConnectionError, XpozError };
597
+ export { AuthenticationError, type InstagramComment, type InstagramPost, type InstagramUser, OperationCancelledError, OperationFailedError, OperationTimeoutError, PaginatedResult, type PaginationInfo, type RedditComment, type RedditPost, type RedditPostWithComments, type RedditSubreddit, type RedditUser, ResponseType, type SubredditWithPosts, type TwitterPost, type TwitterUser, VERSION, XpozClient, XpozConnectionError, XpozError };
package/dist/index.js CHANGED
@@ -248,7 +248,7 @@ function coerce(value) {
248
248
  }
249
249
 
250
250
  // src/version.ts
251
- var VERSION = "0.1.0";
251
+ var VERSION = "0.2.0";
252
252
 
253
253
  // src/mcp/transport.ts
254
254
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -361,6 +361,12 @@ var OperationCancelledError = class extends XpozError {
361
361
  var DEFAULT_SERVER_URL = "https://mcp.xpoz.ai/mcp";
362
362
  var ENV_API_KEY = "XPOZ_API_KEY";
363
363
  var ENV_SERVER_URL = "XPOZ_SERVER_URL";
364
+ var ResponseType = /* @__PURE__ */ ((ResponseType2) => {
365
+ ResponseType2["Fast"] = "fast";
366
+ ResponseType2["Paging"] = "paging";
367
+ ResponseType2["Csv"] = "csv";
368
+ return ResponseType2;
369
+ })(ResponseType || {});
364
370
  var POLL_INTERVAL_MS = 5e3;
365
371
  var DEFAULT_TIMEOUT_MS = 3e5;
366
372
 
@@ -465,6 +471,9 @@ var BaseNamespace = class {
465
471
  }
466
472
  async callAndMaybePoll(toolName, args) {
467
473
  const result = await this.callTool(toolName, args);
474
+ if ("results" in result) {
475
+ return result;
476
+ }
468
477
  const operationId = result["operationId"];
469
478
  if (operationId) {
470
479
  return waitForResult(this.callTool, operationId, this.timeoutMs);
@@ -483,7 +492,11 @@ var BaseNamespace = class {
483
492
  return this.buildPaginatedResult(pageRaw, parseItem, toolName, baseArgs);
484
493
  };
485
494
  const fetchExport = async (opId) => {
486
- const pollResult = await waitForResult(this.callTool, opId, this.timeoutMs);
495
+ const pollResult = await waitForResult(
496
+ this.callTool,
497
+ opId,
498
+ this.timeoutMs
499
+ );
487
500
  return pollResult["downloadUrl"] ?? "";
488
501
  };
489
502
  return new PaginatedResult({
@@ -559,12 +572,13 @@ var TwitterNamespace = class extends BaseNamespace {
559
572
  }
560
573
  async getPostsByAuthor(identifier, options = {}) {
561
574
  const args = this.buildArgs({
562
- identifier,
563
- identifierType: options.identifierType ?? "username",
575
+ username: identifier,
564
576
  fields: options.fields,
565
577
  startDate: options.startDate,
566
578
  endDate: options.endDate,
567
- forceLatest: options.forceLatest
579
+ forceLatest: options.forceLatest,
580
+ responseType: options.responseType,
581
+ limit: options.limit
568
582
  });
569
583
  const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_AUTHOR, args);
570
584
  return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_POSTS_BY_AUTHOR, args);
@@ -579,9 +593,10 @@ var TwitterNamespace = class extends BaseNamespace {
579
593
  authorId: options.authorId,
580
594
  language: options.language,
581
595
  forceLatest: options.forceLatest,
582
- responseType: options.responseType
596
+ responseType: options.responseType,
597
+ limit: options.limit
583
598
  });
584
- if (options.responseType === "csv") {
599
+ if (options.responseType === "csv" /* Csv */) {
585
600
  const raw = await this.callTool(SEARCH_TWITTER_POSTS, args);
586
601
  const exportOpId = raw["operationId"] ?? raw["dataDumpExportOperationId"] ?? null;
587
602
  const csvRaw = { results: [], dataDumpExportOperationId: exportOpId };
@@ -692,7 +707,9 @@ var InstagramNamespace = class extends BaseNamespace {
692
707
  fields: options.fields,
693
708
  startDate: options.startDate,
694
709
  endDate: options.endDate,
695
- forceLatest: options.forceLatest
710
+ forceLatest: options.forceLatest,
711
+ responseType: options.responseType,
712
+ limit: options.limit
696
713
  });
697
714
  const result = await this.callAndMaybePoll(GET_INSTAGRAM_POSTS_BY_USER, args);
698
715
  return this.buildPaginatedResult(
@@ -703,7 +720,15 @@ var InstagramNamespace = class extends BaseNamespace {
703
720
  );
704
721
  }
705
722
  async searchPosts(query, options = {}) {
706
- const args = this.buildArgs({ query, ...options });
723
+ const args = this.buildArgs({
724
+ query,
725
+ fields: options.fields,
726
+ startDate: options.startDate,
727
+ endDate: options.endDate,
728
+ forceLatest: options.forceLatest,
729
+ responseType: options.responseType,
730
+ limit: options.limit
731
+ });
707
732
  const result = await this.callAndMaybePoll(SEARCH_INSTAGRAM_POSTS, args);
708
733
  return this.buildPaginatedResult(result, parsePost, SEARCH_INSTAGRAM_POSTS, args);
709
734
  }
@@ -907,6 +932,7 @@ export {
907
932
  OperationFailedError,
908
933
  OperationTimeoutError,
909
934
  PaginatedResult,
935
+ ResponseType,
910
936
  VERSION,
911
937
  XpozClient,
912
938
  XpozConnectionError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpoz/xpoz",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript SDK for the Xpoz social media intelligence platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -43,5 +43,14 @@
43
43
  "url": "https://github.com/XPOZpublic/xpoz-ts-sdk/issues"
44
44
  },
45
45
  "license": "MIT",
46
- "keywords": ["xpoz", "social-media", "twitter", "instagram", "reddit", "sdk", "mcp", "api"]
46
+ "keywords": [
47
+ "xpoz",
48
+ "social-media",
49
+ "twitter",
50
+ "instagram",
51
+ "reddit",
52
+ "sdk",
53
+ "mcp",
54
+ "api"
55
+ ]
47
56
  }