ebay-mcp 1.4.3

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.
Files changed (205) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +586 -0
  3. package/build/api/account-management/account.d.ts +216 -0
  4. package/build/api/account-management/account.js +305 -0
  5. package/build/api/analytics-and-report/analytics.d.ts +33 -0
  6. package/build/api/analytics-and-report/analytics.js +102 -0
  7. package/build/api/client.d.ts +89 -0
  8. package/build/api/client.js +343 -0
  9. package/build/api/communication/feedback.d.ts +45 -0
  10. package/build/api/communication/feedback.js +119 -0
  11. package/build/api/communication/message.d.ts +55 -0
  12. package/build/api/communication/message.js +131 -0
  13. package/build/api/communication/negotiation.d.ts +39 -0
  14. package/build/api/communication/negotiation.js +97 -0
  15. package/build/api/communication/notification.d.ts +128 -0
  16. package/build/api/communication/notification.js +373 -0
  17. package/build/api/index.d.ts +96 -0
  18. package/build/api/index.js +121 -0
  19. package/build/api/listing-management/inventory.d.ts +216 -0
  20. package/build/api/listing-management/inventory.js +633 -0
  21. package/build/api/listing-metadata/metadata.d.ts +154 -0
  22. package/build/api/listing-metadata/metadata.js +485 -0
  23. package/build/api/listing-metadata/taxonomy.d.ts +38 -0
  24. package/build/api/listing-metadata/taxonomy.js +58 -0
  25. package/build/api/marketing-and-promotions/marketing.d.ts +395 -0
  26. package/build/api/marketing-and-promotions/marketing.js +565 -0
  27. package/build/api/marketing-and-promotions/recommendation.d.ts +20 -0
  28. package/build/api/marketing-and-promotions/recommendation.js +32 -0
  29. package/build/api/order-management/dispute.d.ts +65 -0
  30. package/build/api/order-management/dispute.js +69 -0
  31. package/build/api/order-management/fulfillment.d.ts +80 -0
  32. package/build/api/order-management/fulfillment.js +89 -0
  33. package/build/api/other/compliance.d.ts +26 -0
  34. package/build/api/other/compliance.js +47 -0
  35. package/build/api/other/edelivery.d.ts +153 -0
  36. package/build/api/other/edelivery.js +219 -0
  37. package/build/api/other/identity.d.ts +17 -0
  38. package/build/api/other/identity.js +24 -0
  39. package/build/api/other/translation.d.ts +14 -0
  40. package/build/api/other/translation.js +22 -0
  41. package/build/api/other/vero.d.ts +30 -0
  42. package/build/api/other/vero.js +48 -0
  43. package/build/auth/oauth-metadata.d.ts +46 -0
  44. package/build/auth/oauth-metadata.js +59 -0
  45. package/build/auth/oauth-middleware.d.ts +35 -0
  46. package/build/auth/oauth-middleware.js +99 -0
  47. package/build/auth/oauth-types.d.ts +66 -0
  48. package/build/auth/oauth-types.js +4 -0
  49. package/build/auth/oauth.d.ts +93 -0
  50. package/build/auth/oauth.js +383 -0
  51. package/build/auth/scope-utils.d.ts +70 -0
  52. package/build/auth/scope-utils.js +304 -0
  53. package/build/auth/token-verifier.d.ts +57 -0
  54. package/build/auth/token-verifier.js +172 -0
  55. package/build/config/environment.d.ts +61 -0
  56. package/build/config/environment.js +260 -0
  57. package/build/index.d.ts +1 -0
  58. package/build/index.js +98 -0
  59. package/build/schemas/account-management/account.d.ts +5324 -0
  60. package/build/schemas/account-management/account.js +366 -0
  61. package/build/schemas/analytics/analytics.d.ts +167 -0
  62. package/build/schemas/analytics/analytics.js +191 -0
  63. package/build/schemas/communication/messages.d.ts +1872 -0
  64. package/build/schemas/communication/messages.js +348 -0
  65. package/build/schemas/fulfillment/orders.d.ts +4655 -0
  66. package/build/schemas/fulfillment/orders.js +317 -0
  67. package/build/schemas/index.d.ts +2100 -0
  68. package/build/schemas/index.js +68 -0
  69. package/build/schemas/inventory-management/inventory.d.ts +6419 -0
  70. package/build/schemas/inventory-management/inventory.js +450 -0
  71. package/build/schemas/marketing/marketing.d.ts +14181 -0
  72. package/build/schemas/marketing/marketing.js +1088 -0
  73. package/build/schemas/metadata/metadata.d.ts +5259 -0
  74. package/build/schemas/metadata/metadata.js +614 -0
  75. package/build/schemas/other/other-apis.d.ts +257 -0
  76. package/build/schemas/other/other-apis.js +372 -0
  77. package/build/schemas/taxonomy/taxonomy.d.ts +215 -0
  78. package/build/schemas/taxonomy/taxonomy.js +571 -0
  79. package/build/scripts/auto-setup.d.ts +12 -0
  80. package/build/scripts/auto-setup.js +277 -0
  81. package/build/scripts/diagnostics.d.ts +8 -0
  82. package/build/scripts/diagnostics.js +299 -0
  83. package/build/scripts/download-specs.d.ts +1 -0
  84. package/build/scripts/download-specs.js +116 -0
  85. package/build/scripts/interactive-setup.d.ts +21 -0
  86. package/build/scripts/interactive-setup.js +723 -0
  87. package/build/server-http.d.ts +11 -0
  88. package/build/server-http.js +361 -0
  89. package/build/tools/definitions/account-with-schemas.d.ts +39 -0
  90. package/build/tools/definitions/account-with-schemas.js +170 -0
  91. package/build/tools/definitions/account.d.ts +12 -0
  92. package/build/tools/definitions/account.js +428 -0
  93. package/build/tools/definitions/analytics.d.ts +25 -0
  94. package/build/tools/definitions/analytics.js +66 -0
  95. package/build/tools/definitions/communication.d.ts +12 -0
  96. package/build/tools/definitions/communication.js +151 -0
  97. package/build/tools/definitions/fulfillment.d.ts +12 -0
  98. package/build/tools/definitions/fulfillment.js +326 -0
  99. package/build/tools/definitions/index.d.ts +25 -0
  100. package/build/tools/definitions/index.js +37 -0
  101. package/build/tools/definitions/inventory.d.ts +12 -0
  102. package/build/tools/definitions/inventory.js +429 -0
  103. package/build/tools/definitions/marketing.d.ts +12 -0
  104. package/build/tools/definitions/marketing.js +1095 -0
  105. package/build/tools/definitions/metadata.d.ts +12 -0
  106. package/build/tools/definitions/metadata.js +188 -0
  107. package/build/tools/definitions/other.d.ts +13 -0
  108. package/build/tools/definitions/other.js +309 -0
  109. package/build/tools/definitions/taxonomy.d.ts +25 -0
  110. package/build/tools/definitions/taxonomy.js +64 -0
  111. package/build/tools/definitions/token-management.d.ts +35 -0
  112. package/build/tools/definitions/token-management.js +103 -0
  113. package/build/tools/index.d.ts +11 -0
  114. package/build/tools/index.js +1003 -0
  115. package/build/tools/schemas.d.ts +14764 -0
  116. package/build/tools/schemas.js +667 -0
  117. package/build/tools/tool-definitions.d.ts +35 -0
  118. package/build/tools/tool-definitions.js +3534 -0
  119. package/build/types/application-settings/developerAnalyticsV1BetaOas3.d.ts +197 -0
  120. package/build/types/application-settings/developerAnalyticsV1BetaOas3.js +5 -0
  121. package/build/types/application-settings/developerClientRegistrationV1Oas3.d.ts +155 -0
  122. package/build/types/application-settings/developerClientRegistrationV1Oas3.js +5 -0
  123. package/build/types/application-settings/developerKeyManagementV1Oas3.d.ts +246 -0
  124. package/build/types/application-settings/developerKeyManagementV1Oas3.js +5 -0
  125. package/build/types/ebay-enums.d.ts +1204 -0
  126. package/build/types/ebay-enums.js +1330 -0
  127. package/build/types/ebay.d.ts +143 -0
  128. package/build/types/ebay.js +123 -0
  129. package/build/types/index.d.ts +6 -0
  130. package/build/types/index.js +10 -0
  131. package/build/types/sell-apps/account-management/sellAccountV1Oas3.d.ts +2579 -0
  132. package/build/types/sell-apps/account-management/sellAccountV1Oas3.js +5 -0
  133. package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.d.ts +446 -0
  134. package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.js +5 -0
  135. package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.d.ts +705 -0
  136. package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.js +5 -0
  137. package/build/types/sell-apps/communication/commerceMessageV1Oas3.d.ts +590 -0
  138. package/build/types/sell-apps/communication/commerceMessageV1Oas3.js +5 -0
  139. package/build/types/sell-apps/communication/commerceNotificationV1Oas3.d.ts +1276 -0
  140. package/build/types/sell-apps/communication/commerceNotificationV1Oas3.js +5 -0
  141. package/build/types/sell-apps/communication/sellNegotiationV1Oas3.d.ts +277 -0
  142. package/build/types/sell-apps/communication/sellNegotiationV1Oas3.js +5 -0
  143. package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.d.ts +3133 -0
  144. package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.js +5 -0
  145. package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.d.ts +2289 -0
  146. package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.js +5 -0
  147. package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.d.ts +6650 -0
  148. package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.js +5 -0
  149. package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.d.ts +172 -0
  150. package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.js +5 -0
  151. package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.d.ts +1869 -0
  152. package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.js +5 -0
  153. package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.d.ts +178 -0
  154. package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.js +5 -0
  155. package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.d.ts +128 -0
  156. package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.js +5 -0
  157. package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.d.ts +417 -0
  158. package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.js +5 -0
  159. package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.d.ts +273 -0
  160. package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.js +5 -0
  161. package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.d.ts +2537 -0
  162. package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.js +5 -0
  163. package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.d.ts +6650 -0
  164. package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.js +5 -0
  165. package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.d.ts +172 -0
  166. package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.js +5 -0
  167. package/build/utils/account-management/account.d.ts +1094 -0
  168. package/build/utils/account-management/account.js +831 -0
  169. package/build/utils/communication/feedback.d.ts +152 -0
  170. package/build/utils/communication/feedback.js +216 -0
  171. package/build/utils/communication/message.d.ts +174 -0
  172. package/build/utils/communication/message.js +242 -0
  173. package/build/utils/communication/negotiation.d.ts +123 -0
  174. package/build/utils/communication/negotiation.js +150 -0
  175. package/build/utils/communication/notification.d.ts +370 -0
  176. package/build/utils/communication/notification.js +369 -0
  177. package/build/utils/date-converter.d.ts +59 -0
  178. package/build/utils/date-converter.js +160 -0
  179. package/build/utils/llm-client-detector.d.ts +54 -0
  180. package/build/utils/llm-client-detector.js +318 -0
  181. package/build/utils/oauth-helper.d.ts +37 -0
  182. package/build/utils/oauth-helper.js +315 -0
  183. package/build/utils/order-management/dispute.d.ts +346 -0
  184. package/build/utils/order-management/dispute.js +369 -0
  185. package/build/utils/order-management/fulfillment.d.ts +200 -0
  186. package/build/utils/order-management/fulfillment.js +205 -0
  187. package/build/utils/other/compliance.d.ts +49 -0
  188. package/build/utils/other/compliance.js +76 -0
  189. package/build/utils/other/edelivery.d.ts +310 -0
  190. package/build/utils/other/edelivery.js +241 -0
  191. package/build/utils/other/identity.d.ts +13 -0
  192. package/build/utils/other/identity.js +13 -0
  193. package/build/utils/other/translation.d.ts +28 -0
  194. package/build/utils/other/translation.js +41 -0
  195. package/build/utils/other/vero.d.ts +61 -0
  196. package/build/utils/other/vero.js +90 -0
  197. package/build/utils/scope-helper.d.ts +49 -0
  198. package/build/utils/scope-helper.js +207 -0
  199. package/build/utils/security-checker.d.ts +46 -0
  200. package/build/utils/security-checker.js +248 -0
  201. package/build/utils/setup-validator.d.ts +25 -0
  202. package/build/utils/setup-validator.js +305 -0
  203. package/build/utils/token-utils.d.ts +40 -0
  204. package/build/utils/token-utils.js +40 -0
  205. package/package.json +115 -0
