@xpoz/xpoz 0.2.0 → 0.3.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/dist/index.cjs CHANGED
@@ -29,7 +29,8 @@ __export(index_exports, {
29
29
  VERSION: () => VERSION,
30
30
  XpozClient: () => XpozClient,
31
31
  XpozConnectionError: () => XpozConnectionError,
32
- XpozError: () => XpozError
32
+ XpozError: () => XpozError,
33
+ checkForUpdates: () => checkForUpdates
33
34
  });
34
35
  module.exports = __toCommonJS(index_exports);
35
36
 
@@ -283,7 +284,7 @@ function coerce(value) {
283
284
  }
284
285
 
285
286
  // src/version.ts
286
- var VERSION = "0.2.0";
287
+ var VERSION = "0.3.0";
287
288
 
288
289
  // src/mcp/transport.ts
289
290
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -570,6 +571,7 @@ var GET_TWITTER_COMMENTS = "getTwitterPostComments";
570
571
  var GET_TWITTER_POST_INTERACTING_USERS = "getTwitterPostInteractingUsers";
571
572
  var COUNT_TWEETS = "countTweets";
572
573
  var GET_TWITTER_USER = "getTwitterUser";
574
+ var GET_TWITTER_USERS = "getTwitterUsers";
573
575
  var SEARCH_TWITTER_USERS = "searchTwitterUsers";
574
576
  var GET_TWITTER_USER_CONNECTIONS = "getTwitterUserConnections";
575
577
  var GET_TWITTER_USERS_BY_KEYWORDS = "getTwitterUsersByKeywords";
@@ -602,7 +604,10 @@ function parseUser(item) {
602
604
  var TwitterNamespace = class extends BaseNamespace {
603
605
  async getPostsByIds(postIds, options = {}) {
604
606
  const args = this.buildArgs({ postIds, ...options });
605
- const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_IDS, args);
607
+ const result = await this.callAndMaybePoll(
608
+ GET_TWITTER_POSTS_BY_IDS,
609
+ args
610
+ );
606
611
  return (result["results"] ?? []).map(parseTwitterPost);
607
612
  }
608
613
  async getPostsByAuthor(identifier, options = {}) {
@@ -615,8 +620,16 @@ var TwitterNamespace = class extends BaseNamespace {
615
620
  responseType: options.responseType,
616
621
  limit: options.limit
617
622
  });
618
- const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_AUTHOR, args);
619
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_POSTS_BY_AUTHOR, args);
623
+ const result = await this.callAndMaybePoll(
624
+ GET_TWITTER_POSTS_BY_AUTHOR,
625
+ args
626
+ );
627
+ return this.buildPaginatedResult(
628
+ result,
629
+ parseTwitterPost,
630
+ GET_TWITTER_POSTS_BY_AUTHOR,
631
+ args
632
+ );
620
633
  }
