@profplum700/etsy-v3-api-client 2.5.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -12
- package/README.md +138 -130
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser.esm.js +64 -23
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +1 -1
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +67 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +39 -5
- package/dist/index.esm.js +67 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/node.cjs +67 -24
- package/dist/node.cjs.map +1 -1
- package/dist/node.esm.js +67 -25
- package/dist/node.esm.js.map +1 -1
- package/package.json +1 -1
- package/dist/index.js +0 -8517
- package/dist/index.js.map +0 -1
- package/dist/index.umd.js +0 -1180
- package/dist/index.umd.js.map +0 -1
- package/dist/index.umd.min.js +0 -2
- package/dist/index.umd.min.js.map +0 -1
package/dist/browser.esm.js
CHANGED
|
@@ -639,6 +639,11 @@ class FileTokenStorage {
|
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
|
|
642
|
+
const ETSY_RATE_LIMITS = {
|
|
643
|
+
MAX_REQUESTS_PER_DAY: 5000,
|
|
644
|
+
MAX_REQUESTS_PER_SECOND: 5,
|
|
645
|
+
MIN_REQUEST_INTERVAL: 200,
|
|
646
|
+
};
|
|
642
647
|
class EtsyRateLimiter {
|
|
643
648
|
constructor(config) {
|
|
644
649
|
this.requestCount = 0;
|
|
@@ -647,9 +652,9 @@ class EtsyRateLimiter {
|
|
|
647
652
|
this.isHeaderBasedLimiting = false;
|
|
648
653
|
this.currentRetryCount = 0;
|
|
649
654
|
this.config = {
|
|
650
|
-
maxRequestsPerDay:
|
|
651
|
-
maxRequestsPerSecond:
|
|
652
|
-
minRequestInterval:
|
|
655
|
+
maxRequestsPerDay: ETSY_RATE_LIMITS.MAX_REQUESTS_PER_DAY,
|
|
656
|
+
maxRequestsPerSecond: ETSY_RATE_LIMITS.MAX_REQUESTS_PER_SECOND,
|
|
657
|
+
minRequestInterval: ETSY_RATE_LIMITS.MIN_REQUEST_INTERVAL,
|
|
653
658
|
maxRetries: 3,
|
|
654
659
|
baseDelayMs: 1000,
|
|
655
660
|
maxDelayMs: 30000,
|
|
@@ -704,7 +709,7 @@ class EtsyRateLimiter {
|
|
|
704
709
|
if (value === null)
|
|
705
710
|
return undefined;
|
|
706
711
|
const num = parseInt(value, 10);
|
|
707
|
-
return isNaN(num) ? undefined : num;
|
|
712
|
+
return Number.isNaN(num) ? undefined : num;
|
|
708
713
|
};
|
|
709
714
|
return {
|
|
710
715
|
limitPerSecond: parseNumber(getHeader('x-limit-per-second')),
|
|
@@ -1045,7 +1050,7 @@ class FieldValidator {
|
|
|
1045
1050
|
const value = data[this.field];
|
|
1046
1051
|
if (value === undefined || value === null)
|
|
1047
1052
|
return null;
|
|
1048
|
-
if (typeof value !== 'number' || isNaN(value)) {
|
|
1053
|
+
if (typeof value !== 'number' || Number.isNaN(value)) {
|
|
1049
1054
|
return {
|
|
1050
1055
|
field: this.field,
|
|
1051
1056
|
message: options.message || `${this.field} must be a number`,
|
|
@@ -1254,7 +1259,11 @@ function combineValidators(...validators) {
|
|
|
1254
1259
|
|
|
1255
1260
|
class DefaultLogger {
|
|
1256
1261
|
debug(message, ...args) {
|
|
1257
|
-
|
|
1262
|
+
let isDevelopment;
|
|
1263
|
+
{
|
|
1264
|
+
const host = window.location?.hostname;
|
|
1265
|
+
isDevelopment = host === 'localhost' || host === '127.0.0.1';
|
|
1266
|
+
}
|
|
1258
1267
|
if (isDevelopment) {
|
|
1259
1268
|
console.log(`[DEBUG] ${message}`, ...args);
|
|
1260
1269
|
}
|
|
@@ -1296,6 +1305,9 @@ class MemoryCache {
|
|
|
1296
1305
|
}
|
|
1297
1306
|
class EtsyClient {
|
|
1298
1307
|
constructor(config) {
|
|
1308
|
+
if (!config.sharedSecret) {
|
|
1309
|
+
throw new EtsyAuthError('sharedSecret is REQUIRED for Etsy API v3 application usage. See: https://github.com/profplum700/etsy-v3-api-client/issues/21');
|
|
1310
|
+
}
|
|
1299
1311
|
this.tokenManager = new TokenManager(config);
|
|
1300
1312
|
this.baseUrl = config.baseUrl || 'https://api.etsy.com/v3/application';
|
|
1301
1313
|
this.logger = new DefaultLogger();
|
|
@@ -1303,9 +1315,9 @@ class EtsyClient {
|
|
|
1303
1315
|
this.sharedSecret = config.sharedSecret;
|
|
1304
1316
|
if (config.rateLimiting?.enabled !== false) {
|
|
1305
1317
|
this.rateLimiter = new EtsyRateLimiter({
|
|
1306
|
-
maxRequestsPerDay: config.rateLimiting?.maxRequestsPerDay ||
|
|
1307
|
-
maxRequestsPerSecond: config.rateLimiting?.maxRequestsPerSecond ||
|
|
1308
|
-
minRequestInterval: config.rateLimiting?.minRequestInterval ??
|
|
1318
|
+
maxRequestsPerDay: config.rateLimiting?.maxRequestsPerDay || ETSY_RATE_LIMITS.MAX_REQUESTS_PER_DAY,
|
|
1319
|
+
maxRequestsPerSecond: config.rateLimiting?.maxRequestsPerSecond || ETSY_RATE_LIMITS.MAX_REQUESTS_PER_SECOND,
|
|
1320
|
+
minRequestInterval: config.rateLimiting?.minRequestInterval ?? ETSY_RATE_LIMITS.MIN_REQUEST_INTERVAL,
|
|
1309
1321
|
maxRetries: config.rateLimiting?.maxRetries,
|
|
1310
1322
|
baseDelayMs: config.rateLimiting?.baseDelayMs,
|
|
1311
1323
|
maxDelayMs: config.rateLimiting?.maxDelayMs,
|
|
@@ -1336,7 +1348,12 @@ class EtsyClient {
|
|
|
1336
1348
|
if (useCache && this.cache && requestOptions.method === 'GET') {
|
|
1337
1349
|
const cached = await this.cache.get(cacheKey);
|
|
1338
1350
|
if (cached) {
|
|
1339
|
-
|
|
1351
|
+
try {
|
|
1352
|
+
return JSON.parse(cached);
|
|
1353
|
+
}
|
|
1354
|
+
catch {
|
|
1355
|
+
await this.cache.delete(cacheKey);
|
|
1356
|
+
}
|
|
1340
1357
|
}
|
|
1341
1358
|
}
|
|
1342
1359
|
await this.rateLimiter.waitForRateLimit();
|
|
@@ -1410,10 +1427,7 @@ class EtsyClient {
|
|
|
1410
1427
|
return body;
|
|
1411
1428
|
}
|
|
1412
1429
|
getApiKey() {
|
|
1413
|
-
|
|
1414
|
-
return `${this.keystring}:${this.sharedSecret}`;
|
|
1415
|
-
}
|
|
1416
|
-
return this.keystring;
|
|
1430
|
+
return `${this.keystring}:${this.sharedSecret}`;
|
|
1417
1431
|
}
|
|
1418
1432
|
async getUser() {
|
|
1419
1433
|
return this.makeRequest('/users/me');
|
|
@@ -2084,6 +2098,22 @@ class EtsyClient {
|
|
|
2084
2098
|
async deleteListingVideo(shopId, listingId, videoId) {
|
|
2085
2099
|
await this.makeRequest(`/shops/${shopId}/listings/${listingId}/videos/${videoId}`, { method: 'DELETE' }, false);
|
|
2086
2100
|
}
|
|
2101
|
+
async getListingPersonalizations(listingId) {
|
|
2102
|
+
return this.makeRequest(`/listings/${listingId}/personalization`);
|
|
2103
|
+
}
|
|
2104
|
+
async updateListingPersonalization(shopId, listingId, params) {
|
|
2105
|
+
const { supports_multiple_personalization_questions, ...body } = params;
|
|
2106
|
+
const query = supports_multiple_personalization_questions
|
|
2107
|
+
? '?supports_multiple_personalization_questions=true'
|
|
2108
|
+
: '';
|
|
2109
|
+
return this.makeRequest(`/shops/${shopId}/listings/${listingId}/personalization${query}`, {
|
|
2110
|
+
method: 'POST',
|
|
2111
|
+
body: JSON.stringify(body)
|
|
2112
|
+
}, false);
|
|
2113
|
+
}
|
|
2114
|
+
async deleteListingPersonalization(shopId, listingId) {
|
|
2115
|
+
await this.makeRequest(`/shops/${shopId}/listings/${listingId}/personalization`, { method: 'DELETE' }, false);
|
|
2116
|
+
}
|
|
2087
2117
|
async createListingTranslation(shopId, listingId, language, params) {
|
|
2088
2118
|
const body = this.buildFormBody(params);
|
|
2089
2119
|
return this.makeRequest(`/shops/${shopId}/listings/${listingId}/translations/${language}`, {
|
|
@@ -2541,9 +2571,9 @@ class GlobalRequestQueue {
|
|
|
2541
2571
|
this.requestCount = 0;
|
|
2542
2572
|
this.dailyReset = new Date();
|
|
2543
2573
|
this.lastRequestTime = 0;
|
|
2544
|
-
this.maxRequestsPerDay =
|
|
2545
|
-
this.maxRequestsPerSecond =
|
|
2546
|
-
this.minRequestInterval =
|
|
2574
|
+
this.maxRequestsPerDay = ETSY_RATE_LIMITS.MAX_REQUESTS_PER_DAY;
|
|
2575
|
+
this.maxRequestsPerSecond = ETSY_RATE_LIMITS.MAX_REQUESTS_PER_SECOND;
|
|
2576
|
+
this.minRequestInterval = ETSY_RATE_LIMITS.MIN_REQUEST_INTERVAL;
|
|
2547
2577
|
this.setNextDailyReset();
|
|
2548
2578
|
}
|
|
2549
2579
|
static getInstance() {
|
|
@@ -2628,11 +2658,12 @@ class GlobalRequestQueue {
|
|
|
2628
2658
|
try {
|
|
2629
2659
|
let result;
|
|
2630
2660
|
if (item.timeout) {
|
|
2631
|
-
const
|
|
2661
|
+
const timeout = item.timeout;
|
|
2662
|
+
const remainingTimeout = timeout - elapsed;
|
|
2632
2663
|
let timeoutId;
|
|
2633
2664
|
const timeoutPromise = new Promise((_, reject) => {
|
|
2634
2665
|
timeoutId = setTimeout(() => {
|
|
2635
|
-
reject(new Error(`Request timeout after ${
|
|
2666
|
+
reject(new Error(`Request timeout after ${timeout}ms (exceeded during execution)`));
|
|
2636
2667
|
}, remainingTimeout);
|
|
2637
2668
|
if (timeoutId && typeof timeoutId.unref === 'function') {
|
|
2638
2669
|
timeoutId.unref();
|
|
@@ -2941,7 +2972,18 @@ class EtsyWebhookHandler {
|
|
|
2941
2972
|
}
|
|
2942
2973
|
}
|
|
2943
2974
|
parseEvent(payload) {
|
|
2944
|
-
|
|
2975
|
+
let data;
|
|
2976
|
+
if (typeof payload === 'string') {
|
|
2977
|
+
try {
|
|
2978
|
+
data = JSON.parse(payload);
|
|
2979
|
+
}
|
|
2980
|
+
catch {
|
|
2981
|
+
throw new Error('Invalid webhook payload: malformed JSON');
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
else {
|
|
2985
|
+
data = payload;
|
|
2986
|
+
}
|
|
2945
2987
|
if (!data.type || !data.data) {
|
|
2946
2988
|
throw new Error('Invalid webhook event format');
|
|
2947
2989
|
}
|
|
@@ -3331,7 +3373,6 @@ function createCacheStorage(config = {}) {
|
|
|
3331
3373
|
case 'lfu':
|
|
3332
3374
|
return new LFUCache(config);
|
|
3333
3375
|
case 'ttl':
|
|
3334
|
-
return new LRUCache(config);
|
|
3335
3376
|
default:
|
|
3336
3377
|
return new LRUCache(config);
|
|
3337
3378
|
}
|
|
@@ -4028,7 +4069,7 @@ function createCachingPlugin(config = {}) {
|
|
|
4028
4069
|
};
|
|
4029
4070
|
}
|
|
4030
4071
|
function createRateLimitPlugin(config = {}) {
|
|
4031
|
-
const maxRequestsPerSecond = config.maxRequestsPerSecond ||
|
|
4072
|
+
const maxRequestsPerSecond = config.maxRequestsPerSecond || ETSY_RATE_LIMITS.MAX_REQUESTS_PER_SECOND;
|
|
4032
4073
|
const requests = [];
|
|
4033
4074
|
return {
|
|
4034
4075
|
name: 'rateLimit',
|
|
@@ -4082,5 +4123,5 @@ function getLibraryInfo() {
|
|
|
4082
4123
|
};
|
|
4083
4124
|
}
|
|
4084
4125
|
|
|
4085
|
-
export { AuthHelper, BatchQueryExecutor, BulkOperationManager, COMMON_SCOPE_COMBINATIONS, CacheWithInvalidation, CreateListingSchema, DEFAULT_RETRY_CONFIG, ETSY_SCOPES, EncryptedFileTokenStorage, EtsyApiError, EtsyAuthError, EtsyClient, EtsyRateLimitError, EtsyRateLimiter, EtsyWebhookHandler, FieldValidator, FileTokenStorage, GlobalRequestQueue, LFUCache, LIBRARY_NAME, LRUCache, ListingQueryBuilder, LocalStorageTokenStorage, MemoryTokenStorage, PaginatedResults, PluginManager, ReceiptQueryBuilder, RedisCacheStorage, RetryManager, SecureTokenStorage, SessionStorageTokenStorage, TokenManager, UpdateListingSchema, UpdateShopSchema, VERSION, ValidationException, Validator, WebhookSecurity, combineValidators, createAnalyticsPlugin, createAuthHelper, createBatchQuery, createBulkOperationManager, createCacheStorage, createCacheWithInvalidation, createCachingPlugin, createCodeChallenge, createDefaultTokenStorage, createEtsyClient, createListingQuery, createLoggingPlugin, createPaginatedResults, createRateLimitPlugin, createRateLimiter, createReceiptQuery, createRedisCacheStorage, createRetryPlugin, createTokenManager, createValidator, createWebhookHandler, createWebhookSecurity, decryptAES256GCM, EtsyClient as default, defaultRateLimiter, deriveKeyFromPassword, encryptAES256GCM, executeBulkOperation, field, generateCodeVerifier, generateEncryptionKey, generateRandomBase64Url, generateState, getAvailableStorage, getEnvironmentInfo, getGlobalQueue, getLibraryInfo, hasLocalStorage, hasSessionStorage, isBrowser$1 as isBrowser, isNode, isSecureStorageSupported, sha256, sha256Base64Url, validate, validateEncryptionKey, validateOrThrow, withQueryBuilder, withQueue, withRetry };
|
|
4126
|
+
export { AuthHelper, BatchQueryExecutor, BulkOperationManager, COMMON_SCOPE_COMBINATIONS, CacheWithInvalidation, CreateListingSchema, DEFAULT_RETRY_CONFIG, ETSY_RATE_LIMITS, ETSY_SCOPES, EncryptedFileTokenStorage, EtsyApiError, EtsyAuthError, EtsyClient, EtsyRateLimitError, EtsyRateLimiter, EtsyWebhookHandler, FieldValidator, FileTokenStorage, GlobalRequestQueue, LFUCache, LIBRARY_NAME, LRUCache, ListingQueryBuilder, LocalStorageTokenStorage, MemoryTokenStorage, PaginatedResults, PluginManager, ReceiptQueryBuilder, RedisCacheStorage, RetryManager, SecureTokenStorage, SessionStorageTokenStorage, TokenManager, UpdateListingSchema, UpdateShopSchema, VERSION, ValidationException, Validator, WebhookSecurity, combineValidators, createAnalyticsPlugin, createAuthHelper, createBatchQuery, createBulkOperationManager, createCacheStorage, createCacheWithInvalidation, createCachingPlugin, createCodeChallenge, createDefaultTokenStorage, createEtsyClient, createListingQuery, createLoggingPlugin, createPaginatedResults, createRateLimitPlugin, createRateLimiter, createReceiptQuery, createRedisCacheStorage, createRetryPlugin, createTokenManager, createValidator, createWebhookHandler, createWebhookSecurity, decryptAES256GCM, EtsyClient as default, defaultRateLimiter, deriveKeyFromPassword, encryptAES256GCM, executeBulkOperation, field, generateCodeVerifier, generateEncryptionKey, generateRandomBase64Url, generateState, getAvailableStorage, getEnvironmentInfo, getGlobalQueue, getLibraryInfo, hasLocalStorage, hasSessionStorage, isBrowser$1 as isBrowser, isNode, isSecureStorageSupported, sha256, sha256Base64Url, validate, validateEncryptionKey, validateOrThrow, withQueryBuilder, withQueue, withRetry };
|
|
4086
4127
|
//# sourceMappingURL=browser.esm.js.map
|