ebay-mcp 1.18.3 → 2.0.1
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 +35 -17
- package/build/api/account-management/account.js +2 -2
- package/build/api/account-management/accountV2.js +0 -6
- package/build/api/account-management/finances.js +7 -5
- package/build/api/client/ebayApiClient.js +111 -10
- package/build/api/client/signEbayRequest.js +124 -0
- package/build/api/communication/feedback.js +4 -4
- package/build/api/developer/developer.js +43 -7
- package/build/api/ebaySellerApi.js +0 -8
- package/build/api/marketing-and-promotions/campaigns.js +0 -34
- package/build/api/order-management/dispute.js +29 -20
- package/build/api/order-management/fulfillment.js +2 -1
- package/build/api/other/browse.js +1 -2
- package/build/api/other/edelivery.js +3 -3
- package/build/api/other/translation.js +1 -1
- package/build/config/environment.js +31 -3
- package/build/schemas/account-management/account.js +1 -1
- package/build/schemas/account-management/accountV2.js +3 -4
- package/build/schemas/communication/messages.js +2 -2
- package/build/schemas/marketing/campaigns.js +0 -21
- package/build/schemas/other/otherApis.js +2 -85
- package/build/scripts/devSync.js +75 -225
- package/build/scripts/specCoverage.js +78 -0
- package/build/scripts/specDownload.js +42 -0
- package/build/scripts/specRefs.js +2 -3
- package/build/scripts/specSources.js +4 -6
- package/build/scripts/specTypeNames.js +23 -0
- package/build/skills/content.js +2 -2
- package/build/skills/registrySnapshot.js +1 -1
- package/build/tools/categories/account.js +3 -3
- package/build/tools/categories/browse.js +2 -10
- package/build/tools/categories/communication.js +5 -5
- package/build/tools/categories/developer.js +1 -1
- package/build/tools/categories/finances.js +2 -2
- package/build/tools/categories/marketing.js +0 -16
- package/build/tools/categories/other.js +3 -17
- package/build/types/ebay.js +0 -1
- package/build/types/ebayEnums.js +0 -40
- package/build/ui/card.html +23 -23
- package/build/ui/chart.html +22 -22
- package/build/ui/stat.html +23 -23
- package/build/ui/table.html +21 -21
- package/build/utils/communication/feedback.js +3 -3
- package/build/utils/errors.js +1 -0
- package/package.json +5 -5
- package/build/api/other/compliance.js +0 -60
- package/build/api/other/finding.js +0 -280
- package/build/schemas/other/finding.js +0 -27
- package/build/utils/other/compliance.js +0 -56
|
@@ -34,8 +34,8 @@ const sortSchema = z
|
|
|
34
34
|
description: 'Sort order for results',
|
|
35
35
|
})
|
|
36
36
|
.optional();
|
|
37
|
-
/** Schema for
|
|
38
|
-
export const
|
|
37
|
+
/** Schema for getItemsAwaitingFeedback input. */
|
|
38
|
+
export const getItemsAwaitingFeedbackSchema = z.object({
|
|
39
39
|
filter: filterSchema,
|
|
40
40
|
limit: limitSchema,
|
|
41
41
|
offset: offsetSchema,
|
|
@@ -100,7 +100,7 @@ export const getFeedbackRatingSummarySchema = z.object({
|
|
|
100
100
|
}),
|
|
101
101
|
});
|
|
102
102
|
/** Schema for leaveFeedback input. */
|
|
103
|
-
export const
|
|
103
|
+
export const leaveFeedbackSchema = z.object({
|
|
104
104
|
commentText: z
|
|
105
105
|
.string({
|
|
106
106
|
invalid_type_error: 'commentText must be a string',
|
package/build/utils/errors.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ebay-mcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Model Context Protocol (MCP) server that exposes 100% of eBay
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server that exposes 100% of the eBay Sell, Commerce and Developer APIs it tracks (379 tools across 356 endpoints) to AI assistants like Claude, Cursor, and Cline, covering inventory, order fulfillment, marketing, analytics, and developer tools with OAuth authentication and refresh-token support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"types": "build/index.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@modelcontextprotocol/ext-apps": "1.7.4",
|
|
57
|
-
"@modelcontextprotocol/sdk": "1.
|
|
57
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
58
58
|
"chalk": "^5.6.2",
|
|
59
59
|
"cors": "^2.8.6",
|
|
60
60
|
"dotenv": "^17.4.2",
|
|
@@ -93,10 +93,10 @@
|
|
|
93
93
|
"typescript": "^5.9.3",
|
|
94
94
|
"vite": "^7.3.5",
|
|
95
95
|
"vite-plugin-singlefile": "2.3.3",
|
|
96
|
-
"vitest": "^4.1.
|
|
96
|
+
"vitest": "^4.1.12"
|
|
97
97
|
},
|
|
98
98
|
"engines": {
|
|
99
|
-
"node": ">=
|
|
99
|
+
"node": ">=24"
|
|
100
100
|
},
|
|
101
101
|
"scripts": {
|
|
102
102
|
"build": "tsc && tsc-alias && pnpm run build:mcp-apps",
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { EbayApiError } from '../../api/shared/request.js';
|
|
2
|
-
import { Effect } from 'effect';
|
|
3
|
-
/**
|
|
4
|
-
* eBay decommissioned the Sell Compliance API on 2026-03-30 with no API
|
|
5
|
-
* replacement. Seller Hub → Performance → Issue Resolution Center is the UI path.
|
|
6
|
-
*
|
|
7
|
-
* @see https://developer.ebay.com/develop/guides/api-deprecation-status
|
|
8
|
-
*/
|
|
9
|
-
const COMPLIANCE_API_DECOMMISSIONED_MESSAGE = 'eBay decommissioned the Sell Compliance API on 2026-03-30. There is no API equivalent; use Seller Hub → Performance → Issue Resolution Center instead.';
|
|
10
|
-
const failDecommissioned = (path) => Effect.fail(new EbayApiError({
|
|
11
|
-
method: 'GET',
|
|
12
|
-
path,
|
|
13
|
-
cause: new Error(COMPLIANCE_API_DECOMMISSIONED_MESSAGE),
|
|
14
|
-
}));
|
|
15
|
-
/** Clear error copy exported for tests and callers that match on the message. */
|
|
16
|
-
export { COMPLIANCE_API_DECOMMISSIONED_MESSAGE };
|
|
17
|
-
/** Compliance API - listing policy violation checks (decommissioned by eBay). */
|
|
18
|
-
export class ComplianceApi {
|
|
19
|
-
basePath = '/sell/compliance/v1';
|
|
20
|
-
constructor(_client) {
|
|
21
|
-
// Client is unused: eBay decommissioned this API, so methods never call the network.
|
|
22
|
-
void _client;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Always fails: eBay decommissioned the Sell Compliance API on 2026-03-30.
|
|
26
|
-
*
|
|
27
|
-
* @param _input - Ignored; retained so existing call sites type-check.
|
|
28
|
-
* @returns An Effect that always fails with a clear decommission message.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* // Rejects with COMPLIANCE_API_DECOMMISSIONED_MESSAGE — no network call.
|
|
33
|
-
* await Effect.runPromise(complianceApi.getListingViolations({}));
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* @see https://developer.ebay.com/api-docs/sell/compliance/resources/listing_violation/methods/getListingViolations
|
|
37
|
-
*/
|
|
38
|
-
getListingViolations = (_input = {}) => {
|
|
39
|
-
void _input;
|
|
40
|
-
return failDecommissioned(`${this.basePath}/listing_violation`);
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Always fails: eBay decommissioned the Sell Compliance API on 2026-03-30.
|
|
44
|
-
*
|
|
45
|
-
* @param _input - Ignored; retained so existing call sites type-check.
|
|
46
|
-
* @returns An Effect that always fails with a clear decommission message.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* // Rejects with COMPLIANCE_API_DECOMMISSIONED_MESSAGE — no network call.
|
|
51
|
-
* await Effect.runPromise(complianceApi.getListingViolationsSummary({}));
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* @see https://developer.ebay.com/api-docs/sell/compliance/resources/listing_violation_summary/methods/getListingViolationsSummary
|
|
55
|
-
*/
|
|
56
|
-
getListingViolationsSummary = (_input = {}) => {
|
|
57
|
-
void _input;
|
|
58
|
-
return failDecommissioned(`${this.basePath}/listing_violation_summary`);
|
|
59
|
-
};
|
|
60
|
-
}
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { EbayApiError, EndpointInputError, optionalPositiveNumberEffect, requireObjectEffect, requireStringEffect, } from '../../api/shared/request.js';
|
|
2
|
-
import { isRecord } from '../../utils/typeGuards.js';
|
|
3
|
-
import { Effect } from 'effect';
|
|
4
|
-
/** Finding Service API version used for findCompletedItems. */
|
|
5
|
-
const FINDING_SERVICE_VERSION = '1.13.0';
|
|
6
|
-
/** Default page size when maxResults is omitted. */
|
|
7
|
-
const DEFAULT_MAX_RESULTS = 20;
|
|
8
|
-
/** Hard upper bound for paginationInput.entriesPerPage. */
|
|
9
|
-
const MAX_ENTRIES_PER_PAGE = 100;
|
|
10
|
-
/** Hard upper bound for the EndTimeFrom days-back window. */
|
|
11
|
-
const MAX_DAYS_BACK = 90;
|
|
12
|
-
/**
|
|
13
|
-
* Resolve the Finding Service base URL for the configured environment.
|
|
14
|
-
*
|
|
15
|
-
* Finding lives on the `svcs` host, not the Sell REST `api` host. When a proxy
|
|
16
|
-
* base URL is configured, the Finding path is appended so the proxy can route it.
|
|
17
|
-
*
|
|
18
|
-
* @param environment - eBay environment used when no override is configured.
|
|
19
|
-
* @param overrideBaseUrl - Optional base URL override from `EBAY_MCP_API_BASE_URL`.
|
|
20
|
-
* @returns Absolute Finding Service URL (no trailing slash).
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* const url = getFindingServiceBaseUrl('production');
|
|
25
|
-
* // https://svcs.ebay.com/services/search/FindingService/v1
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export const getFindingServiceBaseUrl = (environment, overrideBaseUrl) => {
|
|
29
|
-
if (overrideBaseUrl) {
|
|
30
|
-
return `${overrideBaseUrl.replace(/\/$/, '')}/services/search/FindingService/v1`;
|
|
31
|
-
}
|
|
32
|
-
return environment === 'production'
|
|
33
|
-
? 'https://svcs.ebay.com/services/search/FindingService/v1'
|
|
34
|
-
: 'https://svcs.sandbox.ebay.com/services/search/FindingService/v1';
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Build query parameters for Finding API findCompletedItems.
|
|
38
|
-
*
|
|
39
|
-
* Finding authenticates primarily via `SECURITY-APPNAME` (the app client id).
|
|
40
|
-
* Results are limited to sold listings through the `SoldItemsOnly` item filter.
|
|
41
|
-
*
|
|
42
|
-
* @param input - Validated search input plus the app client id.
|
|
43
|
-
* @returns Wire query params for the Finding Service GET request.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```ts
|
|
47
|
-
* const params = buildFindCompletedItemsParams({
|
|
48
|
-
* keywords: 'iphone 14',
|
|
49
|
-
* maxResults: 20,
|
|
50
|
-
* appId: 'client-id',
|
|
51
|
-
* });
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export const buildFindCompletedItemsParams = (input) => {
|
|
55
|
-
const params = {
|
|
56
|
-
'OPERATION-NAME': 'findCompletedItems',
|
|
57
|
-
'SERVICE-VERSION': FINDING_SERVICE_VERSION,
|
|
58
|
-
'SECURITY-APPNAME': input.appId,
|
|
59
|
-
'RESPONSE-DATA-FORMAT': 'JSON',
|
|
60
|
-
'REST-PAYLOAD': '',
|
|
61
|
-
keywords: input.keywords,
|
|
62
|
-
'paginationInput.entriesPerPage': input.maxResults,
|
|
63
|
-
'itemFilter(0).name': 'SoldItemsOnly',
|
|
64
|
-
'itemFilter(0).value': 'true',
|
|
65
|
-
};
|
|
66
|
-
if (input.daysBack !== undefined) {
|
|
67
|
-
const endTimeFrom = new Date();
|
|
68
|
-
endTimeFrom.setUTCDate(endTimeFrom.getUTCDate() - input.daysBack);
|
|
69
|
-
params['itemFilter(1).name'] = 'EndTimeFrom';
|
|
70
|
-
params['itemFilter(1).value'] = endTimeFrom.toISOString();
|
|
71
|
-
}
|
|
72
|
-
return params;
|
|
73
|
-
};
|
|
74
|
-
/** Read the first string from a Finding JSON array-or-string field. */
|
|
75
|
-
const firstString = (rawField) => {
|
|
76
|
-
if (typeof rawField === 'string' && rawField.length > 0) {
|
|
77
|
-
return rawField;
|
|
78
|
-
}
|
|
79
|
-
if (Array.isArray(rawField) && typeof rawField[0] === 'string' && rawField[0].length > 0) {
|
|
80
|
-
return rawField[0];
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
/** Read the first object from a Finding JSON array-or-object field. */
|
|
84
|
-
const firstRecord = (rawField) => {
|
|
85
|
-
if (isRecord(rawField)) {
|
|
86
|
-
return rawField;
|
|
87
|
-
}
|
|
88
|
-
if (Array.isArray(rawField) && isRecord(rawField[0])) {
|
|
89
|
-
return rawField[0];
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
/** Parse a Finding API money field (`@currencyId` + `__value__`). */
|
|
93
|
-
const parseMoney = (rawMoney) => {
|
|
94
|
-
const money = firstRecord(rawMoney);
|
|
95
|
-
if (!money) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const currency = typeof money['@currencyId'] === 'string'
|
|
99
|
-
? money['@currencyId']
|
|
100
|
-
: typeof money.currencyId === 'string'
|
|
101
|
-
? money.currencyId
|
|
102
|
-
: undefined;
|
|
103
|
-
const amount = typeof money.__value__ === 'string'
|
|
104
|
-
? money.__value__
|
|
105
|
-
: typeof money.value === 'string'
|
|
106
|
-
? money.value
|
|
107
|
-
: undefined;
|
|
108
|
-
if (!(currency && amount)) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
return { currency, value: amount };
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* Map one raw Finding item into a cleaned {@link CompletedItem}.
|
|
115
|
-
*
|
|
116
|
-
* @param raw - One item object from `searchResult.item`.
|
|
117
|
-
* @returns Cleaned item, or undefined when itemId/title are missing.
|
|
118
|
-
*/
|
|
119
|
-
export const mapFindingItem = (raw) => {
|
|
120
|
-
if (!isRecord(raw)) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const itemId = firstString(raw.itemId);
|
|
124
|
-
const title = firstString(raw.title);
|
|
125
|
-
if (!(itemId && title)) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
const sellingStatus = firstRecord(raw.sellingStatus);
|
|
129
|
-
const shippingInfo = firstRecord(raw.shippingInfo);
|
|
130
|
-
const listingInfo = firstRecord(raw.listingInfo);
|
|
131
|
-
const condition = firstRecord(raw.condition);
|
|
132
|
-
const price = parseMoney(sellingStatus?.currentPrice);
|
|
133
|
-
const shippingCost = parseMoney(shippingInfo?.shippingServiceCost);
|
|
134
|
-
const soldDate = firstString(listingInfo?.endTime);
|
|
135
|
-
const conditionName = firstString(condition?.conditionDisplayName);
|
|
136
|
-
const listingUrl = firstString(raw.viewItemURL);
|
|
137
|
-
return {
|
|
138
|
-
itemId,
|
|
139
|
-
title,
|
|
140
|
-
...(price === undefined ? {} : { price }),
|
|
141
|
-
...(shippingCost === undefined ? {} : { shippingCost }),
|
|
142
|
-
...(soldDate === undefined ? {} : { soldDate }),
|
|
143
|
-
...(conditionName === undefined ? {} : { condition: conditionName }),
|
|
144
|
-
...(listingUrl === undefined ? {} : { listingUrl }),
|
|
145
|
-
};
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* Map a raw Finding findCompletedItems JSON response into cleaned sold comps.
|
|
149
|
-
*
|
|
150
|
-
* Finding wraps most nodes in single-element arrays (XML→JSON conversion).
|
|
151
|
-
*
|
|
152
|
-
* @param raw - Full JSON body returned by the Finding Service.
|
|
153
|
-
* @param keywords - Keywords used for the request (echoed in the result).
|
|
154
|
-
* @returns Cleaned items plus optional total entry count.
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```ts
|
|
158
|
-
* const soldListings = mapFindCompletedItemsResponse(rawJson, 'iphone 14');
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
|
-
export const mapFindCompletedItemsResponse = (raw, keywords) => {
|
|
162
|
-
if (!isRecord(raw)) {
|
|
163
|
-
return { items: [], keywords };
|
|
164
|
-
}
|
|
165
|
-
const responseRoot = firstRecord(raw.findCompletedItemsResponse);
|
|
166
|
-
if (!responseRoot) {
|
|
167
|
-
return { items: [], keywords };
|
|
168
|
-
}
|
|
169
|
-
const searchResult = firstRecord(responseRoot.searchResult);
|
|
170
|
-
const rawItems = searchResult?.item;
|
|
171
|
-
const itemList = Array.isArray(rawItems) ? rawItems : rawItems === undefined ? [] : [rawItems];
|
|
172
|
-
const items = [];
|
|
173
|
-
for (const entry of itemList) {
|
|
174
|
-
const mapped = mapFindingItem(entry);
|
|
175
|
-
if (mapped) {
|
|
176
|
-
items.push(mapped);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
const pagination = firstRecord(responseRoot.paginationOutput);
|
|
180
|
-
const totalRaw = firstString(pagination?.totalEntries);
|
|
181
|
-
const totalEntries = totalRaw !== undefined && Number.isFinite(Number(totalRaw)) ? Number(totalRaw) : undefined;
|
|
182
|
-
return {
|
|
183
|
-
items,
|
|
184
|
-
keywords,
|
|
185
|
-
...(totalEntries === undefined ? {} : { totalEntries }),
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* Validate maxResults falls within Finding's supported range.
|
|
190
|
-
*
|
|
191
|
-
* @param maxResults - Positive page size already validated as > 0.
|
|
192
|
-
* @returns The same value when in range, or a tagged input error.
|
|
193
|
-
*/
|
|
194
|
-
const requireMaxResultsInRange = (maxResults) => {
|
|
195
|
-
if (maxResults > MAX_ENTRIES_PER_PAGE) {
|
|
196
|
-
return Effect.fail(new EndpointInputError({
|
|
197
|
-
parameter: 'maxResults',
|
|
198
|
-
message: `maxResults must be between 1 and ${MAX_ENTRIES_PER_PAGE}`,
|
|
199
|
-
}));
|
|
200
|
-
}
|
|
201
|
-
return Effect.succeed(maxResults);
|
|
202
|
-
};
|
|
203
|
-
/**
|
|
204
|
-
* Validate daysBack falls within the supported window when provided.
|
|
205
|
-
*
|
|
206
|
-
* @param daysBack - Optional positive day count.
|
|
207
|
-
* @returns The same value (or undefined) when valid, or a tagged input error.
|
|
208
|
-
*/
|
|
209
|
-
const requireDaysBackInRange = (daysBack) => {
|
|
210
|
-
if (daysBack === undefined) {
|
|
211
|
-
return Effect.succeed(undefined);
|
|
212
|
-
}
|
|
213
|
-
if (daysBack > MAX_DAYS_BACK) {
|
|
214
|
-
return Effect.fail(new EndpointInputError({
|
|
215
|
-
parameter: 'daysBack',
|
|
216
|
-
message: `daysBack must be between 1 and ${MAX_DAYS_BACK}`,
|
|
217
|
-
}));
|
|
218
|
-
}
|
|
219
|
-
return Effect.succeed(daysBack);
|
|
220
|
-
};
|
|
221
|
-
/** Finding API - sold/completed listing search for pricing research. */
|
|
222
|
-
export class FindingApi {
|
|
223
|
-
client;
|
|
224
|
-
constructor(client) {
|
|
225
|
-
this.client = client;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Search sold and completed eBay listings for pricing comps.
|
|
229
|
-
*
|
|
230
|
-
* Uses the legacy Finding API (`findCompletedItems`) with app credentials
|
|
231
|
-
* (`SECURITY-APPNAME`). Useful for market price research; sold listings only.
|
|
232
|
-
*
|
|
233
|
-
* @param input - Keywords plus optional result cap and days-back window.
|
|
234
|
-
* @returns An Effect that succeeds with cleaned sold-item comps.
|
|
235
|
-
*
|
|
236
|
-
* @example
|
|
237
|
-
* ```ts
|
|
238
|
-
* const comps = await Effect.runPromise(
|
|
239
|
-
* findingApi.findCompletedItems({ keywords: 'nike dunk low', maxResults: 25, daysBack: 30 }),
|
|
240
|
-
* );
|
|
241
|
-
* ```
|
|
242
|
-
*
|
|
243
|
-
* @see https://developer.ebay.com/devzone/finding/callref/findCompletedItems.html
|
|
244
|
-
*/
|
|
245
|
-
findCompletedItems = (input) => {
|
|
246
|
-
const client = this.client;
|
|
247
|
-
return Effect.gen(function* () {
|
|
248
|
-
const validatedInput = yield* requireObjectEffect(input, 'input');
|
|
249
|
-
const keywords = yield* requireStringEffect(validatedInput.keywords, 'keywords');
|
|
250
|
-
const maxResultsRaw = yield* optionalPositiveNumberEffect(validatedInput.maxResults, 'maxResults');
|
|
251
|
-
const daysBackRaw = yield* optionalPositiveNumberEffect(validatedInput.daysBack, 'daysBack');
|
|
252
|
-
const maxResults = yield* requireMaxResultsInRange(maxResultsRaw ?? DEFAULT_MAX_RESULTS);
|
|
253
|
-
const daysBack = yield* requireDaysBackInRange(daysBackRaw);
|
|
254
|
-
const config = client.getConfig();
|
|
255
|
-
const appId = config.clientId;
|
|
256
|
-
if (!appId) {
|
|
257
|
-
return yield* Effect.fail(new EndpointInputError({
|
|
258
|
-
parameter: 'clientId',
|
|
259
|
-
message: 'EBAY_CLIENT_ID is required for Finding API requests (SECURITY-APPNAME). Set it in your environment.',
|
|
260
|
-
}));
|
|
261
|
-
}
|
|
262
|
-
const baseUrl = getFindingServiceBaseUrl(config.environment, config.apiBaseUrl);
|
|
263
|
-
const params = buildFindCompletedItemsParams({
|
|
264
|
-
keywords,
|
|
265
|
-
maxResults,
|
|
266
|
-
...(daysBack === undefined ? {} : { daysBack }),
|
|
267
|
-
appId,
|
|
268
|
-
});
|
|
269
|
-
const raw = yield* Effect.tryPromise({
|
|
270
|
-
try: () => client.getWithFullUrl(baseUrl, params),
|
|
271
|
-
catch: (cause) => new EbayApiError({
|
|
272
|
-
method: 'GET',
|
|
273
|
-
path: baseUrl,
|
|
274
|
-
cause,
|
|
275
|
-
}),
|
|
276
|
-
});
|
|
277
|
-
return mapFindCompletedItemsResponse(raw, keywords);
|
|
278
|
-
});
|
|
279
|
-
};
|
|
280
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
* Finding API Schemas
|
|
4
|
-
*
|
|
5
|
-
* Zod input schemas for sold/completed listing search tools.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Validates input for ebay_find_completed_items (Finding API findCompletedItems).
|
|
9
|
-
*/
|
|
10
|
-
export const findCompletedItemsInputSchema = z.object({
|
|
11
|
-
keywords: z
|
|
12
|
-
.string()
|
|
13
|
-
.min(1)
|
|
14
|
-
.describe('Search keywords for sold/completed listings (e.g. "iphone 14 pro 256")'),
|
|
15
|
-
maxResults: z
|
|
16
|
-
.number()
|
|
17
|
-
.int()
|
|
18
|
-
.positive()
|
|
19
|
-
.optional()
|
|
20
|
-
.describe('Maximum sold items to return (1–100). Defaults to 20.'),
|
|
21
|
-
daysBack: z
|
|
22
|
-
.number()
|
|
23
|
-
.int()
|
|
24
|
-
.positive()
|
|
25
|
-
.optional()
|
|
26
|
-
.describe('Only include items that ended within this many days (1–90).'),
|
|
27
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
* Zod schemas for Compliance API input validation
|
|
4
|
-
* Based on: src/api/other/compliance.ts
|
|
5
|
-
* OpenAPI spec: sell_compliance_v1_oas3.json
|
|
6
|
-
* Types from: src/types/sell_compliance_v1_oas3.ts
|
|
7
|
-
*/
|
|
8
|
-
// Reusable schema for complianceType parameter
|
|
9
|
-
const complianceTypeSchema = z
|
|
10
|
-
.string({
|
|
11
|
-
invalid_type_error: 'complianceType must be a string',
|
|
12
|
-
description: 'Compliance type(s) to filter violations (e.g., ASPECTS_ADOPTION, HTTPS, OUTSIDE_EBAY_BUYING_AND_SELLING, RETURNS_POLICY)',
|
|
13
|
-
})
|
|
14
|
-
.optional();
|
|
15
|
-
// Reusable schema for offset parameter
|
|
16
|
-
const offsetSchema = z
|
|
17
|
-
.number({
|
|
18
|
-
invalid_type_error: 'offset must be a number',
|
|
19
|
-
description: 'Number of items to skip (zero-based index)',
|
|
20
|
-
})
|
|
21
|
-
.int()
|
|
22
|
-
.nonnegative()
|
|
23
|
-
.optional();
|
|
24
|
-
// Reusable schema for limit parameter
|
|
25
|
-
const limitSchema = z
|
|
26
|
-
.number({
|
|
27
|
-
invalid_type_error: 'limit must be a number',
|
|
28
|
-
description: 'Maximum number of items to return (default: 100, max: 200)',
|
|
29
|
-
})
|
|
30
|
-
.int()
|
|
31
|
-
.positive()
|
|
32
|
-
.optional();
|
|
33
|
-
/**
|
|
34
|
-
* Schema for getListingViolations method
|
|
35
|
-
* Endpoint: GET /listing_violation
|
|
36
|
-
* Query: complianceType, offset, limit, filter
|
|
37
|
-
*/
|
|
38
|
-
export const getListingViolationsSchema = z.object({
|
|
39
|
-
complianceType: complianceTypeSchema,
|
|
40
|
-
offset: offsetSchema,
|
|
41
|
-
limit: limitSchema,
|
|
42
|
-
filter: z
|
|
43
|
-
.string({
|
|
44
|
-
invalid_type_error: 'filter must be a string',
|
|
45
|
-
description: 'Filter by compliance state (e.g., complianceState:{OUT_OF_COMPLIANCE})',
|
|
46
|
-
})
|
|
47
|
-
.optional(),
|
|
48
|
-
});
|
|
49
|
-
/**
|
|
50
|
-
* Schema for getListingViolationsSummary method
|
|
51
|
-
* Endpoint: GET /listing_violation_summary
|
|
52
|
-
* Query: complianceType
|
|
53
|
-
*/
|
|
54
|
-
export const getListingViolationsSummarySchema = z.object({
|
|
55
|
-
complianceType: complianceTypeSchema,
|
|
56
|
-
});
|