@lgriffin/esi.ts 5.0.0 → 5.2.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +174 -7
  3. package/dist/EsiClient.d.ts +5 -0
  4. package/dist/EsiClient.d.ts.map +1 -1
  5. package/dist/EsiClient.js +13 -0
  6. package/dist/core/ApiClient.d.ts +4 -0
  7. package/dist/core/ApiClient.d.ts.map +1 -1
  8. package/dist/core/ApiClient.js +7 -0
  9. package/dist/core/ApiRequestHandler.d.ts +3 -1
  10. package/dist/core/ApiRequestHandler.d.ts.map +1 -1
  11. package/dist/core/ApiRequestHandler.js +107 -41
  12. package/dist/core/BatchRequestHandler.d.ts +12 -0
  13. package/dist/core/BatchRequestHandler.d.ts.map +1 -0
  14. package/dist/core/BatchRequestHandler.js +66 -0
  15. package/dist/core/constants.d.ts +2 -2
  16. package/dist/core/constants.js +1 -1
  17. package/dist/core/endpoints/createClient.d.ts.map +1 -1
  18. package/dist/core/endpoints/createClient.js +14 -2
  19. package/dist/core/endpoints/esi-cache-ttls.generated.d.ts +2 -0
  20. package/dist/core/endpoints/esi-cache-ttls.generated.d.ts.map +1 -0
  21. package/dist/core/endpoints/esi-cache-ttls.generated.js +126 -0
  22. package/dist/core/endpoints/esi-rate-limit-groups.generated.d.ts +7 -0
  23. package/dist/core/endpoints/esi-rate-limit-groups.generated.d.ts.map +1 -0
  24. package/dist/core/endpoints/esi-rate-limit-groups.generated.js +153 -0
  25. package/dist/core/pagination/PaginationHandler.d.ts +1 -1
  26. package/dist/core/pagination/PaginationHandler.d.ts.map +1 -1
  27. package/dist/core/pagination/PaginationHandler.js +2 -2
  28. package/dist/core/rateLimiter/IRateLimiter.d.ts +13 -3
  29. package/dist/core/rateLimiter/IRateLimiter.d.ts.map +1 -1
  30. package/dist/core/rateLimiter/RateLimiter.d.ts +24 -51
  31. package/dist/core/rateLimiter/RateLimiter.d.ts.map +1 -1
  32. package/dist/core/rateLimiter/RateLimiter.js +213 -109
  33. package/dist/core/util/error.d.ts +5 -1
  34. package/dist/core/util/error.d.ts.map +1 -1
  35. package/dist/core/util/error.js +11 -2
  36. package/dist/core/util/headersUtil.d.ts.map +1 -1
  37. package/dist/core/util/headersUtil.js +2 -1
  38. package/dist/core/util/retry.d.ts +8 -0
  39. package/dist/core/util/retry.d.ts.map +1 -0
  40. package/dist/core/util/retry.js +9 -0
  41. package/dist/core/util/stringUtil.d.ts +2 -0
  42. package/dist/core/util/stringUtil.d.ts.map +1 -0
  43. package/dist/core/util/stringUtil.js +6 -0
  44. package/dist/index.d.ts +5 -2
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +7 -2
  47. package/dist/types/api-responses.d.ts +1 -0
  48. package/dist/types/api-responses.d.ts.map +1 -1
  49. package/dist/types/api-responses.js +24 -0
  50. package/dist/types/common.d.ts +9 -0
  51. package/dist/types/common.d.ts.map +1 -1
  52. package/dist/types/generated/esi-spec.generated.d.ts +1763 -0
  53. package/dist/types/generated/esi-spec.generated.d.ts.map +1 -0
  54. package/dist/types/generated/esi-spec.generated.js +6 -0
  55. package/package.json +4 -2
@@ -1,171 +1,204 @@
1
1
  "use strict";
2
- /**
3
- * Rate Limiter for ESI API calls
4
- *
5
- * Implements both the new floating-window rate limiting system and the legacy
6
- * error-limit system per the official ESI documentation:
7
- *
8
- * New system (X-Ratelimit-* headers):
9
- * - Floating window with token bucket per IP+route group
10
- * - Token costs: 2xx = 2 tokens, 3xx = 1 token, 4xx = 5 tokens, 5xx = 0 tokens
11
- * - Returns 429 when bucket is empty, with Retry-After header
12
- *
13
- * Legacy system (x-esi-error-limit-* headers):
14
- * - 100 non-2xx/3xx errors per minute
15
- * - Returns 420 when limit exceeded, with Retry-After header
16
- */
17
2
  Object.defineProperty(exports, "__esModule", { value: true });
18
3
  exports.RateLimiter = void 0;
