@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
@@ -6,6 +6,10 @@ const loggerUtil_1 = require("../core/logger/loggerUtil");
6
6
  const headersUtil_1 = require("../core/util/headersUtil");
7
7
  const PaginationHandler_1 = require("./pagination/PaginationHandler");
8
8
  const constants_1 = require("./constants");
9
+ const esi_cache_ttls_generated_1 = require("./endpoints/esi-cache-ttls.generated");
10
+ const retry_1 = require("./util/retry");
11
+ const sleep_1 = require("./util/sleep");
12
+ const CircuitBreaker_1 = require("./circuitBreaker/CircuitBreaker");
9
13
  const STATUS_MESSAGES = {
10
14
  201: 'Created',
11
15
  204: 'No Content',
@@ -38,8 +42,41 @@ function resolveCircuitBreaker(client) {
38
42
  return client.getCircuitBreaker();
39
43
  }
40
44
  // --- Pure helpers ---
45
+ const stringUtil_1 = require("./util/stringUtil");
46
+ function lookupSpecTtl(method, templatePath) {
47
+ const normalized = templatePath
48
+ .replace(/\/$/, '')
49
+ .replace(/\{(\w+)\}/g, (_, name) => `{${(0, stringUtil_1.camelToSnake)(name)}}`);
50
+ const key = `${method}:${normalized}`;
51
+ const seconds = esi_cache_ttls_generated_1.esiCacheTtls[key];
52
+ return typeof seconds === 'number' ? seconds * 1000 : undefined;
53
+ }
54
+ function trySpecAwareCacheHit(client, url, method, templatePath) {
55
+ if (method !== 'GET' || !templatePath)
56
+ return null;
57
+ const specTtlMs = lookupSpecTtl(method, templatePath);
58
+ if (!specTtlMs)
59
+ return null;
60
+ const cache = resolveCache(client);
61
+ if (!cache)
62
+ return null;
63
+ const entry = cache.get(url);
64
+ if (!entry)
65
+ return null;
66
+ const age = Date.now() - entry.timestamp;
67
+ if (age < specTtlMs) {
68
+ (0, loggerUtil_1.logDebug)(`Spec-aware cache hit for ${url} (age=${Math.round(age / 1000)}s, ttl=${Math.round(specTtlMs / 1000)}s)`);
69
+ return {
70
+ headers: entry.headers,
71
+ body: entry.data,
72
+ fromCache: true,
73
+ cacheHitType: 'spec-ttl',
74
+ };
75
+ }
76
+ return null;
77
+ }
41
78
  const parseCacheControlTtl = (headers) => {
42
- const cacheControl = headers['cache-control'] || headers['Cache-Control'];
79
+ const cacheControl = headers['cache-control'] ?? headers['Cache-Control'];
43
80
  if (!cacheControl)
44
81
  return undefined;
45
82
  const match = /max-age=(\d+)/.exec(cacheControl);
@@ -89,6 +126,7 @@ function handleEarlyStatus(client, status, url, parsed, useETag) {
89
126
  headers: { ...cachedEntry.headers, ...parsed.raw },
90
127
  body: cachedEntry.data,
91
128
  fromCache: true,
129
+ cacheHitType: 'etag-304',
92
130
  };
93
131
  }
94
132
  }
@@ -108,6 +146,7 @@ function tryStaleCacheResponse(client, url, parsed) {
108
146
  body: cachedEntry.data,
109
147
  fromCache: true,
110
148
  stale: true,
149
+ cacheHitType: 'stale-on-error',
111
150
  };
112
151
  }
113
152
  function cacheResponse(client, url, method, endpoint, parsed, data, useETag) {
@@ -141,7 +180,7 @@ function handleCursorPagination(parsed, data) {
141
180
  };
142
181
  return { headers: parsed.raw, body: data, cursors };
143
182
  }