621
634
  async searchPosts(query, options = {}) {
622
635
  const args = this.buildArgs({
@@ -627,6 +640,7 @@ var TwitterNamespace = class extends BaseNamespace {
627
640
  authorUsername: options.authorUsername,
628
641
  authorId: options.authorId,
629
642
  language: options.language,
643
+ filterOutRetweets: options.filterOutRetweets,
630
644
  forceLatest: options.forceLatest,
631
645
  responseType: options.responseType,
632
646
  limit: options.limit
@@ -634,30 +648,70 @@ var TwitterNamespace = class extends BaseNamespace {
634
648
  if (options.responseType === "csv" /* Csv */) {
635
649
  const raw = await this.callTool(SEARCH_TWITTER_POSTS, args);
636
650
  const exportOpId = raw["operationId"] ?? raw["dataDumpExportOperationId"] ?? null;
637
- const csvRaw = { results: [], dataDumpExportOperationId: exportOpId };
638
- return this.buildPaginatedResult(csvRaw, parseTwitterPost, SEARCH_TWITTER_POSTS, args);
651
+ const csvRaw = {
652
+ results: [],
653
+ dataDumpExportOperationId: exportOpId
654
+ };
655
+ return this.buildPaginatedResult(
656
+ csvRaw,
657
+ parseTwitterPost,
658
+ SEARCH_TWITTER_POSTS,
659
+ args
660
+ );
639
661
  }
640
- const result = await this.callAndMaybePoll(SEARCH_TWITTER_POSTS, args);
641
- return this.buildPaginatedResult(result, parseTwitterPost, SEARCH_TWITTER_POSTS, args);
662
+ const result = await this.callAndMaybePoll(
663
+ SEARCH_TWITTER_POSTS,
664
+ args
665
+ );
666
+ return this.buildPaginatedResult(
667
+ result,
668
+ parseTwitterPost,
669
+ SEARCH_TWITTER_POSTS,
670
+ args
671
+ );
642
672
  }
643
673
  async getRetweets(postId, options = {}) {
644
674
  const args = this.buildArgs({ postId, ...options });
645
- const result = await this.callAndMaybePoll(GET_TWITTER_RETWEETS, args);
646
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_RETWEETS, args);
675
+ const result = await this.callAndMaybePoll(
676
+ GET_TWITTER_RETWEETS,
677
+ args
678
+ );
679
+ return this.buildPaginatedResult(
680
+ result,
681
+ parseTwitterPost,
682
+ GET_TWITTER_RETWEETS,
683
+ args
684
+ );
647
685
  }
648
686
  async getQuotes(postId, options = {}) {
649
687
  const args = this.buildArgs({ postId, ...options });
650
688
  const result = await this.callAndMaybePoll(GET_TWITTER_QUOTES, args);
651
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_QUOTES, args);
689
+ return this.buildPaginatedResult(
690
+ result,
691
+ parseTwitterPost,
692
+ GET_TWITTER_QUOTES,
693
+ args
694
+ );
652
695
  }
653
696
  async getComments(postId, options = {}) {
654
697
  const args = this.buildArgs({ postId, ...options });
655
- const result = await this.callAndMaybePoll(GET_TWITTER_COMMENTS, args);
656
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_COMMENTS, args);
698
+ const result = await this.callAndMaybePoll(
699
+ GET_TWITTER_COMMENTS,
700
+ args
701
+ );
702
+ return this.buildPaginatedResult(
703
+ result,
704
+ parseTwitterPost,
705
+ GET_TWITTER_COMMENTS,
706
+ args
707
+ );
657
708
  }
658
709
  async getPostInteractingUsers(postId, interactionType, options = {}) {
659
710
  const args = this.buildArgs({ postId, interactionType, ...options });
660
- const result = await this.callAndMaybePoll(GET_TWITTER_POST_INTERACTING_USERS, args);
711
+ const result = await this.callAndMaybePoll(
712
+ GET_TWITTER_POST_INTERACTING_USERS,
713
+ args
714
+ );
661
715
  return this.buildPaginatedResult(
662
716
  result,
663
717
  parseUser,
@@ -679,6 +733,16 @@ var TwitterNamespace = class extends BaseNamespace {
679
733
  }
680
734
  return Number(count);
681
735
  }
736
+ async getUsers(identifiers, options = {}) {
737
+ const args = this.buildArgs({
738
+ identifiers,
739
+ identifierType: options.identifierType ?? "username",
740
+ fields: options.fields,
741
+ forceLatest: options.forceLatest
742
+ });
743
+ const result = await this.callAndMaybePoll(GET_TWITTER_USERS, args);
744
+ return (result["results"] ?? []).map(parseUser);
745
+ }
682
746
  async getUser(identifier, options = {}) {
683
747
  const args = this.buildArgs({
684
748
  identifier,
@@ -694,12 +758,18 @@ var TwitterNamespace = class extends BaseNamespace {
694
758
  }
695
759
  async searchUsers(name, options = {}) {
696
760
  const args = this.buildArgs({ name, ...options });
697
- const result = await this.callAndMaybePoll(SEARCH_TWITTER_USERS, args);
761
+ const result = await this.callAndMaybePoll(
762
+ SEARCH_TWITTER_USERS,
763
+ args
764
+ );
698
765
  return (result["results"] ?? []).map(parseUser);
699
766
  }
700
767
  async getUserConnections(username, connectionType, options = {}) {
701
768
  const args = this.buildArgs({ username, connectionType, ...options });
702
- const result = await this.callAndMaybePoll(GET_TWITTER_USER_CONNECTIONS, args);
769
+ const result = await this.callAndMaybePoll(
770
+ GET_TWITTER_USER_CONNECTIONS,
771
+ args
772
+ );
703
773
  return this.buildPaginatedResult(
704
774
  result,
705
775
  parseUser,
@@ -709,7 +779,10 @@ var TwitterNamespace = class extends BaseNamespace {
709
779
  }
710
780
  async getUsersByKeywords(query, options = {}) {
711
781
  const args = this.buildArgs({ query, ...options });
712
- const result = await this.callAndMaybePoll(GET_TWITTER_USERS_BY_KEYWORDS, args);
782
+ const result = await this.callAndMaybePoll(
783
+ GET_TWITTER_USERS_BY_KEYWORDS,
784
+ args
785
+ );
713
786
  return this.buildPaginatedResult(
714
787
  result,
715
788
  parseUser,
@@ -930,12 +1003,53 @@ var RedditNamespace = class extends BaseNamespace {
930
1003
  }
931
1004
  };
932
1005
 
1006
+ // src/versionCheck.ts
1007
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@xpoz/xpoz/latest";
1008
+ var CHECK_TIMEOUT_MS = 3e3;
1009
+ var PACKAGE_NAME = "@xpoz/xpoz";
1010
+ var hasWarned = false;
1011
+ async function checkForUpdates() {
1012
+ if (hasWarned) return;
1013
+ try {
1014
+ const controller = new AbortController();
1015
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS);
1016
+ const response = await fetch(NPM_REGISTRY_URL, {
1017
+ signal: controller.signal,
1018
+ headers: { Accept: "application/json" }
1019
+ });
1020
+ clearTimeout(timeout);
1021
+ if (!response.ok) return;
1022
+ const data = await response.json();
1023
+ const latest = data.version;
1024
+ if (!latest || latest === VERSION) return;
1025
+ if (isNewerVersion(latest, VERSION)) {
1026
+ hasWarned = true;
1027
+ console.warn(
1028
+ `[xpoz] A newer version of ${PACKAGE_NAME} is available: ${latest} (current: ${VERSION}). Run \`npm install ${PACKAGE_NAME}@latest\` to update.`
1029
+ );
1030
+ }
1031
+ } catch {
1032
+ }
1033
+ }
1034
+ function isNewerVersion(latestVersion, currentVersion) {
1035
+ const latestVersionParts = latestVersion.split(".").map(Number);
1036
+ const currentVersionParts = currentVersion.split(".").map(Number);
1037
+ for (let i = 0; i < 3; i++) {
1038
+ const latestVersionPart = latestVersionParts[i] ?? 0;
1039
+ const currentVersionPart = currentVersionParts[i] ?? 0;
1040
+ if (latestVersionPart > currentVersionPart) return true;
1041
+ if (latestVersionPart < currentVersionPart) return false;
1042
+ }
1043
+ return false;
1044
+ }
1045
+
933
1046
  // src/client.ts
934
1047
  var XpozClient = class {
935
1048
  twitter;
936
1049
  instagram;
937
1050
  reddit;
938
1051
  transport;
1052
+ versionCheck;
939
1053
  constructor(options = {}) {
940
1054
  const apiKey = options.apiKey ?? process.env[ENV_API_KEY];
941
1055
  if (!apiKey) {
@@ -943,6 +1057,7 @@ var XpozClient = class {
943
1057
  `API key required. Get your token at http://xpoz.ai/get-token?utm_source=ts_sdk&utm_medium=sdk (login \u2192 copy token), then pass it as apiKey or set the ${ENV_API_KEY} environment variable.`
944
1058
  );
945
1059
  }
1060
+ this.versionCheck = options.versionCheck ?? true;
946
1061
  const serverUrl = options.serverUrl ?? process.env[ENV_SERVER_URL] ?? DEFAULT_SERVER_URL;
947
1062
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
948
1063
  this.transport = new McpTransport(serverUrl, apiKey);
@@ -953,6 +1068,9 @@ var XpozClient = class {
953
1068
  }
954
1069
  async connect() {
955
1070
  await this.transport.connect();
1071
+ if (this.versionCheck) {
1072
+ checkForUpdates();
1073
+ }
956
1074
  }
957
1075
  async close() {
958
1076
  await this.transport.close();
@@ -972,5 +1090,6 @@ var XpozClient = class {
972
1090
  VERSION,
973
1091
  XpozClient,
974
1092
  XpozConnectionError,
975
- XpozError
1093
+ XpozError,
1094
+ checkForUpdates
976
1095
  });
package/dist/index.d.cts CHANGED
@@ -170,6 +170,7 @@ declare class TwitterNamespace extends BaseNamespace {
170
170
  authorUsername?: string;
171
171
  authorId?: string;
172
172
  language?: string;
173
+ filterOutRetweets?: boolean;
173
174
  forceLatest?: boolean;
174
175
  responseType?: ResponseType;
175
176
  limit?: number;
@@ -196,6 +197,11 @@ declare class TwitterNamespace extends BaseNamespace {
196
197
  startDate?: string;
197
198
  endDate?: string;
198
199
  }): Promise<number>;
200
+ getUsers(identifiers: string[], options?: {
201
+ identifierType?: string;
202
+ fields?: string[];
203
+ forceLatest?: boolean;
204
+ }): Promise<TwitterUser[]>;
199
205
  getUser(identifier: string, options?: {
200
206
  identifierType?: string;
201
207
  fields?: string[];
@@ -558,10 +564,12 @@ declare class XpozClient {
558
564
  instagram: InstagramNamespace;
559
565
  reddit: RedditNamespace;
560
566
  private transport;
567
+ private versionCheck;
561
568
  constructor(options?: {
562
569
  apiKey?: string;
563
570
  serverUrl?: string;
564
571
  timeoutMs?: number;
572
+ versionCheck?: boolean;
565
573
  });
566
574
  connect(): Promise<void>;
567
575
  close(): Promise<void>;
@@ -592,6 +600,8 @@ declare class OperationCancelledError extends XpozError {
592
600
  constructor(operationId: string);
593
601
  }
594
602
 
595
- declare const VERSION = "0.2.0";
603
+ declare const VERSION = "0.3.0";
604
+
605
+ declare function checkForUpdates(): Promise<void>;
596
606
 
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 };
607
+ 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, checkForUpdates };
package/dist/index.d.ts CHANGED
@@ -170,6 +170,7 @@ declare class TwitterNamespace extends BaseNamespace {
170
170
  authorUsername?: string;
171
171
  authorId?: string;
172
172
  language?: string;
173
+ filterOutRetweets?: boolean;
173
174
  forceLatest?: boolean;
174
175
  responseType?: ResponseType;
175
176
  limit?: number;
@@ -196,6 +197,11 @@ declare class TwitterNamespace extends BaseNamespace {
196
197
  startDate?: string;
197
198
  endDate?: string;
198
199
  }): Promise<number>;
200
+ getUsers(identifiers: string[], options?: {
201
+ identifierType?: string;
202
+ fields?: string[];
203
+ forceLatest?: boolean;
204
+ }): Promise<TwitterUser[]>;
199
205
  getUser(identifier: string, options?: {
200
206
  identifierType?: string;
201
207
  fields?: string[];
@@ -558,10 +564,12 @@ declare class XpozClient {
558
564
  instagram: InstagramNamespace;
559
565
  reddit: RedditNamespace;
560
566
  private transport;
567
+ private versionCheck;
561
568
  constructor(options?: {
562
569
  apiKey?: string;
563
570
  serverUrl?: string;
564
571
  timeoutMs?: number;
572
+ versionCheck?: boolean;
565
573
  });
566
574
  connect(): Promise<void>;
567
575
  close(): Promise<void>;
@@ -592,6 +600,8 @@ declare class OperationCancelledError extends XpozError {
592
600
  constructor(operationId: string);
593
601
  }
594
602
 
595
- declare const VERSION = "0.2.0";
603
+ declare const VERSION = "0.3.0";
604
+
605
+ declare function checkForUpdates(): Promise<void>;
596
606
 
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 };
607
+ 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, checkForUpdates };
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.2.0";
251
+ var VERSION = "0.3.0";
252
252
 
253
253
  // src/mcp/transport.ts
254
254
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -535,6 +535,7 @@ var GET_TWITTER_COMMENTS = "getTwitterPostComments";
535
535
  var GET_TWITTER_POST_INTERACTING_USERS = "getTwitterPostInteractingUsers";
536
536
  var COUNT_TWEETS = "countTweets";
537
537
  var GET_TWITTER_USER = "getTwitterUser";
538
+ var GET_TWITTER_USERS = "getTwitterUsers";
538
539
  var SEARCH_TWITTER_USERS = "searchTwitterUsers";
539
540
  var GET_TWITTER_USER_CONNECTIONS = "getTwitterUserConnections";
540
541
  var GET_TWITTER_USERS_BY_KEYWORDS = "getTwitterUsersByKeywords";
@@ -567,7 +568,10 @@ function parseUser(item) {
567
568
  var TwitterNamespace = class extends BaseNamespace {
568
569
  async getPostsByIds(postIds, options = {}) {
569
570
  const args = this.buildArgs({ postIds, ...options });
570
- const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_IDS, args);
571
+ const result = await this.callAndMaybePoll(
572
+ GET_TWITTER_POSTS_BY_IDS,
573
+ args
574
+ );
571
575
  return (result["results"] ?? []).map(parseTwitterPost);
572
576
  }
573
577
  async getPostsByAuthor(identifier, options = {}) {
@@ -580,8 +584,16 @@ var TwitterNamespace = class extends BaseNamespace {
580
584
  responseType: options.responseType,
581
585
  limit: options.limit
582
586
  });
583
- const result = await this.callAndMaybePoll(GET_TWITTER_POSTS_BY_AUTHOR, args);
584
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_POSTS_BY_AUTHOR, args);
587
+ const result = await this.callAndMaybePoll(
588
+ GET_TWITTER_POSTS_BY_AUTHOR,
589
+ args
590
+ );
591
+ return this.buildPaginatedResult(
592
+ result,
593
+ parseTwitterPost,
594
+ GET_TWITTER_POSTS_BY_AUTHOR,
595
+ args
596
+ );
585
597
  }
586
598
  async searchPosts(query, options = {}) {
587
599
  const args = this.buildArgs({
@@ -592,6 +604,7 @@ var TwitterNamespace = class extends BaseNamespace {
592
604
  authorUsername: options.authorUsername,
593
605
  authorId: options.authorId,
594
606
  language: options.language,
607
+ filterOutRetweets: options.filterOutRetweets,
595
608
  forceLatest: options.forceLatest,
596
609
  responseType: options.responseType,
597
610
  limit: options.limit
@@ -599,30 +612,70 @@ var TwitterNamespace = class extends BaseNamespace {
599
612
  if (options.responseType === "csv" /* Csv */) {
600
613
  const raw = await this.callTool(SEARCH_TWITTER_POSTS, args);
601
614
  const exportOpId = raw["operationId"] ?? raw["dataDumpExportOperationId"] ?? null;
602
- const csvRaw = { results: [], dataDumpExportOperationId: exportOpId };
603
- return this.buildPaginatedResult(csvRaw, parseTwitterPost, SEARCH_TWITTER_POSTS, args);
615
+ const csvRaw = {
616
+ results: [],
617
+ dataDumpExportOperationId: exportOpId
618
+ };
619
+ return this.buildPaginatedResult(
620
+ csvRaw,
621
+ parseTwitterPost,
622
+ SEARCH_TWITTER_POSTS,
623
+ args
624
+ );
604
625
  }
605
- const result = await this.callAndMaybePoll(SEARCH_TWITTER_POSTS, args);
606
- return this.buildPaginatedResult(result, parseTwitterPost, SEARCH_TWITTER_POSTS, args);
626
+ const result = await this.callAndMaybePoll(
627
+ SEARCH_TWITTER_POSTS,
628
+ args
629
+ );
630
+ return this.buildPaginatedResult(
631
+ result,
632
+ parseTwitterPost,
633
+ SEARCH_TWITTER_POSTS,
634
+ args
635
+ );
607
636
  }
608
637
  async getRetweets(postId, options = {}) {
609
638
  const args = this.buildArgs({ postId, ...options });
610
- const result = await this.callAndMaybePoll(GET_TWITTER_RETWEETS, args);
611
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_RETWEETS, args);
639
+ const result = await this.callAndMaybePoll(
640
+ GET_TWITTER_RETWEETS,
641
+ args
642
+ );
643
+ return this.buildPaginatedResult(
644
+ result,
645
+ parseTwitterPost,
646
+ GET_TWITTER_RETWEETS,
647
+ args
648
+ );
612
649
  }
613
650
  async getQuotes(postId, options = {}) {
614
651
  const args = this.buildArgs({ postId, ...options });
615
652
  const result = await this.callAndMaybePoll(GET_TWITTER_QUOTES, args);
616
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_QUOTES, args);
653
+ return this.buildPaginatedResult(
654
+ result,
655
+ parseTwitterPost,
656
+ GET_TWITTER_QUOTES,
657
+ args
658
+ );
617
659
  }
618
660
  async getComments(postId, options = {}) {
619
661
  const args = this.buildArgs({ postId, ...options });
620
- const result = await this.callAndMaybePoll(GET_TWITTER_COMMENTS, args);
621
- return this.buildPaginatedResult(result, parseTwitterPost, GET_TWITTER_COMMENTS, args);
662
+ const result = await this.callAndMaybePoll(
663
+ GET_TWITTER_COMMENTS,
664
+ args
665
+ );
666
+ return this.buildPaginatedResult(
667
+ result,
668
+ parseTwitterPost,
669
+ GET_TWITTER_COMMENTS,
670
+ args
671
+ );
622
672
  }
623
673
  async getPostInteractingUsers(postId, interactionType, options = {}) {
624
674
  const args = this.buildArgs({ postId, interactionType, ...options });
625
- const result = await this.callAndMaybePoll(GET_TWITTER_POST_INTERACTING_USERS, args);
675
+ const result = await this.callAndMaybePoll(
676
+ GET_TWITTER_POST_INTERACTING_USERS,
677
+ args
678
+ );
626
679
  return this.buildPaginatedResult(
627
680
  result,
628
681
  parseUser,
@@ -644,6 +697,16 @@ var TwitterNamespace = class extends BaseNamespace {
644
697
  }
645
698
  return Number(count);
646
699
  }
700
+ async getUsers(identifiers, options = {}) {
701
+ const args = this.buildArgs({
702
+ identifiers,
703
+ identifierType: options.identifierType ?? "username",
704
+ fields: options.fields,
705
+ forceLatest: options.forceLatest
706
+ });
707
+ const result = await this.callAndMaybePoll(GET_TWITTER_USERS, args);
708
+ return (result["results"] ?? []).map(parseUser);
709
+ }
647
710
  async getUser(identifier, options = {}) {
648
711
  const args = this.buildArgs({
649
712
  identifier,
@@ -659,12 +722,18 @@ var TwitterNamespace = class extends BaseNamespace {
659
722
  }
660
723
  async searchUsers(name, options = {}) {
661
724
  const args = this.buildArgs({ name, ...options });
662
- const result = await this.callAndMaybePoll(SEARCH_TWITTER_USERS, args);
725
+ const result = await this.callAndMaybePoll(
726
+ SEARCH_TWITTER_USERS,
727
+ args
728
+ );
663
729
  return (result["results"] ?? []).map(parseUser);
664
730
  }
665
731
  async getUserConnections(username, connectionType, options = {}) {
666
732
  const args = this.buildArgs({ username, connectionType, ...options });
667
- const result = await this.callAndMaybePoll(GET_TWITTER_USER_CONNECTIONS, args);
733
+ const result = await this.callAndMaybePoll(
734
+ GET_TWITTER_USER_CONNECTIONS,
735
+ args
736
+ );
668
737
  return this.buildPaginatedResult(
669
738
  result,
670
739
  parseUser,
@@ -674,7 +743,10 @@ var TwitterNamespace = class extends BaseNamespace {
674
743
  }
675
744
  async getUsersByKeywords(query, options = {}) {
676
745
  const args = this.buildArgs({ query, ...options });
677
- const result = await this.callAndMaybePoll(GET_TWITTER_USERS_BY_KEYWORDS, args);
746
+ const result = await this.callAndMaybePoll(
747
+ GET_TWITTER_USERS_BY_KEYWORDS,
748
+ args
749
+ );
678
750
  return this.buildPaginatedResult(
679
751
  result,
680
752
  parseUser,
@@ -895,12 +967,53 @@ var RedditNamespace = class extends BaseNamespace {
895
967
  }
896
968
  };
897
969
 
970
+ // src/versionCheck.ts
971
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@xpoz/xpoz/latest";
972
+ var CHECK_TIMEOUT_MS = 3e3;
973
+ var PACKAGE_NAME = "@xpoz/xpoz";
974
+ var hasWarned = false;
975
+ async function checkForUpdates() {
976
+ if (hasWarned) return;
977
+ try {
978
+ const controller = new AbortController();
979
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS);
980
+ const response = await fetch(NPM_REGISTRY_URL, {
981
+ signal: controller.signal,
982
+ headers: { Accept: "application/json" }
983
+ });
984
+ clearTimeout(timeout);
985
+ if (!response.ok) return;
986
+ const data = await response.json();
987
+ const latest = data.version;
988
+ if (!latest || latest === VERSION) return;
989
+ if (isNewerVersion(latest, VERSION)) {
990
+ hasWarned = true;
991
+ console.warn(
992
+ `[xpoz] A newer version of ${PACKAGE_NAME} is available: ${latest} (current: ${VERSION}). Run \`npm install ${PACKAGE_NAME}@latest\` to update.`
993
+ );
994
+ }
995
+ } catch {
996
+ }
997
+ }
998
+ function isNewerVersion(latestVersion, currentVersion) {
999
+ const latestVersionParts = latestVersion.split(".").map(Number);
1000
+ const currentVersionParts = currentVersion.split(".").map(Number);
1001
+ for (let i = 0; i < 3; i++) {
1002
+ const latestVersionPart = latestVersionParts[i] ?? 0;
1003
+ const currentVersionPart = currentVersionParts[i] ?? 0;
1004
+ if (latestVersionPart > currentVersionPart) return true;
1005
+ if (latestVersionPart < currentVersionPart) return false;
1006
+ }
1007
+ return false;
1008
+ }
1009
+
898
1010
  // src/client.ts
899
1011
  var XpozClient = class {
900
1012
  twitter;
901
1013
  instagram;
902
1014
  reddit;
903
1015
  transport;
1016
+ versionCheck;
904
1017
  constructor(options = {}) {
905
1018
  const apiKey = options.apiKey ?? process.env[ENV_API_KEY];
906
1019
  if (!apiKey) {
@@ -908,6 +1021,7 @@ var XpozClient = class {
908
1021
  `API key required. Get your token at http://xpoz.ai/get-token?utm_source=ts_sdk&utm_medium=sdk (login \u2192 copy token), then pass it as apiKey or set the ${ENV_API_KEY} environment variable.`
909
1022
  );
910
1023
  }
1024
+ this.versionCheck = options.versionCheck ?? true;
911
1025
  const serverUrl = options.serverUrl ?? process.env[ENV_SERVER_URL] ?? DEFAULT_SERVER_URL;
912
1026
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
913
1027
  this.transport = new McpTransport(serverUrl, apiKey);
@@ -918,6 +1032,9 @@ var XpozClient = class {
918
1032
  }
919
1033
  async connect() {
920
1034
  await this.transport.connect();
1035
+ if (this.versionCheck) {
1036
+ checkForUpdates();
1037
+ }
921
1038
  }
922
1039
  async close() {
923
1040
  await this.transport.close();
@@ -936,5 +1053,6 @@ export {
936
1053
  VERSION,
937
1054
  XpozClient,
938
1055
  XpozConnectionError,
939
- XpozError
1056
+ XpozError,
1057
+ checkForUpdates
940
1058
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpoz/xpoz",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript SDK for the Xpoz social media intelligence platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",