@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 +117 -11
- package/dist/index.cjs +36 -9
- package/dist/index.d.cts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +35 -9
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Xpoz TypeScript SDK
|
|
2
2
|
|
|
3
|
+
[](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
|
-
|
|
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.
|
|
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(
|
|
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({
|
|
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?:
|
|
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.
|
|
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?:
|
|
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.
|
|
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.
|
|
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(
|
|
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({
|
|
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.
|
|
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": [
|
|
46
|
+
"keywords": [
|
|
47
|
+
"xpoz",
|
|
48
|
+
"social-media",
|
|
49
|
+
"twitter",
|
|
50
|
+
"instagram",
|
|
51
|
+
"reddit",
|
|
52
|
+
"sdk",
|
|
53
|
+
"mcp",
|
|
54
|
+
"api"
|
|
55
|
+
]
|
|
47
56
|
}
|