144
- async function handleOffsetPagination(client, endpoint, method, requiresAuth, parsed, data, body, url, useETag, pageFetch) {
183
+ async function handleOffsetPagination(client, endpoint, method, requiresAuth, parsed, data, body, url, useETag, pageFetch, templatePath) {
145
184
  const totalPages = parsed.xPages;
146
185
  if (totalPages <= 1) {
147
186
  return { headers: parsed.raw, body: data };
@@ -153,7 +192,7 @@ async function handleOffsetPagination(client, endpoint, method, requiresAuth, pa
153
192
  maxPages: Math.min(totalPages, 1000),
154
193
  stopOnEmptyPage: true,
155
194
  maxRetries: 3,
156
- }, pageFetch);
195
+ }, pageFetch, templatePath);
157
196
  cacheResponse(client, url, method, endpoint, parsed, allData, useETag);
158
197
  return { headers: parsed.raw, body: allData };
159
198
  }
@@ -222,7 +261,7 @@ function handleErrorResponse(client, response, url, parsed, useETag) {
222
261
  throw new error_1.EsiError(response.status, errorMessage, url, parsed.requestId ?? undefined);
223
262
  }
224
263
  function wrapError(error) {
225
- if (error instanceof error_1.EsiError) {
264
+ if (error instanceof error_1.EsiError || error instanceof CircuitBreaker_1.CircuitOpenError) {
226
265
  throw error;
227
266
  }
228
267
  if (error instanceof Error) {
@@ -232,7 +271,7 @@ function wrapError(error) {
232
271
  (0, loggerUtil_1.logError)(`Unexpected error: ${String(error)}`);
233
272
  throw (0, error_1.buildError)(String(error), 'ESIJS_ERROR');
234
273
  }
235
- async function executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag) {
274
+ async function executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag, requestTimeout, templatePath) {
236
275
  const rawUrl = `${client.getLink()}/${endpoint}`;
237
276
  const builtHeaders = buildRequestHeaders(client, rawUrl, method, requiresAuth, useETag, body);
238
277
  const req = await applyRequestMiddleware(client, rawUrl, endpoint, method, builtHeaders, body);
@@ -247,8 +286,8 @@ async function executeSingleFetch(client, endpoint, method, body, requiresAuth,
247
286
  if (cb)
248
287
  cb.checkCircuit(endpoint);
249
288
  const rateLimiter = resolveRateLimiter(client);
250
- await rateLimiter.checkRateLimit();
251
- const timeoutMs = client.getTimeout();
289
+ await rateLimiter.checkRateLimit(templatePath, method, req.headers);
290
+ const timeoutMs = requestTimeout ?? client.getTimeout();
252
291
  const controller = new AbortController();
253
292
  const timer = globalThis.setTimeout(() => controller.abort(), timeoutMs);
254
293
  options.signal = controller.signal;
@@ -259,13 +298,13 @@ async function executeSingleFetch(client, endpoint, method, body, requiresAuth,
259
298
  catch (err) {
260
299
  clearTimeout(timer);
261
300
  if (err instanceof Error && err.name === 'AbortError') {
262
- throw new error_1.EsiError(0, `Request timed out after ${timeoutMs}ms`, url);
301
+ throw new error_1.TimeoutError(timeoutMs, url);
263
302
  }
264
303
  throw err;
265
304
  }
266
305
  clearTimeout(timer);
267
306
  const parsed = (0, headersUtil_1.parseHeaders)(response.headers);
268
- rateLimiter.updateFromResponse(parsed.raw, response.status);
307
+ rateLimiter.updateFromResponse(parsed.raw, response.status, templatePath, method, req.headers);
269
308
  if (cb) {
270
309
  if (response.status >= 500 ||
271
310
  response.status === 420 ||
@@ -281,22 +320,23 @@ async function executeSingleFetch(client, endpoint, method, body, requiresAuth,
281
320
  }
282
321
  return { response, parsed, url };
283
322
  }
284
- async function fetchOnePage(client, endpoint, method, body, requiresAuth = false, useETag = false) {
285
- const { response, parsed, url } = await executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag);
323
+ async function fetchOnePage(client, endpoint, method, body, requiresAuth = false, useETag = false, requestTimeout, templatePath) {
324
+ const { response, parsed, url } = await executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag, requestTimeout, templatePath);
286
325
  if (!response.ok) {
287
326
  throw new error_1.EsiError(response.status, STATUS_MESSAGES[response.status] || response.statusText, url, parsed.requestId ?? undefined);
288
327
  }
289
328
  const data = await parseJsonBody(response, url);
290
329
  return { data, parsed, url };
291
330
  }
292
- const executeRequest = async (client, endpoint, method, body, requiresAuth = false, useETag = true) => {
331
+ const executeRequest = async (client, endpoint, method, body, requiresAuth = false, useETag = true, requestTimeout, templatePath) => {
293
332
  const startTime = Date.now();
294
333
  const finish = (r) => {
334
+ r.responseTimeMs = Date.now() - startTime;
295
335
  const rawUrl = `${client.getLink()}/${endpoint}`;
296
336
  return applyResponseInterceptors(client, r, rawUrl, endpoint, method, startTime);
297
337
  };
298
338
  try {
299
- const { response, parsed, url } = await executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag);
339
+ const { response, parsed, url } = await executeSingleFetch(client, endpoint, method, body, requiresAuth, useETag, requestTimeout, templatePath);
300
340
  if (response.status === 201) {
301
341
  let data;
302
342
  try {
@@ -320,50 +360,76 @@ const executeRequest = async (client, endpoint, method, body, requiresAuth = fal
320
360
  if (cursorResult)
321
361
  return finish(cursorResult);
322
362
  const pageFetch = async (paginatedEndpoint) => {
323
- const result = await fetchOnePage(client, paginatedEndpoint, method, body, requiresAuth);
363
+ const result = await fetchOnePage(client, paginatedEndpoint, method, body, requiresAuth, false, requestTimeout, templatePath);
324
364
  return Array.isArray(result.data)
325
365
  ? result.data
326
366
  : [result.data];
327
367
  };
328
- const paginatedResult = await handleOffsetPagination(client, endpoint, method, requiresAuth, parsed, data, body, url, useETag, pageFetch);
368
+ const paginatedResult = await handleOffsetPagination(client, endpoint, method, requiresAuth, parsed, data, body, url, useETag, pageFetch, templatePath);
329
369
  return finish(paginatedResult);
330
370
  }
331
371
  catch (error) {
332
372
  wrapError(error);
333
373
  }
334
374
  };
335
- const handleRequest = async (client, endpoint, method, body, requiresAuth = false, useETag = true) => {
336
- const doExecute = () => executeRequest(client, endpoint, method, body, requiresAuth, useETag);
375
+ const handleRequest = async (client, endpoint, method, body, requiresAuth = false, useETag = true, templatePath, requestTimeout) => {
376
+ const rawUrl = `${client.getLink()}/${endpoint}`;
377
+ const specHit = trySpecAwareCacheHit(client, rawUrl, method, templatePath);
378
+ if (specHit)
379
+ return specHit;
380
+ const doExecute = () => executeRequest(client, endpoint, method, body, requiresAuth, useETag, requestTimeout, templatePath);
337
381
  const dedup = client.getDeduplicator();
338
382
  const canDedup = dedup && method === 'GET' && !body;
339
- try {
340
- return canDedup
341
- ? await dedup.dedupe(endpoint, doExecute)
342
- : await doExecute();
343
- }
344
- catch (error) {
345
- if (error instanceof error_1.EsiError &&
346
- error.statusCode === 401 &&
347
- requiresAuth &&
348
- client.hasTokenProvider()) {
349
- (0, loggerUtil_1.logInfo)('Received 401, attempting token refresh...');
350
- try {
351
- await client.refreshToken();
352
- (0, loggerUtil_1.logInfo)('Token refreshed, retrying request');
353
- return await executeRequest(client, endpoint, method, body, requiresAuth, useETag);
383
+ const retryConfig = client.getRetryConfig();
384
+ const maxRetries = retryConfig?.maxRetries ?? 0;
385
+ const canRetryMethod = method === 'GET' || retryConfig?.retryMutations === true;
386
+ const baseDelayMs = retryConfig?.baseDelayMs ?? 1000;
387
+ const maxDelayMs = retryConfig?.maxDelayMs ?? 30000;
388
+ let lastError;
389
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
390
+ try {
391
+ return canDedup
392
+ ? await dedup.dedupe(endpoint, doExecute)
393
+ : await doExecute();
394
+ }
395
+ catch (error) {
396
+ if (error instanceof CircuitBreaker_1.CircuitOpenError) {
397
+ throw error;
354
398
  }
355
- catch (refreshError) {
356
- if (refreshError instanceof error_1.EsiError) {
357
- throw refreshError;
399
+ if (error instanceof error_1.EsiError &&
400
+ error.statusCode === 401 &&
401
+ requiresAuth &&
402
+ client.hasTokenProvider()) {
403
+ (0, loggerUtil_1.logInfo)('Received 401, attempting token refresh...');
404
+ try {
405
+ await client.refreshToken();
406
+ (0, loggerUtil_1.logInfo)('Token refreshed, retrying request');
407
+ return await executeRequest(client, endpoint, method, body, requiresAuth, useETag, requestTimeout);
408
+ }
409
+ catch (refreshError) {
410
+ if (refreshError instanceof error_1.EsiError) {
411
+ throw refreshError;
412
+ }
413
+ const msg = refreshError instanceof Error
414
+ ? refreshError.message
415
+ : String(refreshError);
416
+ (0, loggerUtil_1.logError)(`Token refresh failed: ${msg}`);
417
+ throw (0, error_1.buildError)(`Token refresh failed: ${msg}`, 'TOKEN_REFRESH_FAILED');
358
418
  }
359
- const msg = refreshError instanceof Error
360
- ? refreshError.message
361
- : String(refreshError);
362
- (0, loggerUtil_1.logError)(`Token refresh failed: ${msg}`);
363
- throw (0, error_1.buildError)(`Token refresh failed: ${msg}`, 'TOKEN_REFRESH_FAILED');
364
419
  }
420
+ if (error instanceof error_1.EsiError &&
421
+ error.retryable &&
422
+ canRetryMethod &&
423
+ attempt < maxRetries) {
424
+ const delay = (0, retry_1.retryDelay)(attempt, baseDelayMs, maxDelayMs);
425
+ (0, loggerUtil_1.logWarn)(`Request to ${endpoint} failed (${error.statusCode}), retrying in ${Math.round(delay)}ms (attempt ${attempt + 1}/${maxRetries})`);
426
+ await (0, sleep_1.sleep)(delay);
427
+ lastError = error;
428
+ continue;
429
+ }
430
+ throw error;
365
431
  }
366
- throw error;
367
432
  }
433
+ throw lastError;
368
434
  };
369
435
  exports.handleRequest = handleRequest;
@@ -0,0 +1,12 @@
1
+ import { EsiError } from './util/error';
2
+ export interface BatchOptions {
3
+ concurrency?: number;
4
+ onProgress?: (completed: number, total: number) => void;
5
+ }
6
+ export interface BatchResult<K, T> {
7
+ results: Map<K, T>;
8
+ errors: Map<K, EsiError | Error>;
9
+ }
10
+ export declare function batchFetch<K, T>(keys: K[], fetcher: (key: K) => Promise<T>, options?: BatchOptions): Promise<BatchResult<K, T>>;
11
+ export declare function batchPost<T>(ids: number[], poster: (chunk: number[]) => Promise<T[]>, chunkSize?: number): Promise<T[]>;
12
+ //# sourceMappingURL=BatchRequestHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BatchRequestHandler.d.ts","sourceRoot":"","sources":["../../src/core/BatchRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzD;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,CAAC;CAClC;AAED,wBAAsB,UAAU,CAAC,CAAC,EAAE,CAAC,EACnC,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/B,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAqD5B;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EAAE,EACb,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,EACzC,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAiBd"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.batchFetch = batchFetch;
4
+ exports.batchPost = batchPost;
5
+ const error_1 = require("./util/error");
6
+ const loggerUtil_1 = require("./logger/loggerUtil");
7
+ async function batchFetch(keys, fetcher, options = {}) {
8
+ const concurrency = options.concurrency ?? 20;
9
+ const results = new Map();
10
+ const errors = new Map();
11
+ let completed = 0;
12
+ let running = 0;
13
+ let index = 0;
14
+ (0, loggerUtil_1.logInfo)(`Batch fetch: ${keys.length} items, concurrency=${concurrency}`);
15
+ return new Promise((resolve) => {
16
+ function next() {
17
+ while (running < concurrency && index < keys.length) {
18
+ const currentIndex = index++;
19
+ const key = keys[currentIndex];
20
+ running++;
21
+ fetcher(key)
22
+ .then((result) => {
23
+ results.set(key, result);
24
+ })
25
+ .catch((err) => {
26
+ const error = err instanceof error_1.EsiError || err instanceof Error
27
+ ? err
28
+ : new Error(String(err));
29
+ errors.set(key, error);
30
+ })
31
+ .finally(() => {
32
+ running--;
33
+ completed++;
34
+ if (options.onProgress) {
35
+ options.onProgress(completed, keys.length);
36
+ }
37
+ if (completed === keys.length) {
38
+ (0, loggerUtil_1.logDebug)(`Batch complete: ${results.size} succeeded, ${errors.size} failed`);
39
+ resolve({ results, errors });
40
+ }
41
+ else {
42
+ next();
43
+ }
44
+ });
45
+ }
46
+ }
47
+ if (keys.length === 0) {
48
+ resolve({ results, errors });
49
+ return;
50
+ }
51
+ next();
52
+ });
53
+ }
54
+ async function batchPost(ids, poster, chunkSize = 1000) {
55
+ const chunks = [];
56
+ for (let i = 0; i < ids.length; i += chunkSize) {
57
+ chunks.push(ids.slice(i, i + chunkSize));
58
+ }
59
+ (0, loggerUtil_1.logInfo)(`Batch POST: ${ids.length} IDs in ${chunks.length} chunks of ${chunkSize}`);
60
+ const results = [];
61
+ for (const chunk of chunks) {
62
+ const chunkResult = await poster(chunk);
63
+ results.push(...chunkResult);
64
+ }
65
+ return results;
66
+ }
@@ -1,5 +1,5 @@
1
1
  export declare const PACKAGE_NAME = "esi.ts";
2
- export declare const PACKAGE_VERSION = "5.0.0";
3
- export declare const USER_AGENT = "esi.ts/5.0.0";
2
+ export declare const PACKAGE_VERSION = "5.2.0";
3
+ export declare const USER_AGENT = "esi.ts/5.2.0";
4
4
  export declare const COMPATIBILITY_DATE = "2026-05-19";
5
5
  //# sourceMappingURL=constants.d.ts.map
@@ -2,6 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.COMPATIBILITY_DATE = exports.USER_AGENT = exports.PACKAGE_VERSION = exports.PACKAGE_NAME = void 0;
4
4
  exports.PACKAGE_NAME = 'esi.ts';
5
- exports.PACKAGE_VERSION = '5.0.0';
5
+ exports.PACKAGE_VERSION = '5.2.0';
6
6
  exports.USER_AGENT = `${exports.PACKAGE_NAME}/${exports.PACKAGE_VERSION}`;
7
7
  exports.COMPATIBILITY_DATE = '2026-05-19';
@@ -1 +1 @@
1
- {"version":3,"file":"createClient.d.ts","sourceRoot":"","sources":["../../../src/core/endpoints/createClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAmB,MAAM,2BAA2B,CAAC;AAKzE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,KAAK,aAAa,CAAC,CAAC,SAAS,WAAW,IAAI;KACzC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KAC3B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAC/D,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACvC,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AAmBF,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,EAChD,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,CAAC,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC5B,aAAa,CAAC,CAAC,CAAC,CA8HlB;AAGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,KAAK,GAAG,OAAO,EAClE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,EAChE,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,KAAK,EAAE,EAC1C,SAAS,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GACA,OAAO,CAAC,KAAK,EAAE,CAAC,CA0BlB"}
1
+ {"version":3,"file":"createClient.d.ts","sourceRoot":"","sources":["../../../src/core/endpoints/createClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAmB,MAAM,2BAA2B,CAAC;AAKzE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,KAAK,aAAa,CAAC,CAAC,SAAS,WAAW,IAAI;KACzC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KAC3B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAC/D,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACvC,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AA8BF,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,EAChD,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,CAAC,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC5B,aAAa,CAAC,CAAC,CAAC,CAkIlB;AAGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,KAAK,GAAG,OAAO,EAClE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,EAChE,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,KAAK,EAAE,EAC1C,SAAS,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GACA,OAAO,CAAC,KAAK,EAAE,CAAC,CA0BlB"}
@@ -12,6 +12,10 @@ function buildMeta(response) {
12
12
  fromCache: response.fromCache ?? false,
13
13
  stale: response.stale ?? false,
14
14
  };
15
+ if (response.cacheHitType)
16
+ meta.cacheHitType = response.cacheHitType;
17
+ if (response.responseTimeMs !== undefined)
18
+ meta.responseTimeMs = response.responseTimeMs;
15
19
  const w = (0, headersUtil_1.parseWarning)(response.headers['warning']);
16
20
  if (w)
17
21
  meta.warning = w;
@@ -21,6 +25,14 @@ function buildMeta(response) {
21
25
  meta.date = response.headers['date'];
22
26
  if (response.headers['content-language'])
23
27
  meta.contentLanguage = response.headers['content-language'];
28
+ if (response.headers['x-ratelimit-remaining']) {
29
+ meta.rateLimit = {
30
+ remaining: parseInt(response.headers['x-ratelimit-remaining'], 10),
31
+ limit: parseInt(response.headers['x-ratelimit-limit'] ?? '0', 10),
32
+ used: parseInt(response.headers['x-ratelimit-used'] ?? '0', 10),
33
+ group: response.headers['x-ratelimit-group'] ?? null,
34
+ };
35
+ }
24
36
  return meta;
25
37
  }
26
38
  /* eslint-disable sonarjs/cognitive-complexity */
@@ -96,7 +108,7 @@ function createClient(apiClient, endpoints, options) {
96
108
  path += (path.includes('?') ? '&' : '?') + parts.join('&');
97
109
  }
98
110
  }
99
- const response = await (0, ApiRequestHandler_1.handleRequest)(apiClient, path, def.method, body, def.requiresAuth);
111
+ const response = await (0, ApiRequestHandler_1.handleRequest)(apiClient, path, def.method, body, def.requiresAuth, true, def.path);
100
112
  const responseBody = response.body;
101
113
  let data;
102
114
  if (Array.isArray(responseBody)) {
@@ -117,7 +129,7 @@ function createClient(apiClient, endpoints, options) {
117
129
  }
118
130
  return cursorResult;
119
131
  }
120
- const response = await (0, ApiRequestHandler_1.handleRequest)(apiClient, path, def.method, body, def.requiresAuth);
132
+ const response = await (0, ApiRequestHandler_1.handleRequest)(apiClient, path, def.method, body, def.requiresAuth, true, def.path);
121
133
  if (returnMetadata) {
122
134
  return { data: response.body, meta: buildMeta(response) };
123
135
  }
@@ -0,0 +1,2 @@
1
+ export declare const esiCacheTtls: Record<string, number>;
2
+ //# sourceMappingURL=esi-cache-ttls.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esi-cache-ttls.generated.d.ts","sourceRoot":"","sources":["../../../src/core/endpoints/esi-cache-ttls.generated.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwH/C,CAAC"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ // Auto-generated from ESI Swagger spec — do not edit manually
3
+ // Endpoints with cache TTLs: 119
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.esiCacheTtls = void 0;
6
+ exports.esiCacheTtls = {
7
+ 'GET:alliances': 3600,
8
+ 'GET:alliances/{alliance_id}': 3600,
9
+ 'GET:alliances/{alliance_id}/contacts': 300,
10
+ 'GET:alliances/{alliance_id}/contacts/labels': 300,
11
+ 'GET:alliances/{alliance_id}/corporations': 3600,
12
+ 'GET:characters/{character_id}': 604800,
13
+ 'GET:characters/{character_id}/agents_research': 3600,
14
+ 'GET:characters/{character_id}/assets': 3600,
15
+ 'GET:characters/{character_id}/attributes': 120,
16
+ 'GET:characters/{character_id}/blueprints': 3600,
17
+ 'GET:characters/{character_id}/calendar': 5,
18
+ 'GET:characters/{character_id}/calendar/{event_id}': 5,
19
+ 'PUT:characters/{character_id}/calendar/{event_id}': 5,
20
+ 'GET:characters/{character_id}/calendar/{event_id}/attendees': 600,
21
+ 'GET:characters/{character_id}/clones': 120,
22
+ 'GET:characters/{character_id}/contacts': 300,
23
+ 'GET:characters/{character_id}/contacts/labels': 300,
24
+ 'GET:characters/{character_id}/contracts': 300,
25
+ 'GET:characters/{character_id}/contracts/{contract_id}/bids': 300,
26
+ 'GET:characters/{character_id}/contracts/{contract_id}/items': 3600,
27
+ 'GET:characters/{character_id}/corporationhistory': 86400,
28
+ 'GET:characters/{character_id}/fatigue': 300,
29
+ 'GET:characters/{character_id}/fittings': 300,
30
+ 'GET:characters/{character_id}/fleet': 60,
31
+ 'GET:characters/{character_id}/implants': 120,
32
+ 'GET:characters/{character_id}/industry/jobs': 300,
33
+ 'GET:characters/{character_id}/killmails/recent': 300,
34
+ 'GET:characters/{character_id}/location': 5,
35
+ 'GET:characters/{character_id}/loyalty/points': 3600,
36
+ 'GET:characters/{character_id}/mail': 30,
37
+ 'GET:characters/{character_id}/mail/{mail_id}': 30,
38
+ 'GET:characters/{character_id}/mail/labels': 30,
39
+ 'GET:characters/{character_id}/mail/lists': 120,
40
+ 'GET:characters/{character_id}/medals': 3600,
41
+ 'GET:characters/{character_id}/mining': 600,
42
+ 'GET:characters/{character_id}/notifications': 600,
43
+ 'GET:characters/{character_id}/notifications/contacts': 600,
44
+ 'GET:characters/{character_id}/online': 60,
45
+ 'GET:characters/{character_id}/orders': 1200,
46
+ 'GET:characters/{character_id}/orders/history': 3600,
47
+ 'GET:characters/{character_id}/planets': 600,
48
+ 'GET:characters/{character_id}/roles': 3600,
49
+ 'GET:characters/{character_id}/search': 3600,
50
+ 'GET:characters/{character_id}/ship': 5,
51
+ 'GET:characters/{character_id}/skillqueue': 120,
52
+ 'GET:characters/{character_id}/skills': 120,
53
+ 'GET:characters/{character_id}/standings': 3600,
54
+ 'GET:characters/{character_id}/titles': 3600,
55
+ 'GET:characters/{character_id}/wallet': 120,
56
+ 'GET:characters/{character_id}/wallet/journal': 3600,
57
+ 'GET:characters/{character_id}/wallet/transactions': 3600,
58
+ 'POST:characters/affiliation': 3600,
59
+ 'GET:contracts/public/{region_id}': 1800,
60
+ 'GET:contracts/public/bids/{contract_id}': 300,
61
+ 'GET:contracts/public/items/{contract_id}': 3600,
62
+ 'GET:corporation/{corporation_id}/mining/extractions': 1800,
63
+ 'GET:corporation/{corporation_id}/mining/observers': 3600,
64
+ 'GET:corporation/{corporation_id}/mining/observers/{observer_id}': 3600,
65
+ 'GET:corporations/{corporation_id}': 3600,
66
+ 'GET:corporations/{corporation_id}/alliancehistory': 3600,
67
+ 'GET:corporations/{corporation_id}/assets': 3600,
68
+ 'GET:corporations/{corporation_id}/blueprints': 3600,
69
+ 'GET:corporations/{corporation_id}/contacts': 300,
70
+ 'GET:corporations/{corporation_id}/contacts/labels': 300,
71
+ 'GET:corporations/{corporation_id}/containers/logs': 600,
72
+ 'GET:corporations/{corporation_id}/contracts': 300,
73
+ 'GET:corporations/{corporation_id}/contracts/{contract_id}/bids': 3600,
74
+ 'GET:corporations/{corporation_id}/contracts/{contract_id}/items': 3600,
75
+ 'GET:corporations/{corporation_id}/customs_offices': 3600,
76
+ 'GET:corporations/{corporation_id}/divisions': 3600,
77
+ 'GET:corporations/{corporation_id}/facilities': 3600,
78
+ 'GET:corporations/{corporation_id}/icons': 3600,
79
+ 'GET:corporations/{corporation_id}/industry/jobs': 300,
80
+ 'GET:corporations/{corporation_id}/killmails/recent': 300,
81
+ 'GET:corporations/{corporation_id}/medals': 3600,
82
+ 'GET:corporations/{corporation_id}/medals/issued': 3600,
83
+ 'GET:corporations/{corporation_id}/members': 3600,
84
+ 'GET:corporations/{corporation_id}/members/limit': 3600,
85
+ 'GET:corporations/{corporation_id}/members/titles': 3600,
86
+ 'GET:corporations/{corporation_id}/membertracking': 3600,
87
+ 'GET:corporations/{corporation_id}/orders': 1200,
88
+ 'GET:corporations/{corporation_id}/orders/history': 3600,
89
+ 'GET:corporations/{corporation_id}/roles': 3600,
90
+ 'GET:corporations/{corporation_id}/roles/history': 3600,
91
+ 'GET:corporations/{corporation_id}/shareholders': 3600,
92
+ 'GET:corporations/{corporation_id}/standings': 3600,
93
+ 'GET:corporations/{corporation_id}/starbases': 3600,
94
+ 'GET:corporations/{corporation_id}/starbases/{starbase_id}': 3600,
95
+ 'GET:corporations/{corporation_id}/structures': 3600,
96
+ 'GET:corporations/{corporation_id}/titles': 3600,
97
+ 'GET:corporations/{corporation_id}/wallets': 300,
98
+ 'GET:corporations/{corporation_id}/wallets/{division}/journal': 3600,
99
+ 'GET:corporations/{corporation_id}/wallets/{division}/transactions': 3600,
100
+ 'GET:fleets/{fleet_id}': 5,
101
+ 'GET:fleets/{fleet_id}/members': 5,
102
+ 'GET:fleets/{fleet_id}/wings': 5,
103
+ 'GET:fw/systems': 1800,
104
+ 'GET:incursions': 300,
105
+ 'GET:industry/facilities': 3600,
106
+ 'GET:industry/systems': 3600,
107
+ 'GET:insurance/prices': 3600,
108
+ 'GET:killmails/{killmail_id}/{killmail_hash}': 30758400,
109
+ 'GET:markets/{region_id}/orders': 300,
110
+ 'GET:markets/{region_id}/types': 600,
111
+ 'GET:markets/prices': 3600,
112
+ 'GET:markets/structures/{structure_id}': 300,
113
+ 'GET:route/{origin}/{destination}': 86400,
114
+ 'GET:sovereignty/campaigns': 5,
115
+ 'GET:sovereignty/map': 3600,
116
+ 'GET:sovereignty/structures': 120,
117
+ 'GET:status': 30,
118
+ 'GET:universe/schematics/{schematic_id}': 3600,
119
+ 'GET:universe/structures': 3600,
120
+ 'GET:universe/structures/{structure_id}': 3600,
121
+ 'GET:universe/system_jumps': 3600,
122
+ 'GET:universe/system_kills': 3600,
123
+ 'GET:wars': 3600,
124
+ 'GET:wars/{war_id}': 3600,
125
+ 'GET:wars/{war_id}/killmails': 3600,
126
+ };
@@ -0,0 +1,7 @@
1
+ export interface RateLimitGroupSpec {
2
+ group: string;
3
+ maxTokens: number;
4
+ windowSizeMs: number;
5
+ }
6
+ export declare const esiRateLimitGroups: Record<string, RateLimitGroupSpec>;
7
+ //# sourceMappingURL=esi-rate-limit-groups.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esi-rate-limit-groups.generated.d.ts","sourceRoot":"","sources":["../../../src/core/endpoints/esi-rate-limit-groups.generated.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAmJjE,CAAC"}