4
+ const esi_rate_limit_groups_generated_1 = require("../endpoints/esi-rate-limit-groups.generated");
5
+ const stringUtil_1 = require("../util/stringUtil");
19
6
  const loggerUtil_1 = require("../logger/loggerUtil");
20
7
  const sleep_1 = require("../util/sleep");
21
- /** Token costs per HTTP status code range, per ESI docs */
22
- const TOKEN_COSTS = {
23
- '2xx': 2,
24
- '3xx': 1,
25
- '4xx': 5,
26
- '5xx': 0,
27
- };
28
8
  function getTokenCost(statusCode) {
29
9
  if (statusCode >= 200 && statusCode < 300)
30
- return TOKEN_COSTS['2xx'];
10
+ return 2;
31
11
  if (statusCode >= 300 && statusCode < 400)
32
- return TOKEN_COSTS['3xx'];
12
+ return 1;
33
13
  if (statusCode >= 400 && statusCode < 500)
34
- return TOKEN_COSTS['4xx'];
14
+ return 5;
35
15
  if (statusCode >= 500 && statusCode < 600)
36
- return TOKEN_COSTS['5xx'];
37
- return 2; // default to 2xx cost
16
+ return 0;
17
+ return 2;
38
18
  }
19
+ const DEFAULT_WINDOW_MS = 900_000;
39
20
  class RateLimiter {
40
- rateLimitInfo;
41
- lastRequestTime = 0;
42
21
  minDelayMs;
43
- isTestMode = false;
44
22
  decelerationThreshold;
23
+ userKeyExtractor;
24
+ lastRequestTime = 0;
25
+ isTestMode = false;
26
+ errorLimitRemain = 100;
27
+ errorLimitReset = 0;
28
+ defaultBuckets = new Map();
29
+ userBuckets = null;
30
+ fallbackBucket;
31
+ lastCleanup = 0;
32
+ static CLEANUP_INTERVAL_MS = 60_000;
45
33
  constructor(config) {
46
34
  this.minDelayMs = config?.minDelayMs ?? 50;
47
35
  this.decelerationThreshold = config?.decelerationThreshold ?? 0.2;
48
- this.rateLimitInfo = this.defaultInfo();
36
+ this.userKeyExtractor = config?.userKeyExtractor;
37
+ if (this.userKeyExtractor) {
38
+ this.userBuckets = new Map();
39
+ }
40
+ this.fallbackBucket = this.createFallbackBucket();
41
+ }
42
+ createFallbackBucket() {
43
+ return {
44
+ group: '__fallback__',
45
+ remaining: -1,
46
+ limit: 0,
47
+ used: 0,
48
+ windowSizeMs: DEFAULT_WINDOW_MS,
49
+ blockedUntil: 0,
50
+ lastUpdated: 0,
51
+ };
52
+ }
53
+ createBucketFromSpec(spec) {
54
+ return {
55
+ group: spec.group,
56
+ remaining: spec.maxTokens,
57
+ limit: spec.maxTokens,
58
+ used: 0,
59
+ windowSizeMs: spec.windowSizeMs,
60
+ blockedUntil: 0,
61
+ lastUpdated: 0,
62
+ };
49
63
  }
50
- defaultInfo() {
64
+ createBucketForGroup(groupName) {
51
65
  return {
52
- remaining: -1, // -1 means "no data yet"
66
+ group: groupName,
67
+ remaining: -1,
53
68
  limit: 0,
54
69
  used: 0,
55
- group: null,
56
- errorLimitRemain: 100,
57
- errorLimitReset: 0,
58
- retryAfter: null,
70
+ windowSizeMs: DEFAULT_WINDOW_MS,
59
71
  blockedUntil: 0,
72
+ lastUpdated: 0,
60
73
  };
61
74
  }
62
- /**
63
- * Update rate limit information from response headers and status code.
64
- * Must be called on EVERY response, not just 2xx.
65
- */
66
- updateFromResponse(headers, statusCode) {
75
+ lookupGroupSpec(method, templatePath) {
76
+ if (!templatePath || !method)
77
+ return undefined;
78
+ const normalized = templatePath
79
+ .replace(/\/$/, '')
80
+ .replace(/\{(\w+)\}/g, (_, name) => `{${(0, stringUtil_1.camelToSnake)(name)}}`);
81
+ const key = `${method}:${normalized}`;
82
+ return esi_rate_limit_groups_generated_1.esiRateLimitGroups[key];
83
+ }
84
+ resolveBucketMap(requestHeaders) {
85
+ if (!this.userBuckets || !this.userKeyExtractor || !requestHeaders) {
86
+ return this.defaultBuckets;
87
+ }
88
+ const userKey = this.userKeyExtractor(requestHeaders);
89
+ let userSet = this.userBuckets.get(userKey);
90
+ if (!userSet) {
91
+ userSet = { groups: new Map(), lastAccessed: Date.now() };
92
+ this.userBuckets.set(userKey, userSet);
93
+ }
94
+ userSet.lastAccessed = Date.now();
95
+ return userSet.groups;
96
+ }
97
+ getBucket(templatePath, method, requestHeaders, groupNameOverride) {
98
+ const bucketMap = this.resolveBucketMap(requestHeaders);
99
+ const spec = this.lookupGroupSpec(method, templatePath);
100
+ const groupName = groupNameOverride ?? spec?.group;
101
+ if (!groupName)
102
+ return this.fallbackBucket;
103
+ let bucket = bucketMap.get(groupName);
104
+ if (!bucket) {
105
+ bucket = spec
106
+ ? this.createBucketFromSpec(spec)
107
+ : this.createBucketForGroup(groupName);
108
+ bucketMap.set(groupName, bucket);
109
+ }
110
+ return bucket;
111
+ }
112
+ cleanupStaleUsers() {
113
+ if (!this.userBuckets)
114
+ return;
115
+ const now = Date.now();
116
+ if (now - this.lastCleanup < RateLimiter.CLEANUP_INTERVAL_MS)
117
+ return;
118
+ this.lastCleanup = now;
119
+ for (const [userKey, userSet] of this.userBuckets) {
120
+ if (now - userSet.lastAccessed > DEFAULT_WINDOW_MS) {
121
+ this.userBuckets.delete(userKey);
122
+ }
123
+ }
124
+ }
125
+ updateFromResponse(headers, statusCode, templatePath, method, requestHeaders) {
67
126
  if (this.isTestMode)
68
127
  return;
69
- // New rate limit headers (preferred)
70
- const group = headers['x-ratelimit-group'] || null;
128
+ const responseGroup = headers['x-ratelimit-group'] || undefined;
129
+ const bucket = this.getBucket(templatePath, method, requestHeaders, responseGroup);
71
130
  if ('x-ratelimit-remaining' in headers) {
72
- this.rateLimitInfo.remaining = parseInt(headers['x-ratelimit-remaining'], 10);
131
+ bucket.remaining = parseInt(headers['x-ratelimit-remaining'], 10);
73
132
  }
74
133
  if ('x-ratelimit-limit' in headers) {
75
- this.rateLimitInfo.limit = parseInt(headers['x-ratelimit-limit'], 10);
134
+ bucket.limit = parseInt(headers['x-ratelimit-limit'], 10);
76
135
  }
77
136
  if ('x-ratelimit-used' in headers) {
78
- this.rateLimitInfo.used = parseInt(headers['x-ratelimit-used'], 10);
79
- }
80
- this.rateLimitInfo.group = group;
81
- // Legacy error limit headers
82
- if ('x-esi-error-limit-remain' in headers) {
83
- this.rateLimitInfo.errorLimitRemain = parseInt(headers['x-esi-error-limit-remain'], 10);
137
+ bucket.used = parseInt(headers['x-ratelimit-used'], 10);
84
138
  }
85
- if ('x-esi-error-limit-reset' in headers) {
86
- this.rateLimitInfo.errorLimitReset = parseInt(headers['x-esi-error-limit-reset'], 10);
87
- }
88
- // Retry-After (present on 420 and 429 responses)
139
+ bucket.lastUpdated = Date.now();
89
140
  if ('retry-after' in headers) {
90
141
  const retrySeconds = parseInt(headers['retry-after'], 10);
91
- this.rateLimitInfo.retryAfter = retrySeconds;
92
- this.rateLimitInfo.blockedUntil = Date.now() + retrySeconds * 1000;
142
+ bucket.blockedUntil = Date.now() + retrySeconds * 1000;
93
143
  }
94
- // Handle 420 (legacy error limited) and 429 (new rate limited)
95
144
  if (statusCode === 420 || statusCode === 429) {
96
- if (!this.rateLimitInfo.retryAfter) {
97
- // No Retry-After header — default to 60 seconds for safety
98
- this.rateLimitInfo.blockedUntil = Date.now() + 60_000;
145
+ if (bucket.blockedUntil <= Date.now()) {
146
+ bucket.blockedUntil = Date.now() + 60_000;
99
147
  }
100
148
  }
149
+ if ('x-esi-error-limit-remain' in headers) {
150
+ this.errorLimitRemain = parseInt(headers['x-esi-error-limit-remain'], 10);
151
+ }
152
+ if ('x-esi-error-limit-reset' in headers) {
153
+ this.errorLimitReset = parseInt(headers['x-esi-error-limit-reset'], 10);
154
+ }
101
155
  }
102
- /**
103
- * Legacy method — kept for backwards compatibility.
104
- * Prefer updateFromResponse() which also accepts status code.
105
- */
106
156
  updateRateLimitInfo(headers) {
107
157
  this.updateFromResponse(headers, 200);
108
158
  }
109
- /**
110
- * Check if we should wait before making the next request.
111
- * Enforces hard blocks (420/429), proactive deceleration, and minimum delay.
112
- */
113
- async checkRateLimit() {
159
+ async checkRateLimit(templatePath, method, requestHeaders) {
114
160
  if (this.isTestMode)
115
161
  return;
162
+ this.cleanupStaleUsers();
163
+ const bucket = this.getBucket(templatePath, method, requestHeaders);
116
164
  const now = Date.now();
117
- // Hard block: we received a 420/429 and must wait
118
- if (this.rateLimitInfo.blockedUntil > now) {
119
- const waitTime = this.rateLimitInfo.blockedUntil - now;
120
- (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Blocked for ${Math.ceil(waitTime / 1000)}s (420/429 received)`);
165
+ if (bucket.blockedUntil > now) {
166
+ const waitTime = bucket.blockedUntil - now;
167
+ (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Group '${bucket.group}' blocked for ${Math.ceil(waitTime / 1000)}s (420/429 received)`);
121
168
  await (0, sleep_1.sleep)(waitTime);
122
- // Clear the block after waiting
123
- this.rateLimitInfo.blockedUntil = 0;
124
- this.rateLimitInfo.retryAfter = null;
169
+ bucket.blockedUntil = 0;
125
170
  return;
126
171
  }
127
- // Legacy error limit: if remaining errors are very low, slow down
128
- if (this.rateLimitInfo.errorLimitRemain <= 10 &&
129
- this.rateLimitInfo.errorLimitRemain > 0) {
130
- const resetMs = this.rateLimitInfo.errorLimitReset * 1000;
131
- const delay = Math.min(resetMs, 5000); // cap at 5s
172
+ if (this.errorLimitRemain <= 10 && this.errorLimitRemain > 0) {
173
+ const resetMs = this.errorLimitReset * 1000;
174
+ const delay = Math.min(resetMs, 5000);
132
175
  if (delay > 0) {
133
- (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Legacy error limit low (${this.rateLimitInfo.errorLimitRemain}), waiting ${delay}ms`);
176
+ (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Legacy error limit low (${this.errorLimitRemain}), waiting ${delay}ms`);
134
177
  await (0, sleep_1.sleep)(delay);
135
178
  return;
136
179
  }
137
180
  }
138
- // Legacy error limit: completely exhausted
139
- if (this.rateLimitInfo.errorLimitRemain <= 0 &&
140
- this.rateLimitInfo.errorLimitReset > 0) {
141
- const waitTime = this.rateLimitInfo.errorLimitReset * 1000;
181
+ if (this.errorLimitRemain <= 0 && this.errorLimitReset > 0) {
182
+ const waitTime = this.errorLimitReset * 1000;
142
183
  (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Legacy error limit exhausted, waiting ${Math.ceil(waitTime / 1000)}s`);
143
184
  await (0, sleep_1.sleep)(waitTime);
144
185
  return;
145
186
  }
146
- // Proactive deceleration: if new-system remaining is known and getting low
147
- if (this.rateLimitInfo.remaining >= 0 && this.rateLimitInfo.limit > 0) {
148
- const ratio = this.rateLimitInfo.remaining / this.rateLimitInfo.limit;
149
- if (this.rateLimitInfo.remaining <= 0) {
150
- // Bucket empty — wait before next request
151
- (0, loggerUtil_1.logWarn)('[ESI Rate Limit] Token bucket empty, waiting 1s');
187
+ if (bucket.remaining >= 0 && bucket.limit > 0) {
188
+ const ratio = bucket.remaining / bucket.limit;
189
+ if (bucket.remaining <= 0) {
190
+ (0, loggerUtil_1.logWarn)(`[ESI Rate Limit] Group '${bucket.group}' token bucket empty, waiting 1s`);
152
191
  await (0, sleep_1.sleep)(1000);
153
192
  return;
154
193
  }
155
194
  if (ratio <= this.decelerationThreshold) {
156
- // Linearly increase delay as remaining approaches 0
157
- // At 20% remaining: ~50ms extra, at 1% remaining: ~1000ms extra
158
195
  const extraDelay = Math.ceil((1 - ratio / this.decelerationThreshold) * 1000);
159
196
  await (0, sleep_1.sleep)(extraDelay);
160
197
  return;
161
198
  }
162
199
  }
163
- // Minimum delay between requests
164
200
  await this.enforceMinDelay();
165
201
  }
166
- /**
167
- * Enforce minimum delay between requests
168
- */
169
202
  async enforceMinDelay() {
170
203
  if (this.isTestMode) {
171
204
  this.lastRequestTime = Date.now();
@@ -178,26 +211,97 @@ class RateLimiter {
178
211
  }
179
212
  this.lastRequestTime = Date.now();
180
213
  }
181
- /** Get current rate limit status */
182
214
  getStatus() {
183
- return { ...this.rateLimitInfo };
215
+ let worstBucket = this.fallbackBucket;
216
+ let worstRatio = Infinity;
217
+ const checkBucket = (bucket) => {
218
+ if (bucket.limit > 0) {
219
+ const ratio = bucket.remaining / bucket.limit;
220
+ if (ratio < worstRatio) {
221
+ worstRatio = ratio;
222
+ worstBucket = bucket;
223
+ }
224
+ }
225
+ };
226
+ for (const bucket of this.defaultBuckets.values()) {
227
+ checkBucket(bucket);
228
+ }
229
+ if (this.userBuckets) {
230
+ for (const userSet of this.userBuckets.values()) {
231
+ for (const bucket of userSet.groups.values()) {
232
+ checkBucket(bucket);
233
+ }
234
+ }
235
+ }
236
+ return {
237
+ remaining: worstBucket.remaining,
238
+ limit: worstBucket.limit,
239
+ used: worstBucket.used,
240
+ group: worstBucket.group === '__fallback__' ? null : worstBucket.group,
241
+ errorLimitRemain: this.errorLimitRemain,
242
+ errorLimitReset: this.errorLimitReset,
243
+ retryAfter: worstBucket.blockedUntil > Date.now()
244
+ ? Math.ceil((worstBucket.blockedUntil - Date.now()) / 1000)
245
+ : null,
246
+ blockedUntil: worstBucket.blockedUntil,
247
+ };
248
+ }
249
+ getGroupStatus(group) {
250
+ const bucket = this.defaultBuckets.get(group);
251
+ if (!bucket)
252
+ return undefined;
253
+ return {
254
+ group: bucket.group,
255
+ remaining: bucket.remaining,
256
+ limit: bucket.limit,
257
+ used: bucket.used,
258
+ windowSizeMs: bucket.windowSizeMs,
259
+ blockedUntil: bucket.blockedUntil,
260
+ };
261
+ }
262
+ getAllGroupStatuses() {
263
+ const result = new Map();
264
+ for (const [name, bucket] of this.defaultBuckets) {
265
+ result.set(name, {
266
+ group: bucket.group,
267
+ remaining: bucket.remaining,
268
+ limit: bucket.limit,
269
+ used: bucket.used,
270
+ windowSizeMs: bucket.windowSizeMs,
271
+ blockedUntil: bucket.blockedUntil,
272
+ });
273
+ }
274
+ return result;
184
275
  }
185
- /** Get token cost for a given status code */
186
276
  static getTokenCost(statusCode) {
187
277
  return getTokenCost(statusCode);
188
278
  }
189
- /** Check if currently blocked (420/429 backoff active) */
190
- isBlocked() {
191
- return this.rateLimitInfo.blockedUntil > Date.now();
279
+ isBlocked(group) {
280
+ const now = Date.now();
281
+ if (group) {
282
+ const bucket = this.defaultBuckets.get(group);
283
+ return bucket ? bucket.blockedUntil > now : false;
284
+ }
285
+ if (this.fallbackBucket.blockedUntil > now)
286
+ return true;
287
+ for (const bucket of this.defaultBuckets.values()) {
288
+ if (bucket.blockedUntil > now)
289
+ return true;
290
+ }
291
+ return false;
192
292
  }
193
- /** Set test mode (disables all delays) */
194
293
  setTestMode(enabled) {
195
294
  this.isTestMode = enabled;
196
295
  }
197
- /** Reset rate limiter state */
198
296
  reset() {
199
- this.rateLimitInfo = this.defaultInfo();
297
+ this.defaultBuckets.clear();
298
+ if (this.userBuckets)
299
+ this.userBuckets.clear();
300
+ this.fallbackBucket = this.createFallbackBucket();
301
+ this.errorLimitRemain = 100;
302
+ this.errorLimitReset = 0;
200
303
  this.lastRequestTime = 0;
304
+ this.lastCleanup = 0;
201
305
  }
202
306
  }
203
307
  exports.RateLimiter = RateLimiter;
@@ -17,7 +17,11 @@ export declare function isNotFound(error: unknown): error is EsiError;
17
17
  export declare function isUnauthorized(error: unknown): error is EsiError;
18
18
  export declare function isForbidden(error: unknown): error is EsiError;
19
19
  export declare function isServerError(error: unknown): error is EsiError;
20
- export declare function isTimeout(error: unknown): error is EsiError;
20
+ export declare class TimeoutError extends EsiError {
21
+ readonly timeoutMs: number;
22
+ constructor(timeoutMs: number, url?: string, requestId?: string);
23
+ }
24
+ export declare function isTimeout(error: unknown): error is TimeoutError;
21
25
  export declare function isRetryable(error: unknown): error is EsiError;
22
26
  export declare const buildError: (message: string, type?: string, url?: string) => Error;
23
27
  //# sourceMappingURL=error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/core/util/error.ts"],"names":[],"mappings":"AAiBA,qBAAa,QAAS,SAAQ,KAAK;aAIf,UAAU,EAAE,MAAM;aAGlB,SAAS,CAAC,EAAE,MAAM;IANpC,SAAgB,GAAG,CAAC,EAAE,MAAM,CAAC;gBAGX,UAAU,EAAE,MAAM,EAClC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACI,SAAS,CAAC,EAAE,MAAM,YAAA;IAOpC,aAAa,IAAI,OAAO;IAIxB,UAAU,IAAI,OAAO;IAIrB,cAAc,IAAI,OAAO;IAIzB,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,OAAO;IAIxB,SAAS,IAAI,OAAO;IAIpB,IAAI,SAAS,IAAI,OAAO,CASvB;CACF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE/D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEhE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE/D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE3D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE7D;AAED,eAAO,MAAM,UAAU,GACrB,SAAS,MAAM,EACf,OAAM,MAAgB,EACtB,MAAM,MAAM,KACX,KAMF,CAAC"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/core/util/error.ts"],"names":[],"mappings":"AAiBA,qBAAa,QAAS,SAAQ,KAAK;aAIf,UAAU,EAAE,MAAM;aAGlB,SAAS,CAAC,EAAE,MAAM;IANpC,SAAgB,GAAG,CAAC,EAAE,MAAM,CAAC;gBAGX,UAAU,EAAE,MAAM,EAClC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACI,SAAS,CAAC,EAAE,MAAM,YAAA;IAOpC,aAAa,IAAI,OAAO;IAIxB,UAAU,IAAI,OAAO;IAIrB,cAAc,IAAI,OAAO;IAIzB,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,OAAO;IAIxB,SAAS,IAAI,OAAO;IAIpB,IAAI,SAAS,IAAI,OAAO,CASvB;CACF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE/D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEhE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE/D;AAED,qBAAa,YAAa,SAAQ,QAAQ;aAEtB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM,EACjC,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM;CAKrB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAE/D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE7D;AAED,eAAO,MAAM,UAAU,GACrB,SAAS,MAAM,EACf,OAAM,MAAgB,EACtB,MAAM,MAAM,KACX,KAMF,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildError = exports.EsiError = void 0;
3
+ exports.buildError = exports.TimeoutError = exports.EsiError = void 0;
4
4
  exports.isEsiError = isEsiError;
5
5
  exports.isRateLimited = isRateLimited;
6
6
  exports.isNotFound = isNotFound;
@@ -84,8 +84,17 @@ function isForbidden(error) {
84
84
  function isServerError(error) {
85
85
  return error instanceof EsiError && error.isServerError();
86
86
  }
87
+ class TimeoutError extends EsiError {
88
+ timeoutMs;
89
+ constructor(timeoutMs, url, requestId) {
90
+ super(0, `Request timed out after ${timeoutMs}ms`, url, requestId);
91
+ this.timeoutMs = timeoutMs;
92
+ this.name = 'TimeoutError';
93
+ }
94
+ }
95
+ exports.TimeoutError = TimeoutError;
87
96
  function isTimeout(error) {
88
- return error instanceof EsiError && error.isTimeout();
97
+ return error instanceof TimeoutError;
89
98
  }
90
99
  function isRetryable(error) {
91
100
  return error instanceof EsiError && error.retryable;
@@ -1 +1 @@
1
- {"version":3,"file":"headersUtil.d.ts","sourceRoot":"","sources":["../../../src/core/util/headersUtil.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,UAAU,GAAG,IAAI,CAOnB;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,OAAO,GAAG,aAAa,CAwBjE"}
1
+ {"version":3,"file":"headersUtil.d.ts","sourceRoot":"","sources":["../../../src/core/util/headersUtil.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,UAAU,GAAG,IAAI,CAQnB;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,OAAO,GAAG,aAAa,CAwBjE"}
@@ -9,7 +9,8 @@ function parseWarning(value) {
9
9
  /^(\d{3}) - ([^ ].+[^ ])$/.exec(value);
10
10
  if (!match)
11
11
  return null;
12
- return { code: parseInt(match[1], 10), message: match[2] };
12
+ const [, code, message] = match;
13
+ return { code: parseInt(code, 10), message: message };
13
14
  }
14
15
  function parseHeaders(fetchHeaders) {
15
16
  const raw = {};
@@ -0,0 +1,8 @@
1
+ export interface RetryConfig {
2
+ maxRetries?: number;
3
+ baseDelayMs?: number;
4
+ maxDelayMs?: number;
5
+ retryMutations?: boolean;
6
+ }
7
+ export declare function retryDelay(attempt: number, baseMs: number, maxMs: number): number;
8
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/core/util/retry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,CAKR"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.retryDelay = retryDelay;
4
+ function retryDelay(attempt, baseMs, maxMs) {
5
+ const exponential = baseMs * Math.pow(2, attempt);
6
+ // eslint-disable-next-line sonarjs/pseudo-random
7
+ const jitter = exponential * (0.75 + Math.random() * 0.5);
8
+ return Math.min(jitter, maxMs);
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare function camelToSnake(s: string): string;
2
+ //# sourceMappingURL=stringUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringUtil.d.ts","sourceRoot":"","sources":["../../../src/core/util/stringUtil.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.camelToSnake = camelToSnake;
4
+ function camelToSnake(s) {
5
+ return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
6
+ }
package/dist/index.d.ts CHANGED
@@ -42,17 +42,20 @@ export { MercenaryClient } from './clients/MercenaryClient';
42
42
  export { AccessListsClient } from './clients/AccessListsClient';
43
43
  export { CursorOptions, CursorResult, CreateClientOptions, WithMetadata, fetchAllCursorPages, } from './core/endpoints/createClient';
44
44
  export { CursorTokens } from './core/pagination/CursorPaginationHandler';
45
- export { EsiError, isEsiError, isRateLimited, isNotFound, isUnauthorized, isForbidden, isServerError, isTimeout, isRetryable, } from './core/util/error';
45
+ export { EsiError, TimeoutError, isEsiError, isRateLimited, isNotFound, isUnauthorized, isForbidden, isServerError, isTimeout, isRetryable, } from './core/util/error';
46
46
  export { DeprecationInfo } from './core/endpoints/EndpointDefinition';
47
47
  export { RequestInterceptor, ResponseInterceptor, RequestContext, ResponseContext, } from './core/middleware/Middleware';
48
48
  export { CircuitBreaker, CircuitBreakerConfig, CircuitState, CircuitOpenError, } from './core/circuitBreaker/CircuitBreaker';
49
49
  export { RateLimiter, RateLimitInfo, RateLimiterConfig, } from './core/rateLimiter/RateLimiter';
50
50
  export { ETagCacheManager, ETagCacheConfig, } from './core/cache/ETagCacheManager';
51
+ export { RetryConfig } from './core/util/retry';
51
52
  export { RequestDeduplicator } from './core/RequestDeduplicator';
53
+ export { batchFetch, batchPost, BatchOptions, BatchResult, } from './core/BatchRequestHandler';
52
54
  export { EsiDiagnostics, CacheStats, CircuitBreakerStats, } from './core/EsiDiagnostics';
53
55
  export { fetchPages, PageResult, } from './core/pagination/AsyncPaginationIterator';
54
56
  export { ICache } from './core/cache/ICache';
55
- export { IRateLimiter } from './core/rateLimiter/IRateLimiter';
57
+ export { IRateLimiter, RateLimitGroupStatus, } from './core/rateLimiter/IRateLimiter';
58
+ export { RateLimitGroupSpec } from './core/endpoints/esi-rate-limit-groups.generated';
56
59
  export { ILogger } from './core/logger/ILogger';
57
60
  export { setLogger } from './core/logger/loggerUtil';
58
61
  export * from './types/api-responses';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isForbidden = exports.isUnauthorized = exports.isNotFound = exports.isRateLimited = exports.isEsiError = exports.EsiError = exports.fetchAllCursorPages = exports.AccessListsClient = exports.MercenaryClient = exports.SkyhooksClient = exports.FreelanceJobsClient = exports.MetaClient = exports.WarsClient = exports.WalletClient = exports.UniverseClient = exports.UiClient = exports.StatusClient = exports.SovereigntyClient = exports.CharacterSkillsClient = exports.SearchClient = exports.RouteClient = exports.PiClient = exports.MarketClient = exports.MailClient = exports.LoyaltyClient = exports.LocationClient = exports.KillmailsClient = exports.InsuranceClient = exports.IndustryClient = exports.IncursionsClient = exports.FleetClient = exports.FittingsClient = exports.FactionClient = exports.DogmaClient = exports.CorporationsClient = exports.ContractsClient = exports.ContactsClient = exports.ClonesClient = exports.CharacterClient = exports.CalendarClient = exports.AssetsClient = exports.AllianceClient = exports.BaseEsiClient = exports.ApiClientBuilder = exports.ApiClient = exports.EsiApiFactory = exports.EsiClientBuilder = exports.CustomEsiClient = exports.getDefaultClient = exports.EsiClient = void 0;
18
- exports.setLogger = exports.fetchPages = exports.EsiDiagnostics = exports.RequestDeduplicator = exports.ETagCacheManager = exports.RateLimiter = exports.CircuitOpenError = exports.CircuitBreaker = exports.isRetryable = exports.isTimeout = exports.isServerError = void 0;
17
+ exports.isUnauthorized = exports.isNotFound = exports.isRateLimited = exports.isEsiError = exports.TimeoutError = exports.EsiError = exports.fetchAllCursorPages = exports.AccessListsClient = exports.MercenaryClient = exports.SkyhooksClient = exports.FreelanceJobsClient = exports.MetaClient = exports.WarsClient = exports.WalletClient = exports.UniverseClient = exports.UiClient = exports.StatusClient = exports.SovereigntyClient = exports.CharacterSkillsClient = exports.SearchClient = exports.RouteClient = exports.PiClient = exports.MarketClient = exports.MailClient = exports.LoyaltyClient = exports.LocationClient = exports.KillmailsClient = exports.InsuranceClient = exports.IndustryClient = exports.IncursionsClient = exports.FleetClient = exports.FittingsClient = exports.FactionClient = exports.DogmaClient = exports.CorporationsClient = exports.ContractsClient = exports.ContactsClient = exports.ClonesClient = exports.CharacterClient = exports.CalendarClient = exports.AssetsClient = exports.AllianceClient = exports.BaseEsiClient = exports.ApiClientBuilder = exports.ApiClient = exports.EsiApiFactory = exports.EsiClientBuilder = exports.CustomEsiClient = exports.getDefaultClient = exports.EsiClient = void 0;
18
+ exports.setLogger = exports.fetchPages = exports.EsiDiagnostics = exports.batchPost = exports.batchFetch = exports.RequestDeduplicator = exports.ETagCacheManager = exports.RateLimiter = exports.CircuitOpenError = exports.CircuitBreaker = exports.isRetryable = exports.isTimeout = exports.isServerError = exports.isForbidden = void 0;
19
19
  // Main client
20
20
  var EsiClient_1 = require("./EsiClient");
21
21
  Object.defineProperty(exports, "EsiClient", { enumerable: true, get: function () { return EsiClient_1.EsiClient; } });
@@ -111,6 +111,7 @@ Object.defineProperty(exports, "fetchAllCursorPages", { enumerable: true, get: f
111
111
  // Error class & type guards
112
112
  var error_1 = require("./core/util/error");
113
113
  Object.defineProperty(exports, "EsiError", { enumerable: true, get: function () { return error_1.EsiError; } });
114
+ Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return error_1.TimeoutError; } });
114
115
  Object.defineProperty(exports, "isEsiError", { enumerable: true, get: function () { return error_1.isEsiError; } });
115
116
  Object.defineProperty(exports, "isRateLimited", { enumerable: true, get: function () { return error_1.isRateLimited; } });
116
117
  Object.defineProperty(exports, "isNotFound", { enumerable: true, get: function () { return error_1.isNotFound; } });
@@ -131,6 +132,10 @@ Object.defineProperty(exports, "ETagCacheManager", { enumerable: true, get: func
131
132
  // Request deduplication
132
133
  var RequestDeduplicator_1 = require("./core/RequestDeduplicator");
133
134
  Object.defineProperty(exports, "RequestDeduplicator", { enumerable: true, get: function () { return RequestDeduplicator_1.RequestDeduplicator; } });
135
+ // Batch operations
136
+ var BatchRequestHandler_1 = require("./core/BatchRequestHandler");
137
+ Object.defineProperty(exports, "batchFetch", { enumerable: true, get: function () { return BatchRequestHandler_1.batchFetch; } });
138
+ Object.defineProperty(exports, "batchPost", { enumerable: true, get: function () { return BatchRequestHandler_1.batchPost; } });
134
139
  // Diagnostics
135
140
  var EsiDiagnostics_1 = require("./core/EsiDiagnostics");
136
141
  Object.defineProperty(exports, "EsiDiagnostics", { enumerable: true, get: function () { return EsiDiagnostics_1.EsiDiagnostics; } });
@@ -30,4 +30,5 @@ export * from './freelance-jobs';
30
30
  export * from './skyhooks';
31
31
  export * from './mercenary';
32
32
  export * from './access-lists';
33
+ export * as EsiSpec from './generated/esi-spec.generated';
33
34
  //# sourceMappingURL=api-responses.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-responses.d.ts","sourceRoot":"","sources":["../../src/types/api-responses.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,MAAM,CAAC;AACrB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"api-responses.d.ts","sourceRoot":"","sources":["../../src/types/api-responses.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,MAAM,CAAC;AACrB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,KAAK,OAAO,MAAM,gCAAgC,CAAC"}