ebay-mcp 1.17.0 → 1.18.2
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 +92 -53
- package/build/api/account-management/accountV2.js +347 -0
- package/build/api/account-management/finances.js +289 -0
- package/build/api/analytics-and-report/analytics.js +1 -1
- package/build/api/{client.js → client/ebayApiClient.js} +83 -36
- package/build/api/{clientTrading.js → client/tradingApiClient.js} +22 -22
- package/build/api/communication/feedback.js +21 -21
- package/build/api/communication/message.js +23 -23
- package/build/api/communication/negotiation.js +7 -7
- package/build/api/communication/notification.js +52 -52
- package/build/api/developer/developer.js +3 -3
- package/build/api/{index.js → ebaySellerApi.js} +28 -4
- package/build/api/listing-management/feed.js +91 -0
- package/build/api/listing-management/feedReportTasks.js +107 -0
- package/build/api/listing-management/feedRequest.js +91 -0
- package/build/api/listing-management/feedSchedules.js +95 -0
- package/build/api/listing-management/feedTasks.js +91 -0
- package/build/api/listing-management/items.js +22 -22
- package/build/api/listing-management/locations.js +4 -4
- package/build/api/listing-management/media.js +14 -14
- package/build/api/listing-management/mediaAttach.js +14 -14
- package/build/api/listing-management/mediaResources.js +22 -39
- package/build/api/listing-management/offerFormat.js +1 -1
- package/build/api/listing-management/offers.js +23 -23
- package/build/api/listing-management/stores.js +203 -0
- package/build/api/listing-metadata/charity.js +76 -0
- package/build/api/listing-metadata/metadata.js +31 -11
- package/build/api/listing-metadata/metadataShipping.js +117 -0
- package/build/api/listing-metadata/taxonomy.js +52 -7
- package/build/api/marketing-and-promotions/ads.js +34 -34
- package/build/api/marketing-and-promotions/campaigns.js +21 -21
- package/build/api/marketing-and-promotions/promotions.js +24 -24
- package/build/api/marketing-and-promotions/reports.js +7 -7
- package/build/api/marketing-and-promotions/shared.js +0 -3
- package/build/api/order-management/dispute.js +11 -9
- package/build/api/order-management/fulfillment.js +4 -4
- package/build/api/order-management/logistics.js +150 -0
- package/build/api/other/browseMappers.js +15 -13
- package/build/api/other/browseValidators.js +4 -4
- package/build/api/other/edelivery.js +19 -19
- package/build/api/other/finding.js +13 -13
- package/build/api/other/translation.js +2 -2
- package/build/api/other/vero.js +2 -2
- package/build/api/shared/download.js +79 -0
- package/build/api/shared/location.js +33 -0
- package/build/api/shared/request.js +69 -11
- package/build/api/trading/listingFormat.js +37 -30
- package/build/api/trading/trading.js +33 -33
- package/build/auth/credentialSession.js +5 -5
- package/build/auth/oauth.js +3 -3
- package/build/auth/oauthHelper.js +24 -24
- package/build/auth/oauthMetadata.js +4 -4
- package/build/auth/oauthMiddleware.js +16 -16
- package/build/auth/scopeUtils.js +24 -3
- package/build/auth/tokenVerifier.js +23 -23
- package/build/config/environment.js +10 -45
- package/build/config/oauthScopes.js +132 -0
- package/build/config/toolFamilies.js +4 -0
- package/build/index.js +5 -5
- package/build/mcp/httpTransport.js +32 -20
- package/build/mcp/runtime.js +12 -12
- package/build/mcp/toolGating.js +6 -12
- package/build/mcp/uiBridge.js +3 -3
- package/build/schemas/account-management/account.js +2 -52
- package/build/schemas/account-management/accountV2.js +294 -0
- package/build/schemas/account-management/finances.js +143 -0
- package/build/schemas/analytics/analytics.js +2 -48
- package/build/schemas/communication/messages.js +2 -46
- package/build/schemas/developer/developer.js +1 -27
- package/build/schemas/fulfillment/logistics.js +115 -0
- package/build/schemas/fulfillment/orders.js +2 -47
- package/build/schemas/inventory-management/feed.js +217 -0
- package/build/schemas/inventory-management/inventory.js +2 -50
- package/build/schemas/inventory-management/media.js +2 -2
- package/build/schemas/inventory-management/mediaDocuments.js +1 -1
- package/build/schemas/inventory-management/stores.js +42 -0
- package/build/schemas/marketing/ads.js +2 -2
- package/build/schemas/marketing/campaigns.js +2 -2
- package/build/schemas/marketing/common.js +2 -2
- package/build/schemas/marketing/marketing.js +0 -1
- package/build/schemas/marketing/promotions.js +2 -2
- package/build/schemas/marketing/reports.js +2 -2
- package/build/schemas/metadata/metadata.js +2 -90
- package/build/schemas/metadata/shipping.js +16 -0
- package/build/schemas/other/browse.js +2 -2
- package/build/schemas/other/finding.js +2 -2
- package/build/schemas/other/otherApis.js +2 -114
- package/build/schemas/taxonomy/categoryTree.js +8 -0
- package/build/schemas/taxonomy/charity.js +41 -0
- package/build/schemas/taxonomy/taxonomy.js +2 -69
- package/build/scripts/autoSetup.js +3 -3
- package/build/scripts/{buildUi.js → buildMcpApps.js} +13 -13
- package/build/scripts/devSync.js +34 -70
- package/build/scripts/diagnostics.js +15 -16
- package/build/scripts/interactiveSetup.js +25 -25
- package/build/scripts/scopeHelper.js +2 -2
- package/build/scripts/securityChecker.js +20 -20
- package/build/scripts/setup.js +76 -76
- package/build/scripts/setupShared.js +5 -30
- package/build/scripts/setupValidator.js +9 -9
- package/build/scripts/setupWizard.js +23 -23
- package/build/scripts/skills.js +14 -17
- package/build/scripts/specRefs.js +55 -0
- package/build/scripts/specSources.js +144 -0
- package/build/serverHttp.js +4 -7
- package/build/skills/content.js +13 -13
- package/build/skills/install.js +9 -9
- package/build/skills/registrySnapshot.js +7 -3
- package/build/skills/render.js +2 -2
- package/build/tools/categories/accountV2.js +106 -0
- package/build/tools/categories/charity.js +21 -0
- package/build/tools/categories/communication.js +1 -1
- package/build/tools/categories/connector.js +19 -16
- package/build/tools/categories/feed.js +183 -0
- package/build/tools/categories/finances.js +86 -0
- package/build/tools/categories/fulfillment.js +4 -4
- package/build/tools/categories/index.js +12 -2
- package/build/tools/categories/inventory.js +1 -1
- package/build/tools/categories/logistics.js +52 -0
- package/build/tools/categories/metadata.js +38 -1
- package/build/tools/categories/stores.js +64 -0
- package/build/tools/categories/taxonomy.js +18 -1
- package/build/tools/categories/tokenManagement.js +8 -8
- package/build/tools/contracts.js +2 -2
- package/build/tools/defineTool.js +27 -12
- package/build/tools/fileResult.js +30 -0
- package/build/tools/registry.js +2 -2
- package/build/tools/schemas.js +2 -2
- package/build/tools/ui/mapHelpers.js +12 -12
- package/build/tools/ui/maps.js +101 -97
- package/build/tools/ui/viewModels.js +2 -2
- package/build/utils/apiStatusFeed.js +12 -12
- package/build/utils/communication/feedback.js +3 -3
- package/build/utils/communication/message.js +3 -3
- package/build/utils/communication/negotiation.js +3 -3
- package/build/utils/communication/notification.js +3 -3
- package/build/utils/entryModule.js +33 -0
- package/build/utils/envFile.js +47 -0
- package/build/utils/envParser.js +5 -5
- package/build/utils/errors.js +4 -4
- package/build/utils/http.js +60 -41
- package/build/utils/localFeedFiles.js +61 -0
- package/build/utils/localMedia.js +18 -6
- package/build/utils/logRedaction.js +21 -0
- package/build/utils/logger.js +52 -33
- package/build/utils/other/compliance.js +3 -3
- package/build/utils/other/identity.js +3 -3
- package/build/utils/other/translation.js +3 -3
- package/build/utils/other/vero.js +3 -3
- package/build/utils/schemaHelpers.js +2 -2
- package/build/utils/tokenUtils.js +2 -2
- package/build/utils/trading/trading.js +1 -1
- package/build/utils/version.js +1 -1
- package/build/utils/zodIssues.js +14 -0
- package/package.json +9 -12
- package/README.de.md +0 -422
- package/README.es.md +0 -422
- package/README.fr.md +0 -422
- package/README.ja.md +0 -422
- package/README.ko.md +0 -422
- package/README.pt-BR.md +0 -422
- package/README.ru.md +0 -422
- package/README.zh-CN.md +0 -422
- package/build/schemas/index.js +0 -76
- package/build/schemas/marketing/jsonSchemas.js +0 -118
- package/build/scripts/downloadSpecs.js +0 -117
- package/build/scripts/updateApiStatusDoc.js +0 -71
- package/build/utils/effectSchema.js +0 -203
- package/build/utils/effectSchemaAdapter.js +0 -121
- package/build/utils/effectSchemaChainMethods.js +0 -146
- package/build/utils/effectSchemaRefinements.js +0 -104
- package/build/utils/effectSchemaStringMethods.js +0 -63
- package/build/utils/effectSchemaTypes.js +0 -47
- package/docs/auth/production_scopes.json +0 -111
- package/docs/auth/sandbox_scopes.json +0 -142
- /package/build/api/{clientRequestError.js → client/ebayClientRequestError.js} +0 -0
- /package/build/api/{rateLimitTracker.js → client/rateLimitTracker.js} +0 -0
- /package/build/api/{clientTradingError.js → client/tradingApiFailure.js} +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { EbayOAuthClient } from '
|
|
2
|
-
import { clientRequestError } from '
|
|
3
|
-
import { RateLimitTracker } from '
|
|
4
|
-
import { getBaseUrl } from '
|
|
5
|
-
import { getErrorMessage } from '
|
|
6
|
-
import { httpRequestEffect, isHttpError, } from '
|
|
7
|
-
import { isRecord } from '
|
|
8
|
-
import { apiLogger, logRequest, logResponse, logErrorResponse } from '
|
|
1
|
+
import { EbayOAuthClient } from '../../auth/oauth.js';
|
|
2
|
+
import { clientRequestError, } from '../../api/client/ebayClientRequestError.js';
|
|
3
|
+
import { RateLimitTracker } from '../../api/client/rateLimitTracker.js';
|
|
4
|
+
import { getBaseUrl } from '../../config/environment.js';
|
|
5
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
6
|
+
import { httpRequestEffect, isHttpError, } from '../../utils/http.js';
|
|
7
|
+
import { isRecord } from '../../utils/typeGuards.js';
|
|
8
|
+
import { apiLogger, logRequest, logResponse, logErrorResponse } from '../../utils/logger.js';
|
|
9
9
|
import { Cause, Effect, Exit } from 'effect';
|
|
10
10
|
/** Bodies that must never be echoed into debug logs. */
|
|
11
|
-
const isBinaryBody = (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const isBinaryBody = (requestBody) => requestBody instanceof FormData ||
|
|
12
|
+
requestBody instanceof Blob ||
|
|
13
|
+
requestBody instanceof Uint8Array ||
|
|
14
|
+
requestBody instanceof ArrayBuffer;
|
|
15
15
|
const CONTENT_TYPE_HEADER = 'content-type';
|
|
16
16
|
const hasHeader = (headers, name) => headers !== undefined && Object.keys(headers).some((key) => key.toLowerCase() === name);
|
|
17
17
|
/** Removes every spelling of a header so fetch can derive it from the body. */
|
|
@@ -31,10 +31,6 @@ const deleteHeader = (headers, name) => {
|
|
|
31
31
|
const tokenFailureRemediation = (tokenType) => tokenType === 'application'
|
|
32
32
|
? 'This endpoint requires an application access token minted from client credentials, which a user token cannot supply. Check EBAY_CLIENT_ID and EBAY_CLIENT_SECRET.'
|
|
33
33
|
: 'Please use the ebay_set_user_tokens_with_expiry tool to provide valid tokens.';
|
|
34
|
-
/** Sleep for a retry backoff delay without exposing timers to callers. */
|
|
35
|
-
const sleep = (delayMs) => Effect.promise(() => new Promise((resolve) => {
|
|
36
|
-
setTimeout(resolve, delayMs);
|
|
37
|
-
}));
|
|
38
34
|
/**
|
|
39
35
|
* Base client for making eBay API requests.
|
|
40
36
|
*
|
|
@@ -103,9 +99,9 @@ export class EbayApiClient {
|
|
|
103
99
|
* Pull the most descriptive eBay error string from a response body when present.
|
|
104
100
|
* eBay REST errors arrive as `{ errors: [{ message, longMessage }] }`.
|
|
105
101
|
*/
|
|
106
|
-
ebayErrorDetail(
|
|
107
|
-
if (isRecord(
|
|
108
|
-
const [firstError] =
|
|
102
|
+
ebayErrorDetail(errorBody) {
|
|
103
|
+
if (isRecord(errorBody) && Array.isArray(errorBody.errors)) {
|
|
104
|
+
const [firstError] = errorBody.errors;
|
|
109
105
|
if (isRecord(firstError)) {
|
|
110
106
|
const detail = firstError.longMessage ?? firstError.message;
|
|
111
107
|
if (typeof detail === 'string') {
|
|
@@ -118,11 +114,11 @@ export class EbayApiClient {
|
|
|
118
114
|
* Serialize the full error response body so structured fields (errorId, parameters)
|
|
119
115
|
* survive into the thrown message for diagnostics.
|
|
120
116
|
*/
|
|
121
|
-
ebayErrorBody(
|
|
122
|
-
if (
|
|
117
|
+
ebayErrorBody(errorBody) {
|
|
118
|
+
if (errorBody == null)
|
|
123
119
|
return '';
|
|
124
120
|
try {
|
|
125
|
-
return ` | response: ${JSON.stringify(
|
|
121
|
+
return ` | response: ${JSON.stringify(errorBody)}`;
|
|
126
122
|
}
|
|
127
123
|
catch {
|
|
128
124
|
return '';
|
|
@@ -142,8 +138,8 @@ export class EbayApiClient {
|
|
|
142
138
|
// rejects with a FiberFailure whose generic message hides eBay response data.
|
|
143
139
|
const exit = await Effect.runPromiseExit(this.requestEffect(method, endpoint, options));
|
|
144
140
|
if (Exit.isSuccess(exit)) {
|
|
145
|
-
const { data, status, headers } = exit.value;
|
|
146
|
-
return { data, status, headers };
|
|
141
|
+
const { data: responseBody, status, headers } = exit.value;
|
|
142
|
+
return { data: responseBody, status, headers };
|
|
147
143
|
}
|
|
148
144
|
throw Cause.squash(exit.cause);
|
|
149
145
|
}
|
|
@@ -221,9 +217,10 @@ export class EbayApiClient {
|
|
|
221
217
|
body: options.data,
|
|
222
218
|
timeoutMs: options.timeoutMs ?? this.timeoutMs,
|
|
223
219
|
responseType: options.responseType,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
220
|
+
maxBytes: options.maxBytes,
|
|
221
|
+
}).pipe(Effect.map((httpResponse) => {
|
|
222
|
+
logResponse(httpResponse.status, httpResponse.statusText, httpResponse.data, httpResponse.headers['x-ebay-c-ratelimit-remaining'], httpResponse.headers['x-ebay-c-ratelimit-limit']);
|
|
223
|
+
return httpResponse;
|
|
227
224
|
}), Effect.catchAll((error) => this.handleRequestFailure(error, { method, url, options, state })));
|
|
228
225
|
});
|
|
229
226
|
}
|
|
@@ -308,7 +305,7 @@ export class EbayApiClient {
|
|
|
308
305
|
attempt: `${nextServerRetries}/3`,
|
|
309
306
|
delayMs,
|
|
310
307
|
});
|
|
311
|
-
return sleep(delayMs).pipe(Effect.flatMap(() => this.sendWithRetry(method, url, options, {
|
|
308
|
+
return Effect.sleep(delayMs).pipe(Effect.flatMap(() => this.sendWithRetry(method, url, options, {
|
|
312
309
|
...state,
|
|
313
310
|
serverRetries: nextServerRetries,
|
|
314
311
|
})));
|
|
@@ -341,41 +338,81 @@ export class EbayApiClient {
|
|
|
341
338
|
responseType: config?.responseType,
|
|
342
339
|
absolute: config?.absolute,
|
|
343
340
|
timeoutMs: config?.timeoutMs,
|
|
341
|
+
maxBytes: config?.maxBytes,
|
|
342
|
+
tokenType: config?.tokenType,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Make a GET request and keep the status and headers of the successful
|
|
347
|
+
* response — for file downloads whose name and type arrive in headers.
|
|
348
|
+
*/
|
|
349
|
+
async getForResponse(endpoint, params, config) {
|
|
350
|
+
return await this.requestResponse('GET', endpoint, {
|
|
351
|
+
params: { ...params, ...config?.params },
|
|
352
|
+
headers: config?.headers,
|
|
353
|
+
responseType: config?.responseType,
|
|
354
|
+
absolute: config?.absolute,
|
|
355
|
+
timeoutMs: config?.timeoutMs,
|
|
356
|
+
maxBytes: config?.maxBytes,
|
|
344
357
|
tokenType: config?.tokenType,
|
|
345
358
|
});
|
|
346
359
|
}
|
|
347
360
|
/**
|
|
348
361
|
* Make a POST request to eBay API
|
|
349
362
|
*/
|
|
350
|
-
async post(endpoint,
|
|
351
|
-
return (await this.postForResponse(endpoint,
|
|
363
|
+
async post(endpoint, requestBody, config) {
|
|
364
|
+
return (await this.postForResponse(endpoint, requestBody, config)).data;
|
|
352
365
|
}
|
|
353
366
|
/**
|
|
354
367
|
* Make a POST request and keep the status and headers of the successful
|
|
355
368
|
* response — for endpoints that return their result in a `Location` header.
|
|
356
369
|
*/
|
|
357
|
-
async postForResponse(endpoint,
|
|
370
|
+
async postForResponse(endpoint, requestBody, config) {
|
|
358
371
|
return await this.requestResponse('POST', endpoint, {
|
|
359
|
-
data,
|
|
372
|
+
data: requestBody,
|
|
360
373
|
params: config?.params,
|
|
361
374
|
headers: config?.headers,
|
|
362
375
|
responseType: config?.responseType,
|
|
363
376
|
absolute: config?.absolute,
|
|
364
377
|
timeoutMs: config?.timeoutMs,
|
|
378
|
+
maxBytes: config?.maxBytes,
|
|
365
379
|
tokenType: config?.tokenType,
|
|
366
380
|
});
|
|
367
381
|
}
|
|
368
382
|
/**
|
|
369
383
|
* Make a PUT request to eBay API
|
|
370
384
|
*/
|
|
371
|
-
async put(endpoint,
|
|
372
|
-
return await this.
|
|
373
|
-
|
|
385
|
+
async put(endpoint, requestBody, config) {
|
|
386
|
+
return (await this.putForResponse(endpoint, requestBody, config)).data;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Make a PUT request and keep the status and headers of the successful
|
|
390
|
+
* response — for asynchronous updates that return a task `Location` header.
|
|
391
|
+
*/
|
|
392
|
+
async putForResponse(endpoint, requestBody, config) {
|
|
393
|
+
return await this.requestResponse('PUT', endpoint, {
|
|
394
|
+
data: requestBody,
|
|
374
395
|
params: config?.params,
|
|
375
396
|
headers: config?.headers,
|
|
376
397
|
responseType: config?.responseType,
|
|
377
398
|
absolute: config?.absolute,
|
|
378
399
|
timeoutMs: config?.timeoutMs,
|
|
400
|
+
maxBytes: config?.maxBytes,
|
|
401
|
+
tokenType: config?.tokenType,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Make a PATCH request to eBay API
|
|
406
|
+
*/
|
|
407
|
+
async patch(endpoint, requestBody, config) {
|
|
408
|
+
return await this.request('PATCH', endpoint, {
|
|
409
|
+
data: requestBody,
|
|
410
|
+
params: config?.params,
|
|
411
|
+
headers: config?.headers,
|
|
412
|
+
responseType: config?.responseType,
|
|
413
|
+
absolute: config?.absolute,
|
|
414
|
+
timeoutMs: config?.timeoutMs,
|
|
415
|
+
maxBytes: config?.maxBytes,
|
|
379
416
|
tokenType: config?.tokenType,
|
|
380
417
|
});
|
|
381
418
|
}
|
|
@@ -383,12 +420,22 @@ export class EbayApiClient {
|
|
|
383
420
|
* Make a DELETE request to eBay API
|
|
384
421
|
*/
|
|
385
422
|
async delete(endpoint, config) {
|
|
386
|
-
return await this.
|
|
423
|
+
return (await this.deleteForResponse(endpoint, config)).data;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Make a DELETE request and keep the status and headers of the successful
|
|
427
|
+
* response — for asynchronous deletes that return a task `Location` header.
|
|
428
|
+
* `requestBody` is the optional body a few eBay DELETE calls document.
|
|
429
|
+
*/
|
|
430
|
+
async deleteForResponse(endpoint, config, requestBody) {
|
|
431
|
+
return await this.requestResponse('DELETE', endpoint, {
|
|
432
|
+
data: requestBody,
|
|
387
433
|
params: config?.params,
|
|
388
434
|
headers: config?.headers,
|
|
389
435
|
responseType: config?.responseType,
|
|
390
436
|
absolute: config?.absolute,
|
|
391
437
|
timeoutMs: config?.timeoutMs,
|
|
438
|
+
maxBytes: config?.maxBytes,
|
|
392
439
|
tokenType: config?.tokenType,
|
|
393
440
|
});
|
|
394
441
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import XmlBuilder from 'fast-xml-builder';
|
|
2
2
|
import { XMLParser } from 'fast-xml-parser';
|
|
3
|
-
import { TradingApiFailure } from '
|
|
4
|
-
import { EbayApiError } from '
|
|
5
|
-
import { getBaseUrl, getTradingSiteId } from '
|
|
6
|
-
import { getErrorMessage } from '
|
|
7
|
-
import { httpRequestEffect } from '
|
|
8
|
-
import { apiLogger } from '
|
|
9
|
-
import { isRecord } from '
|
|
3
|
+
import { TradingApiFailure } from '../../api/client/tradingApiFailure.js';
|
|
4
|
+
import { EbayApiError } from '../../api/shared/request.js';
|
|
5
|
+
import { getBaseUrl, getTradingSiteId } from '../../config/environment.js';
|
|
6
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
7
|
+
import { httpRequestEffect } from '../../utils/http.js';
|
|
8
|
+
import { apiLogger } from '../../utils/logger.js';
|
|
9
|
+
import { isRecord } from '../../utils/typeGuards.js';
|
|
10
10
|
import { Effect } from 'effect';
|
|
11
11
|
const COMPAT_LEVEL = '1451';
|
|
12
12
|
const TRADING_ENDPOINT_PATH = '/ws/api.dll';
|
|
@@ -73,9 +73,9 @@ const parseTradingXml = ({ parser, responseText, callName, path, }) => Effect.tr
|
|
|
73
73
|
return Effect.fail(createTradingApiError({ callName, path }, 'response must be an object'));
|
|
74
74
|
}));
|
|
75
75
|
const readTradingPayload = (parsed, responseTag, { callName, path }) => {
|
|
76
|
-
const
|
|
77
|
-
if (isRecord(
|
|
78
|
-
return Effect.succeed(
|
|
76
|
+
const responsePayload = parsed[responseTag] === undefined ? parsed : parsed[responseTag];
|
|
77
|
+
if (isRecord(responsePayload)) {
|
|
78
|
+
return Effect.succeed(responsePayload);
|
|
79
79
|
}
|
|
80
80
|
return Effect.fail(createTradingApiError({ callName, path }, 'response payload is not an object'));
|
|
81
81
|
};
|
|
@@ -94,25 +94,25 @@ const extractTradingErrorMessage = (errors) => {
|
|
|
94
94
|
}
|
|
95
95
|
return 'Trading API returned a failure without an error message';
|
|
96
96
|
};
|
|
97
|
-
const validateTradingAck = (
|
|
98
|
-
if (
|
|
97
|
+
const validateTradingAck = (tradingPayload, { callName, path }) => {
|
|
98
|
+
if (tradingPayload.Ack === 'Warning') {
|
|
99
99
|
apiLogger.warn(`Trading API ${callName} returned warnings`, {
|
|
100
|
-
errors:
|
|
100
|
+
errors: tradingPayload.Errors,
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
-
if (
|
|
103
|
+
if (tradingPayload.Ack === 'Failure' || tradingPayload.Ack === 'PartialFailure') {
|
|
104
104
|
return Effect.fail(new EbayApiError({
|
|
105
105
|
method: 'POST',
|
|
106
106
|
path,
|
|
107
107
|
cause: new TradingApiFailure({
|
|
108
108
|
callName,
|
|
109
109
|
path,
|
|
110
|
-
message: extractTradingErrorMessage(
|
|
111
|
-
cause:
|
|
110
|
+
message: extractTradingErrorMessage(tradingPayload.Errors),
|
|
111
|
+
cause: tradingPayload.Errors,
|
|
112
112
|
}),
|
|
113
113
|
}));
|
|
114
114
|
}
|
|
115
|
-
return Effect.succeed(
|
|
115
|
+
return Effect.succeed(tradingPayload);
|
|
116
116
|
};
|
|
117
117
|
/**
|
|
118
118
|
* XML-based client for eBay Trading API calls that are not covered by REST APIs.
|
|
@@ -173,7 +173,7 @@ export class TradingApiClient {
|
|
|
173
173
|
*
|
|
174
174
|
* @example
|
|
175
175
|
* ```ts
|
|
176
|
-
* const
|
|
176
|
+
* const tradingReply = await Effect.runPromise(
|
|
177
177
|
* tradingClient.execute('GetItem', { ItemID: '12345' }),
|
|
178
178
|
* );
|
|
179
179
|
* ```
|
|
@@ -193,7 +193,7 @@ export class TradingApiClient {
|
|
|
193
193
|
callName,
|
|
194
194
|
path,
|
|
195
195
|
});
|
|
196
|
-
const
|
|
196
|
+
const xmlResponse = yield* postTradingXml({
|
|
197
197
|
path,
|
|
198
198
|
headers: authorizedHeaders,
|
|
199
199
|
xmlBody,
|
|
@@ -201,12 +201,12 @@ export class TradingApiClient {
|
|
|
201
201
|
});
|
|
202
202
|
const parsed = yield* parseTradingXml({
|
|
203
203
|
parser: tradingClient.parser,
|
|
204
|
-
responseText:
|
|
204
|
+
responseText: xmlResponse.data,
|
|
205
205
|
callName,
|
|
206
206
|
path,
|
|
207
207
|
});
|
|
208
|
-
const
|
|
209
|
-
return yield* validateTradingAck(
|
|
208
|
+
const tradingPayload = yield* readTradingPayload(parsed, responseTag, { callName, path });
|
|
209
|
+
return yield* validateTradingAck(tradingPayload, { callName, path });
|
|
210
210
|
});
|
|
211
211
|
};
|
|
212
212
|
}
|
|
@@ -2,7 +2,7 @@ import { buildEndpointParams, optionalNonNegativeNumberEffect, optionalPositiveN
|
|
|
2
2
|
import { Effect } from 'effect';
|
|
3
3
|
/**
|
|
4
4
|
* Feedback API - Manage buyer and seller feedback
|
|
5
|
-
* Based on:
|
|
5
|
+
* Based on: commerce_feedback_v1_beta_oas3.json
|
|
6
6
|
*/
|
|
7
7
|
export class FeedbackApi {
|
|
8
8
|
client;
|
|
@@ -61,17 +61,17 @@ export class FeedbackApi {
|
|
|
61
61
|
const client = this.client;
|
|
62
62
|
const path = `${this.basePath}/feedback`;
|
|
63
63
|
return Effect.gen(function* () {
|
|
64
|
-
const
|
|
65
|
-
const userId = yield* requireStringEffect(
|
|
66
|
-
const feedbackType = yield* requireStringEffect(
|
|
67
|
-
const feedbackId = yield* optionalStringEffect(
|
|
68
|
-
const filter = yield* optionalStringEffect(
|
|
69
|
-
const limit = yield* optionalPositiveNumberEffect(
|
|
70
|
-
const listingId = yield* optionalStringEffect(
|
|
71
|
-
const offset = yield* optionalNonNegativeNumberEffect(
|
|
72
|
-
const orderLineItemId = yield* optionalStringEffect(
|
|
73
|
-
const sort = yield* optionalStringEffect(
|
|
74
|
-
const transactionId = yield* optionalStringEffect(
|
|
64
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
65
|
+
const userId = yield* requireStringEffect(validatedInput.userId, 'userId');
|
|
66
|
+
const feedbackType = yield* requireStringEffect(validatedInput.feedbackType, 'feedbackType');
|
|
67
|
+
const feedbackId = yield* optionalStringEffect(validatedInput.feedbackId, 'feedbackId');
|
|
68
|
+
const filter = yield* optionalStringEffect(validatedInput.filter, 'filter');
|
|
69
|
+
const limit = yield* optionalPositiveNumberEffect(validatedInput.limit, 'limit');
|
|
70
|
+
const listingId = yield* optionalStringEffect(validatedInput.listingId, 'listingId');
|
|
71
|
+
const offset = yield* optionalNonNegativeNumberEffect(validatedInput.offset, 'offset');
|
|
72
|
+
const orderLineItemId = yield* optionalStringEffect(validatedInput.orderLineItemId, 'orderLineItemId');
|
|
73
|
+
const sort = yield* optionalStringEffect(validatedInput.sort, 'sort');
|
|
74
|
+
const transactionId = yield* optionalStringEffect(validatedInput.transactionId, 'transactionId');
|
|
75
75
|
const params = buildEndpointParams({
|
|
76
76
|
userId: { wireName: 'user_id', value: userId },
|
|
77
77
|
feedbackType: { wireName: 'feedback_type', value: feedbackType },
|
|
@@ -109,9 +109,9 @@ export class FeedbackApi {
|
|
|
109
109
|
const client = this.client;
|
|
110
110
|
const path = `${this.basePath}/feedback_rating_summary`;
|
|
111
111
|
return Effect.gen(function* () {
|
|
112
|
-
const
|
|
113
|
-
const userId = yield* requireStringEffect(
|
|
114
|
-
const filter = yield* requireStringEffect(
|
|
112
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
113
|
+
const userId = yield* requireStringEffect(validatedInput.userId, 'userId');
|
|
114
|
+
const filter = yield* requireStringEffect(validatedInput.filter, 'filter');
|
|
115
115
|
const params = buildEndpointParams({
|
|
116
116
|
userId: { wireName: 'user_id', value: userId },
|
|
117
117
|
filter: { wireName: 'filter', value: filter },
|
|
@@ -138,14 +138,14 @@ export class FeedbackApi {
|
|
|
138
138
|
const client = this.client;
|
|
139
139
|
const path = `${this.basePath}/feedback`;
|
|
140
140
|
return Effect.gen(function* () {
|
|
141
|
-
const
|
|
142
|
-
return yield* requestPostEffect(client, path,
|
|
141
|
+
const feedbackRequest = yield* requireObjectEffect(feedbackData, 'feedbackData');
|
|
142
|
+
return yield* requestPostEffect(client, path, feedbackRequest);
|
|
143
143
|
});
|
|
144
144
|
};
|
|
145
145
|
/**
|
|
146
146
|
* Responds to feedback received from another eBay user.
|
|
147
147
|
*
|
|
148
|
-
* @param
|
|
148
|
+
* @param feedbackReply - Generated RespondToFeedbackRequest body.
|
|
149
149
|
* @returns An Effect that succeeds with eBay's generated empty response.
|
|
150
150
|
*
|
|
151
151
|
* @example
|
|
@@ -157,12 +157,12 @@ export class FeedbackApi {
|
|
|
157
157
|
*
|
|
158
158
|
* @see https://developer.ebay.com/api-docs/commerce/feedback/resources/respond_to_feedback/methods/respondToFeedback
|
|
159
159
|
*/
|
|
160
|
-
respondToFeedback = (
|
|
160
|
+
respondToFeedback = (feedbackReply) => {
|
|
161
161
|
const client = this.client;
|
|
162
162
|
const path = `${this.basePath}/respond_to_feedback`;
|
|
163
163
|
return Effect.gen(function* () {
|
|
164
|
-
const
|
|
165
|
-
return yield* requestPostEffect(client, path,
|
|
164
|
+
const replyRequest = yield* requireObjectEffect(feedbackReply, 'feedbackReply');
|
|
165
|
+
return yield* requestPostEffect(client, path, replyRequest);
|
|
166
166
|
});
|
|
167
167
|
};
|
|
168
168
|
}
|
|
@@ -2,7 +2,7 @@ import { buildEndpointParams, optionalNonNegativeNumberEffect, optionalPositiveN
|
|
|
2
2
|
import { Effect } from 'effect';
|
|
3
3
|
/**
|
|
4
4
|
* Message API - Buyer-seller messaging
|
|
5
|
-
* Based on:
|
|
5
|
+
* Based on: commerce_message_v1_oas3.json
|
|
6
6
|
*/
|
|
7
7
|
export class MessageApi {
|
|
8
8
|
client;
|
|
@@ -18,7 +18,7 @@ export class MessageApi {
|
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```ts
|
|
21
|
-
* const
|
|
21
|
+
* const updatedConversations = await Effect.runPromise(
|
|
22
22
|
* messageApi.bulkUpdateConversation({ conversations: [{ conversationId: 'c1' }] }),
|
|
23
23
|
* );
|
|
24
24
|
* ```
|
|
@@ -29,8 +29,8 @@ export class MessageApi {
|
|
|
29
29
|
const client = this.client;
|
|
30
30
|
const path = `${this.basePath}/bulk_update_conversation`;
|
|
31
31
|
return Effect.gen(function* () {
|
|
32
|
-
const
|
|
33
|
-
return yield* requestPostEffect(client, path,
|
|
32
|
+
const bulkUpdateRequest = yield* requireObjectEffect(updateData, 'updateData');
|
|
33
|
+
return yield* requestPostEffect(client, path, bulkUpdateRequest);
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
36
|
/**
|
|
@@ -52,16 +52,16 @@ export class MessageApi {
|
|
|
52
52
|
const client = this.client;
|
|
53
53
|
const path = `${this.basePath}/conversation`;
|
|
54
54
|
return Effect.gen(function* () {
|
|
55
|
-
const
|
|
56
|
-
const conversationType = yield* requireStringEffect(
|
|
57
|
-
const conversationStatus = yield* optionalStringEffect(
|
|
58
|
-
const endTime = yield* optionalStringEffect(
|
|
59
|
-
const limit = yield* optionalPositiveNumberEffect(
|
|
60
|
-
const offset = yield* optionalNonNegativeNumberEffect(
|
|
61
|
-
const otherPartyUsername = yield* optionalStringEffect(
|
|
62
|
-
const referenceId = yield* optionalStringEffect(
|
|
63
|
-
const referenceType = yield* optionalStringEffect(
|
|
64
|
-
const startTime = yield* optionalStringEffect(
|
|
55
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
56
|
+
const conversationType = yield* requireStringEffect(validatedInput.conversationType, 'conversationType');
|
|
57
|
+
const conversationStatus = yield* optionalStringEffect(validatedInput.conversationStatus, 'conversationStatus');
|
|
58
|
+
const endTime = yield* optionalStringEffect(validatedInput.endTime, 'endTime');
|
|
59
|
+
const limit = yield* optionalPositiveNumberEffect(validatedInput.limit, 'limit');
|
|
60
|
+
const offset = yield* optionalNonNegativeNumberEffect(validatedInput.offset, 'offset');
|
|
61
|
+
const otherPartyUsername = yield* optionalStringEffect(validatedInput.otherPartyUsername, 'otherPartyUsername');
|
|
62
|
+
const referenceId = yield* optionalStringEffect(validatedInput.referenceId, 'referenceId');
|
|
63
|
+
const referenceType = yield* optionalStringEffect(validatedInput.referenceType, 'referenceType');
|
|
64
|
+
const startTime = yield* optionalStringEffect(validatedInput.startTime, 'startTime');
|
|
65
65
|
const params = buildEndpointParams({
|
|
66
66
|
conversationType: { wireName: 'conversation_type', value: conversationType },
|
|
67
67
|
conversationStatus: { wireName: 'conversation_status', value: conversationStatus },
|
|
@@ -95,11 +95,11 @@ export class MessageApi {
|
|
|
95
95
|
const client = this.client;
|
|
96
96
|
const basePath = this.basePath;
|
|
97
97
|
return Effect.gen(function* () {
|
|
98
|
-
const
|
|
99
|
-
const conversationId = yield* requireStringEffect(
|
|
100
|
-
const conversationType = yield* requireStringEffect(
|
|
101
|
-
const limit = yield* optionalPositiveNumberEffect(
|
|
102
|
-
const offset = yield* optionalNonNegativeNumberEffect(
|
|
98
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
99
|
+
const conversationId = yield* requireStringEffect(validatedInput.conversationId, 'conversationId');
|
|
100
|
+
const conversationType = yield* requireStringEffect(validatedInput.conversationType, 'conversationType');
|
|
101
|
+
const limit = yield* optionalPositiveNumberEffect(validatedInput.limit, 'limit');
|
|
102
|
+
const offset = yield* optionalNonNegativeNumberEffect(validatedInput.offset, 'offset');
|
|
103
103
|
const params = buildEndpointParams({
|
|
104
104
|
conversationType: { wireName: 'conversation_type', value: conversationType },
|
|
105
105
|
limit: { wireName: 'limit', value: limit },
|
|
@@ -127,8 +127,8 @@ export class MessageApi {
|
|
|
127
127
|
const client = this.client;
|
|
128
128
|
const path = `${this.basePath}/send_message`;
|
|
129
129
|
return Effect.gen(function* () {
|
|
130
|
-
const
|
|
131
|
-
return yield* requestPostEffect(client, path,
|
|
130
|
+
const messageRequest = yield* requireObjectEffect(messageData, 'messageData');
|
|
131
|
+
return yield* requestPostEffect(client, path, messageRequest);
|
|
132
132
|
});
|
|
133
133
|
};
|
|
134
134
|
/**
|
|
@@ -150,8 +150,8 @@ export class MessageApi {
|
|
|
150
150
|
const client = this.client;
|
|
151
151
|
const path = `${this.basePath}/update_conversation`;
|
|
152
152
|
return Effect.gen(function* () {
|
|
153
|
-
const
|
|
154
|
-
return yield* requestPostEffect(client, path,
|
|
153
|
+
const conversationUpdate = yield* requireObjectEffect(updateData, 'updateData');
|
|
154
|
+
return yield* requestPostEffect(client, path, conversationUpdate);
|
|
155
155
|
});
|
|
156
156
|
};
|
|
157
157
|
}
|
|
@@ -2,7 +2,7 @@ import { buildEndpointParams, optionalNonNegativeNumberEffect, optionalPositiveN
|
|
|
2
2
|
import { Effect } from 'effect';
|
|
3
3
|
/**
|
|
4
4
|
* Negotiation API - Buyer-seller negotiations and offers
|
|
5
|
-
* Based on:
|
|
5
|
+
* Based on: sell_negotiation_v1_oas3.json
|
|
6
6
|
*/
|
|
7
7
|
export class NegotiationApi {
|
|
8
8
|
basePath = '/sell/negotiation/v1';
|
|
@@ -29,8 +29,8 @@ export class NegotiationApi {
|
|
|
29
29
|
const apiClient = this.client;
|
|
30
30
|
const path = `${this.basePath}/find_eligible_items`;
|
|
31
31
|
return Effect.gen(function* () {
|
|
32
|
-
const
|
|
33
|
-
const { marketplaceId: inputMarketplaceId, limit: inputLimit, offset: inputOffset } =
|
|
32
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
33
|
+
const { marketplaceId: inputMarketplaceId, limit: inputLimit, offset: inputOffset, } = validatedInput;
|
|
34
34
|
const marketplaceId = yield* optionalStringEffect(inputMarketplaceId, 'marketplaceId');
|
|
35
35
|
const limit = yield* optionalPositiveNumberEffect(inputLimit, 'limit');
|
|
36
36
|
const offset = yield* optionalNonNegativeNumberEffect(inputOffset, 'offset');
|
|
@@ -66,14 +66,14 @@ export class NegotiationApi {
|
|
|
66
66
|
const apiClient = this.client;
|
|
67
67
|
const path = `${this.basePath}/send_offer_to_interested_buyers`;
|
|
68
68
|
return Effect.gen(function* () {
|
|
69
|
-
const
|
|
70
|
-
const { marketplaceId, ...offerData } =
|
|
71
|
-
const
|
|
69
|
+
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
70
|
+
const { marketplaceId, ...offerData } = validatedInput;
|
|
71
|
+
const createOffersRequest = yield* requireObjectEffect(offerData, 'offerData');
|
|
72
72
|
const validatedMarketplaceId = yield* optionalStringEffect(marketplaceId, 'marketplaceId');
|
|
73
73
|
const config = validatedMarketplaceId === undefined
|
|
74
74
|
? undefined
|
|
75
75
|
: { headers: { 'X-EBAY-C-MARKETPLACE-ID': validatedMarketplaceId } };
|
|
76
|
-
return yield* requestPostEffect(apiClient, path,
|
|
76
|
+
return yield* requestPostEffect(apiClient, path, createOffersRequest, config);
|
|
77
77
|
});
|
|
78
78
|
};
|
|
79
79
|
}
|