@@ -0,0 +1,89 @@
1
+ import { EbayOAuthClient } from '../auth/oauth.js';
2
+ import type { EbayConfig } from '../types/ebay.js';
3
+ import { type AxiosRequestConfig } from 'axios';
4
+ /**
5
+ * Base client for making eBay API requests
6
+ */
7
+ export declare class EbayApiClient {
8
+ private httpClient;
9
+ private authClient;
10
+ private baseUrl;
11
+ private rateLimitTracker;
12
+ private config;
13
+ constructor(config: EbayConfig);
14
+ /**
15
+ * Validate that access token is available before making API request
16
+ */
17
+ private validateAccessToken;
18
+ /**
19
+ * Make a GET request to eBay API
20
+ */
21
+ get<T = unknown>(endpoint: string, params?: Record<string, unknown>, config?: AxiosRequestConfig): Promise<T>;
22
+ /**
23
+ * Make a POST request to eBay API
24
+ */
25
+ post<T = unknown>(endpoint: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
26
+ /**
27
+ * Make a PUT request to eBay API
28
+ */
29
+ put<T = unknown>(endpoint: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
30
+ /**
31
+ * Make a DELETE request to eBay API
32
+ */
33
+ delete<T = unknown>(endpoint: string, config?: AxiosRequestConfig): Promise<T>;
34
+ /**
35
+ * Initialize the client (load user tokens from storage)
36
+ */
37
+ initialize(): Promise<void>;
38
+ /**
39
+ * Check if client is authenticated
40
+ */
41
+ isAuthenticated(): boolean;
42
+ /**
43
+ * Check if user tokens are available
44
+ */
45
+ hasUserTokens(): boolean;
46
+ /**
47
+ * Set user access and refresh tokens
48
+ */
49
+ setUserTokens(accessToken: string, refreshToken: string): Promise<void>;
50
+ /**
51
+ * Get token information for debugging
52
+ */
53
+ getTokenInfo(): {
54
+ hasUserToken: boolean;
55
+ hasAppAccessToken: boolean;
56
+ scopeInfo?: {
57
+ tokenScopes: string[];
58
+ environmentScopes: string[];
59
+ missingScopes: string[];
60
+ };
61
+ };
62
+ /**
63
+ * Get the OAuth client instance for advanced operations
64
+ */
65
+ getOAuthClient(): EbayOAuthClient;
66
+ /**
67
+ * Get rate limit statistics
68
+ */
69
+ getRateLimitStats(): {
70
+ current: number;
71
+ max: number;
72
+ windowMs: number;
73
+ };
74
+ /**
75
+ * Get the config object (for accessing environment, etc.)
76
+ */
77
+ getConfig(): EbayConfig;
78
+ /**
79
+ * Manually refresh user access token using the refresh token
80
+ * This is useful when you encounter "Invalid access token" errors
81
+ * The token will be automatically saved to storage after refresh
82
+ */
83
+ refreshUserToken(): Promise<void>;
84
+ /**
85
+ * Make a GET request with a full URL (for APIs that use different base URLs)
86
+ * Used by Identity API which uses apiz subdomain
87
+ */
88
+ getWithFullUrl<T = unknown>(fullUrl: string, params?: Record<string, unknown>): Promise<T>;
89
+ }
@@ -0,0 +1,343 @@
1
+ import { EbayOAuthClient } from '../auth/oauth.js';
2
+ import { getBaseUrl } from '../config/environment.js';
3
+ import axios from 'axios';
4
+ /**
5
+ * Rate limit tracking
6
+ */
7
+ class RateLimitTracker {
8
+ requestTimestamps = [];
9
+ windowMs = 60000; // 1 minute window
10
+ maxRequests = 5000; // Conservative limit
11
+ canMakeRequest() {
12
+ const now = Date.now();
13
+ // Remove timestamps older than window
14
+ this.requestTimestamps = this.requestTimestamps.filter((timestamp) => now - timestamp < this.windowMs);
15
+ return this.requestTimestamps.length < this.maxRequests;
16
+ }
17
+ recordRequest() {
18
+ this.requestTimestamps.push(Date.now());
19
+ }
20
+ getStats() {
21
+ const now = Date.now();
22
+ this.requestTimestamps = this.requestTimestamps.filter((timestamp) => now - timestamp < this.windowMs);
23
+ return {
24
+ current: this.requestTimestamps.length,
25
+ max: this.maxRequests,
26
+ windowMs: this.windowMs,
27
+ };
28
+ }
29
+ }
30
+ /**
31
+ * Base client for making eBay API requests
32
+ */
33
+ export class EbayApiClient {
34
+ httpClient;
35
+ authClient;
36
+ baseUrl;
37
+ rateLimitTracker;
38
+ config;
39
+ constructor(config) {
40
+ this.config = config;
41
+ this.authClient = new EbayOAuthClient(config);
42
+ this.baseUrl = getBaseUrl(config.environment);
43
+ this.rateLimitTracker = new RateLimitTracker();
44
+ this.httpClient = axios.create({
45
+ baseURL: this.baseUrl,
46
+ timeout: 30000,
47
+ headers: {
48
+ 'Content-Type': 'application/json',
49
+ Accept: 'application/json',
50
+ },
51
+ });
52
+ // Add request interceptor to inject auth token and check rate limits
53
+ this.httpClient.interceptors.request.use(async (config) => {
54
+ // Check rate limit before making request
55
+ if (!this.rateLimitTracker.canMakeRequest()) {
56
+ const stats = this.rateLimitTracker.getStats();
57
+ throw new Error(`Rate limit exceeded: ${stats.current}/${stats.max} requests in ${stats.windowMs}ms window. Please wait before making more requests.`);
58
+ }
59
+ const token = await this.authClient.getAccessToken();
60
+ config.headers.Authorization = `Bearer ${token}`;
61
+ // Record the request
62
+ this.rateLimitTracker.recordRequest();
63
+ // Debug logging: Log outgoing request details
64
+ console.error('\n🔍 [REQUEST DEBUG]');
65
+ console.error(` Method: ${config.method?.toUpperCase()}`);
66
+ console.error(` URL: ${config.baseURL}${config.url}`);
67
+ if (config.params && Object.keys(config.params).length > 0) {
68
+ console.error(` Query Params: ${JSON.stringify(config.params, null, 2)}`);
69
+ }
70
+ if (config.data) {
71
+ console.error(` Request Body: ${JSON.stringify(config.data, null, 2)}`);
72
+ }
73
+ return config;
74
+ }, (error) => console.error(error));
75
+ // Add response interceptor for error handling and retry logic
76
+ this.httpClient.interceptors.response.use((response) => {
77
+ // Extract rate limit info from headers if available
78
+ const remaining = response.headers['x-ebay-c-ratelimit-remaining'];
79
+ const limit = response.headers['x-ebay-c-ratelimit-limit'];
80
+ // Debug logging: Log response details
81
+ console.error('\n✅ [RESPONSE DEBUG]');
82
+ console.error(` Status: ${response.status} ${response.statusText}`);
83
+ if (remaining && limit) {
84
+ console.error(` Rate Limit: ${remaining}/${limit} remaining`);
85
+ }
86
+ if (response.data) {
87
+ const dataStr = JSON.stringify(response.data, null, 2);
88
+ const preview = dataStr.length > 500 ? dataStr.substring(0, 500) + '...' : dataStr;
89
+ console.error(` Response Data: ${preview}`);
90
+ }
91
+ return response;
92
+ }, async (error) => {
93
+ const axiosError = error;
94
+ const config = axiosError.config;
95
+ // Debug logging: Log error response details
96
+ if (axiosError.response) {
97
+ console.error('\n❌ [ERROR RESPONSE DEBUG]');
98
+ console.error(` Status: ${axiosError.response.status} ${axiosError.response.statusText}`);
99
+ console.error(` URL: ${config?.baseURL}${config?.url}`);
100
+ if (axiosError.response.data) {
101
+ console.error(` Error Data: ${JSON.stringify(axiosError.response.data, null, 2)}`);
102
+ }
103
+ }
104
+ else if (axiosError.request) {
105
+ console.error('\n❌ [NO RESPONSE DEBUG]');
106
+ console.error(` Request was made but no response received`);
107
+ console.error(` URL: ${config?.baseURL}${config?.url}`);
108
+ }
109
+ else {
110
+ console.error('\n❌ [REQUEST ERROR DEBUG]');
111
+ console.error(` Error: ${axiosError.message}`);
112
+ }
113
+ // Handle authentication errors (401 Unauthorized)
114
+ if (axiosError.response?.status === 401) {
115
+ const retryCount = config?.__authRetryCount || 0;
116
+ // Only retry once to avoid infinite loops
117
+ if (retryCount === 0 && config) {
118
+ config.__authRetryCount = 1;
119
+ console.error('eBay API authentication error (401). Attempting to refresh user token...');
120
+ try {
121
+ // Force token refresh by getting a new access token
122
+ // The getAccessToken() method will automatically refresh if needed
123
+ const newToken = await this.authClient.getAccessToken();
124
+ // Update the request with the new token
125
+ if (config?.headers) {
126
+ config.headers.Authorization = `Bearer ${newToken}`;
127
+ }
128
+ console.error('Token refreshed successfully. Retrying request...');
129
+ // Retry the request with the new token
130
+ return await this.httpClient.request(config);
131
+ }
132
+ catch (refreshError) {
133
+ console.error('Failed to refresh token:', refreshError);
134
+ // If refresh fails, provide clear guidance
135
+ const ebayError = axiosError.response?.data;
136
+ const originalError = ebayError.errors?.[0]?.longMessage ||
137
+ ebayError.errors?.[0]?.message ||
138
+ 'Invalid access token';
139
+ throw new Error(`${originalError}. ` +
140
+ `Token refresh failed: ${refreshError instanceof Error ? refreshError.message : 'Unknown error'}. ` +
141
+ `Please use the ebay_set_user_tokens_with_expiry tool to provide valid tokens.`);
142
+ }
143
+ }
144
+ // If retry already attempted, provide helpful error message
145
+ const ebayError = axiosError.response?.data;
146
+ const errorMessage = ebayError.errors?.[0]?.longMessage ||
147
+ ebayError.errors?.[0]?.message ||
148
+ 'Invalid access token';
149
+ throw new Error(`${errorMessage}. ` +
150
+ `Automatic token refresh failed. Please use the ebay_set_user_tokens_with_expiry tool to provide valid tokens.`);
151
+ }
152
+ // Handle rate limit errors (429)
153
+ if (axiosError.response?.status === 429) {
154
+ const retryAfter = axiosError.response.headers['retry-after'];
155
+ const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
156
+ throw new Error(`eBay API rate limit exceeded. Retry after ${waitTime / 1000} seconds. ` +
157
+ `Consider reducing request frequency or upgrading to user tokens for higher limits.`);
158
+ }
159
+ // Handle server errors with retry suggestion (500, 502, 503, 504)
160
+ if (axiosError.response?.status && axiosError.response.status >= 500 && config) {
161
+ const retryCount = config.__retryCount || 0;
162
+ if (retryCount < 3) {
163
+ config.__retryCount = retryCount + 1;
164
+ const delay = Math.pow(2, retryCount) * 1000; // Exponential backoff
165
+ console.error(`eBay API server error (${axiosError.response.status}). ` +
166
+ `Retrying in ${delay}ms (attempt ${retryCount + 1}/3)...`);
167
+ await new Promise((resolve) => setTimeout(resolve, Math.min(delay, 5000)));
168
+ return await this.httpClient.request(config);
169
+ }
170
+ }
171
+ // Handle eBay-specific errors
172
+ if (axios.isAxiosError(axiosError) && axiosError.response?.data) {
173
+ const ebayError = axiosError.response.data;
174
+ const errorMessage = ebayError.errors?.[0]?.longMessage ||
175
+ ebayError.errors?.[0]?.message ||
176
+ axiosError.message;
177
+ throw new Error(`eBay API Error: ${errorMessage}`);
178
+ }
179
+ throw error;
180
+ });
181
+ }
182
+ /**
183
+ * Validate that access token is available before making API request
184
+ */
185
+ validateAccessToken() {
186
+ if (!this.authClient.hasUserTokens()) {
187
+ throw new Error('Access token is missing. Please provide your access token and refresh token by calling ebay_set_user_tokens tool in order to perform API requests.');
188
+ }
189
+ }
190
+ /**
191
+ * Make a GET request to eBay API
192
+ */
193
+ async get(endpoint, params, config) {
194
+ this.validateAccessToken();
195
+ const response = await this.httpClient.get(endpoint, { params, ...config });
196
+ return response.data;
197
+ }
198
+ /**
199
+ * Make a POST request to eBay API
200
+ */
201
+ async post(endpoint, data, config) {
202
+ this.validateAccessToken();
203
+ const response = await this.httpClient.post(endpoint, data, config);
204
+ return response.data;
205
+ }
206
+ /**
207
+ * Make a PUT request to eBay API
208
+ */
209
+ async put(endpoint, data, config) {
210
+ this.validateAccessToken();
211
+ const response = await this.httpClient.put(endpoint, data, config);
212
+ return response.data;
213
+ }
214
+ /**
215
+ * Make a DELETE request to eBay API
216
+ */
217
+ async delete(endpoint, config) {
218
+ this.validateAccessToken();
219
+ const response = await this.httpClient.delete(endpoint, config);
220
+ return response.data;
221
+ }
222
+ /**
223
+ * Initialize the client (load user tokens from storage)
224
+ */
225
+ async initialize() {
226
+ await this.authClient.initialize();
227
+ }
228
+ /**
229
+ * Check if client is authenticated
230
+ */
231
+ isAuthenticated() {
232
+ return this.authClient.isAuthenticated();
233
+ }
234
+ /**
235
+ * Check if user tokens are available
236
+ */
237
+ hasUserTokens() {
238
+ return this.authClient.hasUserTokens();
239
+ }
240
+ /**
241
+ * Set user access and refresh tokens
242
+ */
243
+ async setUserTokens(accessToken, refreshToken) {
244
+ await this.authClient.setUserTokens(accessToken, refreshToken);
245
+ }
246
+ /**
247
+ * Get token information for debugging
248
+ */
249
+ getTokenInfo() {
250
+ return this.authClient.getTokenInfo();
251
+ }
252
+ /**
253
+ * Get the OAuth client instance for advanced operations
254
+ */
255
+ getOAuthClient() {
256
+ return this.authClient;
257
+ }
258
+ /**
259
+ * Get rate limit statistics
260
+ */
261
+ getRateLimitStats() {
262
+ return this.rateLimitTracker.getStats();
263
+ }
264
+ /**
265
+ * Get the config object (for accessing environment, etc.)
266
+ */
267
+ getConfig() {
268
+ return this.config;
269
+ }
270
+ /**
271
+ * Manually refresh user access token using the refresh token
272
+ * This is useful when you encounter "Invalid access token" errors
273
+ * The token will be automatically saved to storage after refresh
274
+ */
275
+ async refreshUserToken() {
276
+ await this.authClient.refreshUserToken();
277
+ }
278
+ /**
279
+ * Make a GET request with a full URL (for APIs that use different base URLs)
280
+ * Used by Identity API which uses apiz subdomain
281
+ */
282
+ async getWithFullUrl(fullUrl, params) {
283
+ this.validateAccessToken();
284
+ // Check rate limit
285
+ if (!this.rateLimitTracker.canMakeRequest()) {
286
+ const stats = this.rateLimitTracker.getStats();
287
+ throw new Error(`Rate limit exceeded: ${stats.current}/${stats.max} requests in ${stats.windowMs}ms window. Please wait before making more requests.`);
288
+ }
289
+ // Get auth token
290
+ let token = await this.authClient.getAccessToken();
291
+ // Record the request
292
+ this.rateLimitTracker.recordRequest();
293
+ try {
294
+ // Make request with full URL
295
+ const response = await axios.get(fullUrl, {
296
+ params,
297
+ headers: {
298
+ Authorization: `Bearer ${token}`,
299
+ 'Content-Type': 'application/json',
300
+ Accept: 'application/json',
301
+ },
302
+ timeout: 30000,
303
+ });
304
+ return response.data;
305
+ }
306
+ catch (error) {
307
+ // Handle 401 authentication errors with automatic token refresh
308
+ if (axios.isAxiosError(error) && error.response?.status === 401) {
309
+ console.error('eBay API authentication error (401). Attempting to refresh user token...');
310
+ try {
311
+ // Refresh the token
312
+ await this.authClient.refreshUserToken();
313
+ // Get the new token
314
+ token = await this.authClient.getAccessToken();
315
+ console.error('Token refreshed successfully. Retrying request...');
316
+ // Retry the request with the new token
317
+ const response = await axios.get(fullUrl, {
318
+ params,
319
+ headers: {
320
+ Authorization: `Bearer ${token}`,
321
+ 'Content-Type': 'application/json',
322
+ Accept: 'application/json',
323
+ },
324
+ timeout: 30000,
325
+ });
326
+ return response.data;
327
+ }
328
+ catch (refreshError) {
329
+ console.error('Failed to refresh token:', refreshError);
330
+ const ebayError = error.response?.data;
331
+ const originalError = ebayError.errors?.[0]?.longMessage ||
332
+ ebayError.errors?.[0]?.message ||
333
+ 'Invalid access token';
334
+ throw new Error(`${originalError}. ` +
335
+ `Token refresh failed: ${refreshError instanceof Error ? refreshError.message : 'Unknown error'}. ` +
336
+ `Please use the ebay_set_user_tokens_with_expiry tool to provide valid tokens.`);
337
+ }
338
+ }
339
+ // Re-throw other errors
340
+ throw error;
341
+ }
342
+ }
343
+ }
@@ -0,0 +1,45 @@
1
+ import type { EbayApiClient } from '../client.js';
2
+ /**
3
+ * Feedback API - Manage buyer and seller feedback
4
+ * Based on: docs/sell-apps/communication/commerce_feedback_v1_beta_oas3.json
5
+ */
6
+ export declare class FeedbackApi {
7
+ private client;
8
+ private readonly basePath;
9
+ constructor(client: EbayApiClient);
10
+ /**
11
+ * Get items awaiting feedback
12
+ * Endpoint: GET /awaiting_feedback
13
+ * @throws Error if the request fails
14
+ */
15
+ getAwaitingFeedback(filter?: string, limit?: number, offset?: number): Promise<unknown>;
16
+ /**
17
+ * Get feedback for a transaction
18
+ * Endpoint: GET /feedback
19
+ * @throws Error if required parameters are missing or invalid
20
+ */
21
+ getFeedback(transactionId: string): Promise<unknown>;
22
+ /**
23
+ * Get feedback rating summary
24
+ * Endpoint: GET /feedback_rating_summary
25
+ * @throws Error if the request fails
26
+ */
27
+ getFeedbackRatingSummary(): Promise<unknown>;
28
+ /**
29
+ * Leave feedback for a buyer
30
+ * Endpoint: POST /feedback
31
+ * @throws Error if required parameters are missing or invalid
32
+ */
33
+ leaveFeedbackForBuyer(feedbackData: Record<string, unknown>): Promise<unknown>;
34
+ /**
35
+ * Respond to feedback
36
+ * Endpoint: POST /respond_to_feedback
37
+ * @throws Error if required parameters are missing or invalid
38
+ */
39
+ respondToFeedback(feedbackId: string, responseText: string): Promise<unknown>;
40
+ /**
41
+ * Get feedback summary
42
+ * @deprecated Use getFeedbackRatingSummary() instead
43
+ */
44
+ getFeedbackSummary(): Promise<unknown>;
45
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Feedback API - Manage buyer and seller feedback
3
+ * Based on: docs/sell-apps/communication/commerce_feedback_v1_beta_oas3.json
4
+ */
5
+ export class FeedbackApi {
6
+ client;
7
+ basePath = '/commerce/feedback/v1';
8
+ constructor(client) {
9
+ this.client = client;
10
+ }
11
+ /**
12
+ * Get items awaiting feedback
13
+ * Endpoint: GET /awaiting_feedback
14
+ * @throws Error if the request fails
15
+ */
16
+ async getAwaitingFeedback(filter, limit, offset) {
17
+ const params = {};
18
+ if (filter !== undefined) {
19
+ if (typeof filter !== 'string') {
20
+ throw new Error('filter must be a string when provided');
21
+ }
22
+ params.filter = filter;
23
+ }
24
+ if (limit !== undefined) {
25
+ if (typeof limit !== 'number' || limit < 1) {
26
+ throw new Error('limit must be a positive number when provided');
27
+ }
28
+ params.limit = limit;
29
+ }
30
+ if (offset !== undefined) {
31
+ if (typeof offset !== 'number' || offset < 0) {
32
+ throw new Error('offset must be a non-negative number when provided');
33
+ }
34
+ params.offset = offset;
35
+ }
36
+ try {
37
+ return await this.client.get(`${this.basePath}/awaiting_feedback`, params);
38
+ }
39
+ catch (error) {
40
+ throw new Error(`Failed to get awaiting feedback: ${error instanceof Error ? error.message : 'Unknown error'}`);
41
+ }
42
+ }
43
+ /**
44
+ * Get feedback for a transaction
45
+ * Endpoint: GET /feedback
46
+ * @throws Error if required parameters are missing or invalid
47
+ */
48
+ async getFeedback(transactionId) {
49
+ if (!transactionId || typeof transactionId !== 'string') {
50
+ throw new Error('transactionId is required and must be a string');
51
+ }
52
+ try {
53
+ return await this.client.get(`${this.basePath}/feedback`, {
54
+ transaction_id: transactionId,
55
+ });
56
+ }
57
+ catch (error) {
58
+ throw new Error(`Failed to get feedback: ${error instanceof Error ? error.message : 'Unknown error'}`);
59
+ }
60
+ }
61
+ /**
62
+ * Get feedback rating summary
63
+ * Endpoint: GET /feedback_rating_summary
64
+ * @throws Error if the request fails
65
+ */
66
+ async getFeedbackRatingSummary() {
67
+ try {
68
+ return await this.client.get(`${this.basePath}/feedback_rating_summary`);
69
+ }
70
+ catch (error) {
71
+ throw new Error(`Failed to get feedback rating summary: ${error instanceof Error ? error.message : 'Unknown error'}`);
72
+ }
73
+ }
74
+ /**
75
+ * Leave feedback for a buyer
76
+ * Endpoint: POST /feedback
77
+ * @throws Error if required parameters are missing or invalid
78
+ */
79
+ async leaveFeedbackForBuyer(feedbackData) {
80
+ if (!feedbackData || typeof feedbackData !== 'object') {
81
+ throw new Error('feedbackData is required and must be an object');
82
+ }
83
+ try {
84
+ return await this.client.post(`${this.basePath}/feedback`, feedbackData);
85
+ }
86
+ catch (error) {
87
+ throw new Error(`Failed to leave feedback: ${error instanceof Error ? error.message : 'Unknown error'}`);
88
+ }
89
+ }
90
+ /**
91
+ * Respond to feedback
92
+ * Endpoint: POST /respond_to_feedback
93
+ * @throws Error if required parameters are missing or invalid
94
+ */
95
+ async respondToFeedback(feedbackId, responseText) {
96
+ if (!feedbackId || typeof feedbackId !== 'string') {
97
+ throw new Error('feedbackId is required and must be a string');
98
+ }
99
+ if (!responseText || typeof responseText !== 'string') {
100
+ throw new Error('responseText is required and must be a string');
101
+ }
102
+ try {
103
+ return await this.client.post(`${this.basePath}/respond_to_feedback`, {
104
+ feedback_id: feedbackId,
105
+ response_text: responseText,
106
+ });
107
+ }
108
+ catch (error) {
109
+ throw new Error(`Failed to respond to feedback: ${error instanceof Error ? error.message : 'Unknown error'}`);
110
+ }
111
+ }
112
+ /**
113
+ * Get feedback summary
114
+ * @deprecated Use getFeedbackRatingSummary() instead
115
+ */
116
+ async getFeedbackSummary() {
117
+ return await this.getFeedbackRatingSummary();
118
+ }
119
+ }
@@ -0,0 +1,55 @@
1
+ import type { EbayApiClient } from '../client.js';
2
+ /**
3
+ * Message API - Buyer-seller messaging
4
+ * Based on: docs/sell-apps/communication/commerce_message_v1_oas3.json
5
+ */
6
+ export declare class MessageApi {
7
+ private client;
8
+ private readonly basePath;
9
+ constructor(client: EbayApiClient);
10
+ /**
11
+ * Bulk update conversation
12
+ * Endpoint: POST /bulk_update_conversation
13
+ * @throws Error if required parameters are missing or invalid
14
+ */
15
+ bulkUpdateConversation(updateData: Record<string, unknown>): Promise<unknown>;
16
+ /**
17
+ * Get conversations
18
+ * Endpoint: GET /conversation
19
+ * @throws Error if the request fails
20
+ */
21
+ getConversations(filter?: string, limit?: number, offset?: number): Promise<unknown>;
22
+ /**
23
+ * Get a specific conversation
24
+ * Endpoint: GET /conversation/{conversation_id}
25
+ * @throws Error if required parameters are missing or invalid
26
+ */
27
+ getConversation(conversationId: string): Promise<unknown>;
28
+ /**
29
+ * Send a message
30
+ * Endpoint: POST /send_message
31
+ * @throws Error if required parameters are missing or invalid
32
+ */
33
+ sendMessage(messageData: Record<string, unknown>): Promise<unknown>;
34
+ /**
35
+ * Update a conversation
36
+ * Endpoint: POST /update_conversation
37
+ * @throws Error if required parameters are missing or invalid
38
+ */
39
+ updateConversation(updateData: Record<string, unknown>): Promise<unknown>;
40
+ /**
41
+ * Search for messages
42
+ * @deprecated Use getConversations() instead
43
+ */
44
+ searchMessages(filter?: string, limit?: number, offset?: number): Promise<unknown>;
45
+ /**
46
+ * Get a specific message
47
+ * @deprecated Use getConversation() instead
48
+ */
49
+ getMessage(messageId: string): Promise<unknown>;
50
+ /**
51
+ * Reply to a message
52
+ * @deprecated Use sendMessage() instead
53
+ */
54
+ replyToMessage(messageId: string, messageContent: string): Promise<unknown>;
55
+ }