@lgriffin/esi.ts 6.0.0 → 6.1.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 (52) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +224 -152
  3. package/dist/clients/ContactsClient.d.ts +6 -4
  4. package/dist/clients/ContactsClient.d.ts.map +1 -1
  5. package/dist/clients/ContactsClient.js +9 -7
  6. package/dist/clients/FleetClient.d.ts +2 -2
  7. package/dist/clients/FleetClient.d.ts.map +1 -1
  8. package/dist/clients/FleetClient.js +8 -2
  9. package/dist/clients/SovereigntyClient.d.ts +1 -1
  10. package/dist/clients/SovereigntyClient.d.ts.map +1 -1
  11. package/dist/clients/UiClient.d.ts +11 -9
  12. package/dist/clients/UiClient.d.ts.map +1 -1
  13. package/dist/clients/UiClient.js +15 -13
  14. package/dist/core/endpoints/EndpointDefinition.d.ts +12 -4
  15. package/dist/core/endpoints/EndpointDefinition.d.ts.map +1 -1
  16. package/dist/core/endpoints/assetEndpoints.d.ts +1 -0
  17. package/dist/core/endpoints/assetEndpoints.d.ts.map +1 -1
  18. package/dist/core/endpoints/contactEndpoints.d.ts +11 -3
  19. package/dist/core/endpoints/contactEndpoints.d.ts.map +1 -1
  20. package/dist/core/endpoints/contactEndpoints.js +5 -3
  21. package/dist/core/endpoints/factionEndpoints.d.ts +2 -2
  22. package/dist/core/endpoints/fittingEndpoints.d.ts +1 -1
  23. package/dist/core/endpoints/freelanceJobsEndpoints.d.ts +8 -8
  24. package/dist/core/endpoints/mailEndpoints.d.ts +2 -0
  25. package/dist/core/endpoints/mailEndpoints.d.ts.map +1 -1
  26. package/dist/core/endpoints/sovereigntyEndpoints.d.ts +30 -16
  27. package/dist/core/endpoints/sovereigntyEndpoints.d.ts.map +1 -1
  28. package/dist/core/endpoints/sovereigntyEndpoints.js +1 -1
  29. package/dist/core/endpoints/uiEndpoints.d.ts +14 -4
  30. package/dist/core/endpoints/uiEndpoints.d.ts.map +1 -1
  31. package/dist/core/endpoints/uiEndpoints.js +8 -4
  32. package/dist/core/endpoints/universeEndpoints.d.ts +1 -1
  33. package/dist/schemas/assets.d.ts +1 -0
  34. package/dist/schemas/assets.d.ts.map +1 -1
  35. package/dist/schemas/assets.js +1 -1
  36. package/dist/schemas/faction-warfare.d.ts +2 -2
  37. package/dist/schemas/faction-warfare.js +2 -2
  38. package/dist/schemas/fittings.d.ts +1 -1
  39. package/dist/schemas/fittings.js +1 -1
  40. package/dist/schemas/freelance-jobs.d.ts +8 -8
  41. package/dist/schemas/freelance-jobs.js +5 -5
  42. package/dist/schemas/mail.d.ts +1 -0
  43. package/dist/schemas/mail.d.ts.map +1 -1
  44. package/dist/schemas/mail.js +1 -0
  45. package/dist/schemas/sovereignty.d.ts +28 -14
  46. package/dist/schemas/sovereignty.d.ts.map +1 -1
  47. package/dist/schemas/sovereignty.js +35 -8
  48. package/dist/schemas/universe.d.ts +1 -1
  49. package/dist/schemas/universe.js +1 -1
  50. package/dist/testing/TestDataFactory.d.ts.map +1 -1
  51. package/dist/testing/TestDataFactory.js +16 -10
  52. package/package.json +15 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [6.1.0] - 2026-07-07
11
+
12
+ ### Added
13
+
14
+ - **Fleet wing/squad name validation** — `renameFleetWing()` and `renameFleetSquad()` now reject names exceeding ESI's 10-character limit before sending the request, with a clear error message
15
+ - **43 runnable example scripts** covering all 210 ESI endpoints against live Tranquility (10 new example files: character-details, corporation-details, calendar-search, loyalty-pi, faction-details, industry-mining, market-orders, universe-encyclopedia, corp-contracts-wallet, dogma-meta-sov)
16
+ - **3 write-operation example scripts** — `write-operations.ts` (contacts, fittings, mail, UI lifecycle), `universe-post-helpers.ts` (name resolution, affiliation), `freelance-jobs.ts` (cursor-paginated queries)
17
+ - Live output captured for all example scripts in `examples/output/`
18
+ - 3 new TDD test files and 1 new BDD feature file (81 TDD files, 40 BDD features total)
19
+ - 2 new fleet validation unit tests
20
+
21
+ ### Fixed
22
+
23
+ - **Fleet test babel parse errors** — replaced TypeScript cast syntax `(result as any[]).forEach(...)` with direct index access in fleet tests (pre-existing bug unmasked by stricter transpilation)
24
+ - **Fleet rename test names** — test mock names shortened to respect ESI's 10-character limit (`'New Squad Name'` → `'New Squad'`)
25
+
26
+ ### Changed
27
+
28
+ - README rewritten with "Why ESI.ts vs. OpenAPI-generated clients" comparison, full endpoint coverage table, and updated architecture/testing references
29
+ - `guides/ARCHITECTURE.md`, `guides/TESTING.md`, and `TESTING.md` updated to current test counts (121 suites, 3,224 tests)
30
+ - Autopilot example waypoint changed from Jita to Rens
31
+
32
+ ### Schemas
33
+
34
+ - Multiple Zod schema fixes discovered during live endpoint validation: added missing enum values, corrected optional fields, and adjusted types to match actual ESI responses
35
+
10
36
  ## [6.0.0] - 2026-07-03
11
37
 
12
38
  ### Added
package/README.md CHANGED
@@ -8,17 +8,44 @@
8
8
  [![Coverage](https://img.shields.io/badge/coverage-65%25%2B-brightgreen)](https://github.com/lgriffin/ESI.ts)
9
9
  [![npm downloads](https://img.shields.io/npm/dm/%40lgriffin/esi.ts)](https://www.npmjs.com/package/@lgriffin/esi.ts)
10
10
 
11
- A type-safe TypeScript client for the [EVE Online ESI API](https://esi.evetech.net/).
12
-
13
- - Typed responses for all endpoints with **runtime validation** via Zod schemas
14
- - Spec-driven type generation from ESI swagger spec (147 interfaces)
15
- - ETag caching with Cache-Control TTL, stale-on-error, and write invalidation
16
- - Spec-aware cache TTLs — zero-request cache hits within ESI-specified windows
17
- - Batch requests with bounded concurrency and auto-chunking
18
- - Automatic offset-based pagination, cursor-based pagination, and streaming pagination support
19
- - Rate limiting with header-driven backoff
20
- - Automatic token refresh with 401 retry and concurrent coalescing
21
- - 35 domain clients covering the full ESI surface
11
+ A production-grade TypeScript client for the [EVE Online ESI API](https://esi.evetech.net/), with runtime validation, intelligent caching, and full endpoint coverage.
12
+
13
+ **All 210 ESI endpoints are defined, tested, and validated against live Tranquility.**
14
+
15
+ ## Why ESI.ts vs. OpenAPI-Generated Clients?
16
+
17
+ Tools like `openapi-typescript` or `openapi-generator` can produce a typed client from the ESI swagger spec in minutes. They're a reasonable starting point — but they stop at type generation. ESI.ts is a purpose-built SDK that handles the problems you hit _after_ the types compile.
18
+
19
+ ### What generators give you
20
+
21
+ - TypeScript interfaces from the swagger spec
22
+ - Basic request/response typing
23
+ - A thin HTTP wrapper
24
+
25
+ ### What ESI.ts gives you on top of that
26
+
27
+ | Capability | openapi-typescript | ESI.ts |
28
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
29
+ | **Runtime response validation** | None — types are erased at compile time. If CCP changes a field, you get silent data corruption. | Every response is validated at runtime via [Zod](https://zod.dev/) schemas (146 of 210 endpoints). Schema mismatches throw `EsiValidationError` immediately. |
30
+ | **Intelligent caching** | None — you build your own. | Three-tier: spec-aware TTL (zero HTTP calls within ESI's `x-cached-seconds` window), ETag conditional GETs, stale-on-error fallback on 5xx. Write operations auto-invalidate related GET caches. |
31
+ | **Rate limiting** | None — you build your own. | 36 per-group token buckets extracted from the ESI spec at build time. Market requests can't starve wallet requests. Optional per-user bucketing for multi-character apps. |
32
+ | **Pagination** | Manual — you write the page loop. | Automatic offset pagination, cursor-based pagination (Equinox-era endpoints), and streaming `AsyncGenerator` pagination for memory-efficient processing of large datasets. |
33
+ | **Retry & resilience** | None. | Exponential backoff with jitter, circuit breaker (closed/open/half-open), automatic 401 token refresh with concurrent coalescing. |
34
+ | **Wire format correctness** | Generates from spec, but ESI's spec has inconsistencies (query params documented as body, missing required fields). | Every endpoint tested against live ESI. Wire format bugs (query params vs. body, field naming) are caught and fixed — see the contacts and UI endpoint fixes in v6.1.0. |
35
+ | **Batch operations** | None. | `batch()` with bounded concurrency for GET fan-out, `batchPost()` with auto-chunking for large POST payloads. |
36
+ | **Domain knowledge** | None — generic HTTP client. | 35 domain clients with typed methods, JSDoc documentation, and input validation (e.g., fleet wing/squad names are capped at 10 characters before hitting the API). |
37
+ | **Testing** | Whatever you write. | 121 test suites, 3,224 tests across 7 tiers (TDD unit, BDD behavioral, mocked integration, live smoke, client integration, ESI spec contract, gated auth). 43 runnable example scripts with live output. |
38
+
39
+ ### The real problem with generated clients
40
+
41
+ The ESI swagger spec is not a perfect source of truth. During live endpoint validation, we discovered:
42
+
43
+ - `addContacts`, `editContacts`, and 4 UI endpoints document parameters as request body when ESI actually expects query parameters
44
+ - `deleteCharacterContacts` expects comma-separated contact IDs as a query param, not a JSON body
45
+ - Fleet wing/squad names have a 10-character limit not documented in the spec
46
+ - The `updateMailMetadata` endpoint uses the field name `read`, not `is_read`
47
+
48
+ A generated client faithfully reproduces these spec bugs. ESI.ts fixes them.
22
49
 
23
50
  ## Installation
24
51
 
@@ -44,7 +71,7 @@ Verify everything works:
44
71
 
45
72
  ```bash
46
73
  npm run example:status # quick smoke test — checks ESI is reachable
47
- npm test # run the full test suite
74
+ npm test # run the full test suite (121 suites, 3,224 tests)
48
75
  ```
49
76
 
50
77
  ## Quick Start
@@ -207,43 +234,74 @@ Key behaviors:
207
234
 
208
235
  All clients are accessed as properties on the `EsiClient` instance. Authenticated endpoints require an access token.
209
236
 
210
- | Client | Property | Auth | Examples |
211
- | -------------- | ---------------------- | ---- | -------------------------------------------------------- |
212
- | Alliance | `client.alliance` | Some | `getAlliances()`, `getAllianceById(id)` |
213
- | Assets | `client.assets` | Yes | `getCharacterAssets(id)` |
214
- | Calendar | `client.calendar` | Yes | `getCharacterCalendar(id)` |
215
- | Characters | `client.characters` | Some | `getCharacterPublicInfo(id)`, `getCharacterPortrait(id)` |
216
- | Clones | `client.clones` | Yes | `getCharacterClones(id)` |
217
- | Contacts | `client.contacts` | Yes | `getCharacterContacts(id)` |
218
- | Contracts | `client.contracts` | Yes | `getCharacterContracts(id)` |
219
- | Corporations | `client.corporations` | Some | `getCorporationInfo(id)`, `getCorporationMembers(id)` |
220
- | Dogma | `client.dogma` | No | `getDogmaAttributes()`, `getDogmaEffects()` |
221
- | Factions | `client.factions` | Some | `getFactionWarStats()` |
222
- | Fittings | `client.fittings` | Yes | `getFittings(id)`, `createFitting(id, body)` |
223
- | Fleets | `client.fleets` | Yes | `getFleet(id)`, `getFleetMembers(id)` |
224
- | Incursions | `client.incursions` | No | `getIncursions()` |
225
- | Industry | `client.industry` | Some | `getCharacterIndustryJobs(id)` |
226
- | Insurance | `client.insurance` | No | `getInsurancePrices()` |
227
- | Killmails | `client.killmails` | Some | `getKillmail(id, hash)` |
228
- | Location | `client.location` | Yes | `getCharacterLocation(id)` |
229
- | Loyalty | `client.loyalty` | Yes | `getCharacterLoyaltyPoints(id)` |
230
- | Mail | `client.mail` | Yes | `getCharacterMail(id)` |
231
- | Market | `client.market` | Some | `getMarketPrices()`, `getMarketOrders(regionId)` |
232
- | PI | `client.pi` | Yes | `getCharacterPlanets(id)` |
233
- | Route | `client.route` | No | `getRoute(origin, destination)` |
234
- | Search | `client.search` | Some | `search(characterId, query)` |
235
- | Skills | `client.skills` | Yes | `getCharacterSkills(id)` |
236
- | Sovereignty | `client.sovereignty` | No | `getSovereigntySystems()`, `getSovereigntyMap()` |
237
- | Skyhooks | `client.skyhooks` | No | `getSovereigntyHubs()`, `getRaidableSkyhooks()` |
238
- | Mercenary | `client.mercenary` | No | `getMercenaryDens()`, `getMercenaryTacticalOperations()` |
239
- | Access Lists | `client.accessLists` | Yes | `getAccessList(id)` |
240
- | Status | `client.status` | No | `getStatus()` |
241
- | UI | `client.ui` | Yes | `setWaypoint(id)` |
242
- | Universe | `client.universe` | Some | `getSystemById(id)`, `getTypeById(id)` |
243
- | Wallet | `client.wallet` | Yes | `getCharacterWallet(id)` |
244
- | Wars | `client.wars` | No | `getWars()`, `getWarById(id)` |
245
- | Freelance Jobs | `client.freelanceJobs` | Some | `getFreelanceJobs()`, `getFreelanceJobById(id)` |
246
- | Meta | `client.meta` | No | `getOpenApiJson()`, `getOpenApiYaml()` |
237
+ | Client | Property | Auth | Examples |
238
+ | -------------- | ---------------------- | ---- | -------------------------------------------------------------------------------- |
239
+ | Alliance | `client.alliance` | Some | `getAlliances()`, `getAllianceById(id)` |
240
+ | Assets | `client.assets` | Yes | `getCharacterAssets(id)` |
241
+ | Calendar | `client.calendar` | Yes | `getCalendarEvents(id)` |
242
+ | Characters | `client.characters` | Some | `getCharacterPublicInfo(id)`, `getCharacterPortrait(id)` |
243
+ | Clones | `client.clones` | Yes | `getCharacterClones(id)` |
244
+ | Contacts | `client.contacts` | Yes | `getCharacterContacts(id)`, `postCharacterContacts(id, standing, contactIds)` |
245
+ | Contracts | `client.contracts` | Yes | `getCharacterContracts(id)` |
246
+ | Corporations | `client.corporations` | Some | `getCorporationInfo(id)`, `getCorporationMembers(id)` |
247
+ | Dogma | `client.dogma` | No | `getDogmaAttributes()`, `getDynamicItemInfo(typeId, itemId)` |
248
+ | Factions | `client.factions` | Some | `getFactionWarStats()` |
249
+ | Fittings | `client.fittings` | Yes | `getFittings(id)`, `createFitting(id, body)` |
250
+ | Fleets | `client.fleets` | Yes | `getFleetInformation(id)`, `getFleetMembers(id)` |
251
+ | Incursions | `client.incursions` | No | `getIncursions()` |
252
+ | Industry | `client.industry` | Some | `getCharacterIndustryJobs(id)` |
253
+ | Insurance | `client.insurance` | No | `getInsurancePrices()` |
254
+ | Killmails | `client.killmails` | Some | `getKillmail(id, hash)` |
255
+ | Location | `client.location` | Yes | `getCharacterLocation(id)` |
256
+ | Loyalty | `client.loyalty` | Yes | `getCharacterLoyaltyPoints(id)` |
257
+ | Mail | `client.mail` | Yes | `getCharacterMail(id)`, `sendMail(id, body)` |
258
+ | Market | `client.market` | Some | `getMarketPrices()`, `getMarketOrders(regionId)` |
259
+ | PI | `client.pi` | Yes | `getCharacterPlanets(id)` |
260
+ | Route | `client.route` | No | `getRoute(origin, destination)` |
261
+ | Search | `client.search` | Some | `search(characterId, query)` |
262
+ | Skills | `client.skills` | Yes | `getCharacterSkills(id)` |
263
+ | Sovereignty | `client.sovereignty` | No | `getSovereigntySystems()`, `getSovereigntyMap()` |
264
+ | Skyhooks | `client.skyhooks` | No | `getSovereigntyHubs()`, `getRaidableSkyhooks()` |
265
+ | Mercenary | `client.mercenary` | No | `getMercenaryDens()`, `getMercenaryTacticalOperations()` |
266
+ | Access Lists | `client.accessLists` | Yes | `getAccessList(id)` |
267
+ | Status | `client.status` | No | `getStatus()` |
268
+ | UI | `client.ui` | Yes | `setAutopilotWaypoint(destId, addToBeginning, clear)`, `openNewMailWindow(body)` |
269
+ | Universe | `client.universe` | Some | `getSystemById(id)`, `getTypeById(id)` |
270
+ | Wallet | `client.wallet` | Yes | `getCharacterWallet(id)` |
271
+ | Wars | `client.wars` | No | `getWars()`, `getWarById(id)` |
272
+ | Freelance Jobs | `client.freelanceJobs` | Some | `getFreelanceJobs()`, `getFreelanceJobById(id)` |
273
+ | Meta | `client.meta` | No | `getOpenApiJson()`, `getOpenApiYaml()` |
274
+
275
+ ## Runtime Response Validation
276
+
277
+ ESI.ts validates every API response at runtime using [Zod](https://zod.dev/) schemas. 146 of 210 endpoints have schemas attached. If CCP changes the ESI API and the response no longer matches the expected shape, you get an immediate `EsiValidationError` instead of silent data corruption.
278
+
279
+ Validation is **on by default**. Extra fields from ESI are preserved via `z.looseObject()` passthrough mode, so new fields added by CCP won't break your application — they flow through to your code untouched.
280
+
281
+ ```typescript
282
+ import {
283
+ EsiClient,
284
+ EsiValidationError,
285
+ isValidationError,
286
+ schemas,
287
+ } from '@lgriffin/esi.ts';
288
+
289
+ const client = new EsiClient();
290
+
291
+ // Validation happens automatically on every request
292
+ const character = await client.characters.getCharacterPublicInfo(12345);
293
+
294
+ // Disable validation globally if needed
295
+ const rawClient = new EsiClient({ validateResponse: false });
296
+
297
+ // Use schemas directly for your own validation
298
+ const result = schemas.CharacterInfoSchema.safeParse(someData);
299
+ if (result.success) {
300
+ console.log(result.data.name);
301
+ }
302
+ ```
303
+
304
+ See [guides/RUNTIME-VALIDATION.md](guides/RUNTIME-VALIDATION.md) for the full guide on schemas, error handling, and extending schemas.
247
305
 
248
306
  ## Caching
249
307
 
@@ -323,82 +381,6 @@ const allNames = await client.batchPost(
323
381
  );
324
382
  ```
325
383
 
326
- ## Runtime Response Validation
327
-
328
- ESI.ts validates every API response at runtime using [Zod](https://zod.dev/) schemas. If CCP changes the ESI API and the response no longer matches the expected shape, you get an immediate `EsiValidationError` instead of silent data corruption.
329
-
330
- Validation is **on by default**. Extra fields from ESI are preserved (passthrough mode), so new fields added by CCP won't break your application.
331
-
332
- ```typescript
333
- import {
334
- EsiClient,
335
- EsiValidationError,
336
- isValidationError,
337
- schemas,
338
- } from '@lgriffin/esi.ts';
339
-
340
- const client = new EsiClient();
341
-
342
- // Validation happens automatically on every request
343
- const character = await client.characters.getCharacterPublicInfo(12345);
344
-
345
- // Disable validation globally if needed
346
- const rawClient = new EsiClient({ validateResponse: false });
347
-
348
- // Use schemas directly for your own validation
349
- const result = schemas.CharacterInfoSchema.safeParse(someData);
350
- if (result.success) {
351
- console.log(result.data.name);
352
- }
353
- ```
354
-
355
- See [guides/RUNTIME-VALIDATION.md](guides/RUNTIME-VALIDATION.md) for the full guide on schemas, error handling, and extending schemas.
356
-
357
- ## Generated Types
358
-
359
- The library includes TypeScript interfaces generated directly from the ESI swagger spec, available as the `EsiSpec` namespace. These are guaranteed to match the live spec and complement the hand-written types:
360
-
361
- ```typescript
362
- import { EsiSpec } from '@lgriffin/esi.ts';
363
-
364
- // Generated type — exact spec field names and optionality
365
- const order: EsiSpec.GetMarketsRegionIdOrders200Ok = {
366
- order_id: 123,
367
- type_id: 34,
368
- price: 5.5,
369
- volume_remain: 1000,
370
- volume_total: 5000,
371
- is_buy_order: false,
372
- // ...
373
- };
374
- ```
375
-
376
- To regenerate types from the latest ESI spec:
377
-
378
- ```bash
379
- npm run generate:types # fetches spec, generates 147 interfaces + cache TTL map + rate limit groups + scope map
380
- npm run validate:esi # reports type drift between hand-written and generated types
381
- ```
382
-
383
- ## ESI Scopes
384
-
385
- The library includes a generated scope-to-endpoint mapping extracted from the ESI swagger spec. Use it to check which OAuth scopes an endpoint requires before making a request:
386
-
387
- ```typescript
388
- import { esiEndpointScopes, EsiScope } from '@lgriffin/esi.ts';
389
-
390
- // Look up scopes for a specific endpoint
391
- const walletScopes = esiEndpointScopes['GET:characters/{character_id}/wallet'];
392
- // → ['esi-wallet.read_character_wallet.v1']
393
-
394
- // Check if an endpoint requires auth
395
- const isPublic = !esiEndpointScopes['GET:universe/types/{type_id}'];
396
- // → true (public endpoint, no scopes needed)
397
-
398
- // Type-safe scope values
399
- const scope: EsiScope = 'esi-assets.read_assets.v1';
400
- ```
401
-
402
384
  ## Streaming Pagination
403
385
 
404
386
  For large paginated endpoints (market orders, contracts, assets), streaming yields one page at a time via `AsyncGenerator` instead of eagerly fetching all pages into memory:
@@ -495,6 +477,51 @@ Key points:
495
477
  - **Duplicates across pages** are expected when records are modified between requests
496
478
  - Existing offset-based routes (`getMarketOrders`, etc.) are unchanged
497
479
 
480
+ ## Generated Types
481
+
482
+ The library includes TypeScript interfaces generated directly from the ESI swagger spec, available as the `EsiSpec` namespace. These are guaranteed to match the live spec and complement the hand-written types:
483
+
484
+ ```typescript
485
+ import { EsiSpec } from '@lgriffin/esi.ts';
486
+
487
+ // Generated type — exact spec field names and optionality
488
+ const order: EsiSpec.GetMarketsRegionIdOrders200Ok = {
489
+ order_id: 123,
490
+ type_id: 34,
491
+ price: 5.5,
492
+ volume_remain: 1000,
493
+ volume_total: 5000,
494
+ is_buy_order: false,
495
+ // ...
496
+ };
497
+ ```
498
+
499
+ To regenerate types from the latest ESI spec:
500
+
501
+ ```bash
502
+ npm run generate:types # fetches spec, generates 147 interfaces + cache TTL map + rate limit groups + scope map
503
+ npm run validate:esi # reports type drift between hand-written and generated types
504
+ ```
505
+
506
+ ## ESI Scopes
507
+
508
+ The library includes a generated scope-to-endpoint mapping extracted from the ESI swagger spec. Use it to check which OAuth scopes an endpoint requires before making a request:
509
+
510
+ ```typescript
511
+ import { esiEndpointScopes, EsiScope } from '@lgriffin/esi.ts';
512
+
513
+ // Look up scopes for a specific endpoint
514
+ const walletScopes = esiEndpointScopes['GET:characters/{character_id}/wallet'];
515
+ // → ['esi-wallet.read_character_wallet.v1']
516
+
517
+ // Check if an endpoint requires auth
518
+ const isPublic = !esiEndpointScopes['GET:universe/types/{type_id}'];
519
+ // → true (public endpoint, no scopes needed)
520
+
521
+ // Type-safe scope values
522
+ const scope: EsiScope = 'esi-assets.read_assets.v1';
523
+ ```
524
+
498
525
  ## Error Handling
499
526
 
500
527
  API errors throw `EsiError` with `statusCode`, `message`, and `url` properties:
@@ -628,9 +655,29 @@ const marketClient = EsiApiFactory.createMarketClient({
628
655
  const prices = await marketClient.getMarketPrices();
629
656
  ```
630
657
 
658
+ ## Endpoint Coverage
659
+
660
+ All 210 ESI endpoint definitions have been validated against live Tranquility. This table summarizes the validation approach:
661
+
662
+ | Category | Endpoints | Method |
663
+ | --------------------------- | --------- | -------------------------------------------------- |
664
+ | Public GETs | 78 | 43 runnable example scripts with captured output |
665
+ | Authenticated GETs | 72 | Example scripts + live testing with EVE SSO tokens |
666
+ | Contacts (POST/PUT/DELETE) | 3 | Live create/edit/delete lifecycle |
667
+ | Fittings (POST/DELETE) | 2 | Live create/delete lifecycle |
668
+ | Mail (POST/PUT/DELETE) | 5 | Live send/label/metadata/delete lifecycle |
669
+ | UI (POST) | 5 | Live testing with EVE client running |
670
+ | Calendar (PUT) | 1 | Live RSVP to event |
671
+ | Fleet (GET/POST/PUT/DELETE) | 14 | Live fleet with two characters |
672
+ | Assets POST | 3 | Live asset location/name queries |
673
+ | CSPA (POST) | 1 | Live charge cost calculation |
674
+ | Dogma dynamic (GET) | 1 | Live mutaplasmid item query |
675
+ | Universe POST helpers | 3 | Live name resolution and affiliation |
676
+ | Freelance Jobs (GET) | 4 | Live queries (graceful 404 for no active jobs) |
677
+
631
678
  ## Examples
632
679
 
633
- Runnable examples are in the `examples/` directory.
680
+ 43 runnable examples are in the `examples/` directory.
634
681
 
635
682
  ### Public Endpoints (no auth needed)
636
683
 
@@ -651,23 +698,39 @@ npm run example:rate-limiting # Rate limiter & pagination demonstration
651
698
  npm run example:cursor-pagination # Freelance Jobs with cursor pagination
652
699
  npm run example:streaming # Streaming pagination for large datasets
653
700
  npm run example:token-refresh # Automatic token refresh on 401
701
+ npm run example:universe-encyclopedia # Ancestries, bloodlines, races, celestials
702
+ npm run example:dogma-meta-sov # Dogma effects, sovereignty, meta endpoint
703
+ npm run example:faction-details # Faction warfare leaderboards and stats
654
704
  ```
655
705
 
656
706
  ### Authenticated Endpoints (require ESI_ACCESS_TOKEN)
657
707
 
658
- These examples require an EVE SSO token with the listed scopes. Set `ESI_ACCESS_TOKEN` in your environment or `.env` file.
659
-
660
708
  ```bash
661
709
  npm run example # Full character profile assembly
662
- npm run example:wallet # Wallet balance, journal, transactions (esi-wallet.read_character_wallet.v1)
663
- npm run example:skills # Trained skills, queue, attributes (esi-skills.read_skills.v1, esi-skills.read_skillqueue.v1)
664
- npm run example:assets # Asset inventory with bulk name lookup (esi-assets.read_assets.v1)
665
- npm run example:killmails # Recent killmails + full details (esi-killmails.read_killmails.v1)
666
- npm run example:fleet # Fleet info, members, wing/squad structure (esi-fleets.read_fleet.v1)
667
- npm run example:mail # Inbox headers, labels, mailing lists (esi-mail.read_mail.v1)
668
- npm run example:location # Current system, online status, ship (esi-location.read_location.v1)
669
- npm run example:fittings # Saved fittings + clone state + implants (esi-fittings.read_fittings.v1, esi-clones.read_clones.v1)
670
- npm run example:contacts # Contact list with standings + labels (esi-characters.read_contacts.v1)
710
+ npm run example:wallet # Wallet balance, journal, transactions
711
+ npm run example:skills # Trained skills, queue, attributes
712
+ npm run example:assets # Asset inventory with bulk name lookup
713
+ npm run example:killmails # Recent killmails + full details
714
+ npm run example:fleet # Fleet info, members, wing/squad structure
715
+ npm run example:mail # Inbox headers, labels, mailing lists
716
+ npm run example:location # Current system, online status, ship
717
+ npm run example:fittings # Saved fittings + clone state + implants
718
+ npm run example:contacts # Contact list with standings + labels
719
+ npm run example:character-details # Blueprints, roles, standings, medals
720
+ npm run example:corporation-details # Corp members, divisions, structures
721
+ npm run example:calendar-search # Calendar events + character search
722
+ npm run example:loyalty-pi # Loyalty points + planetary interaction
723
+ npm run example:industry-mining # Industry jobs + mining ledger
724
+ npm run example:market-orders # Character/corp market orders
725
+ npm run example:corp-contracts-wallet # Corp contracts, contacts, wallets
726
+ ```
727
+
728
+ ### Write Operations (require specific scopes + caution)
729
+
730
+ ```bash
731
+ npm run example:write-ops # Contacts, fittings, mail, UI lifecycle tests
732
+ npm run example:universe-posts # Name resolution + character affiliation (public)
733
+ npm run example:freelance-jobs # Freelance job queries
671
734
  ```
672
735
 
673
736
  ### Parallel Requests
@@ -711,6 +774,29 @@ try {
711
774
  }
712
775
  ```
713
776
 
777
+ ## Testing
778
+
779
+ ESI.ts has a comprehensive multi-tier testing strategy:
780
+
781
+ | Tier | Tests | Purpose |
782
+ | ---------------------- | ---------------- | ---------------------------------------------------------------- |
783
+ | **TDD unit tests** | 81 files | Every client method, endpoint path, query param, and body format |
784
+ | **BDD scenario tests** | 40 feature files | Behavioral specifications in Gherkin (Given/When/Then) |
785
+ | **Mocked integration** | Full suite | Cross-layer request flow with jest-fetch-mock |
786
+ | **Live smoke tests** | 43 examples | Every endpoint against live Tranquility |
787
+ | **ESI spec contract** | 10 tests | Endpoint definitions validated against live swagger spec |
788
+ | **Gated auth tests** | 33 tests | Authenticated endpoints with real tokens |
789
+
790
+ ```bash
791
+ npm test # Unit + BDD tests (121 suites, 3,224 tests)
792
+ npm run coverage # Tests with coverage report (thresholds enforced)
793
+ npm run bdd # BDD scenario tests only
794
+ ```
795
+
796
+ Coverage thresholds are enforced in CI: branches 50%, functions 50%, lines 65%, statements 65%.
797
+
798
+ See [guides/TESTING.md](guides/TESTING.md) for the full testing guide, and [guides/ARCHITECTURE.md](guides/ARCHITECTURE.md) for architecture diagrams.
799
+
714
800
  ## Development
715
801
 
716
802
  ### Prerequisites
@@ -743,7 +829,7 @@ npm run format # Format code with Prettier
743
829
  npm run format:check # Check formatting without modifying
744
830
 
745
831
  # Testing
746
- npm test # Unit tests
832
+ npm test # Unit tests (121 suites, 3,224 tests)
747
833
  npm run test:all # Unit + improved + BDD tests
748
834
  npm run coverage # Tests with coverage report (thresholds enforced)
749
835
  npm run bdd # BDD scenario tests
@@ -793,20 +879,6 @@ Every pull request runs the full validation suite:
793
879
 
794
880
  See [.github/workflows/README.md](.github/workflows/README.md) for full workflow details.
795
881
 
796
- ## Testing
797
-
798
- ```bash
799
- npm test # Unit + BDD tests (108 suites, 2836 tests)
800
- npm run coverage # Tests with coverage report (thresholds enforced)
801
- npm run bdd # BDD scenario tests only
802
- ```
803
-
804
- To verify against the live ESI API:
805
-
806
- ```bash
807
- npm run example:status # Confirms ESI connectivity and server status
808
- ```
809
-
810
882
  ## Contributing
811
883
 
812
884
  1. Fork the repository
@@ -40,19 +40,21 @@ export declare class ContactsClient extends BaseEsiClient<typeof contactEndpoint
40
40
  * Add contacts to a character's contact list via a POST request.
41
41
  *
42
42
  * @param characterId - The ID of the character to add contacts for
43
- * @param contacts - Contact data including IDs, standings, and optional labels
43
+ * @param standing - Standing value for the contacts (-10 to 10)
44
+ * @param contactIds - Array of character/corporation/alliance IDs to add
44
45
  * @returns An array of contact IDs that were successfully added
45
46
  * @requires Authentication
46
47
  */
47
- postCharacterContacts(characterId: number, contacts: object): Promise<number[]>;
48
+ postCharacterContacts(characterId: number, standing: number, contactIds: number[]): Promise<number[]>;
48
49
  /**
49
50
  * Update existing contacts in a character's contact list via a PUT request.
50
51
  *
51
52
  * @param characterId - The ID of the character whose contacts to update
52
- * @param contacts - Updated contact data including IDs, standings, and optional labels
53
+ * @param standing - New standing value for the contacts (-10 to 10)
54
+ * @param contactIds - Array of contact IDs to update
53
55
  * @requires Authentication
54
56
  */
55
- putCharacterContacts(characterId: number, contacts: object): Promise<void>;
57
+ putCharacterContacts(characterId: number, standing: number, contactIds: number[]): Promise<void>;
56
58
  /**
57
59
  * Retrieve custom contact labels for a character.
58
60
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ContactsClient.d.ts","sourceRoot":"","sources":["../../src/clients/ContactsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE/D,qBAAa,cAAe,SAAQ,aAAa,CAAC,OAAO,gBAAgB,CAAC;gBAC5D,MAAM,EAAE,SAAS;IAI7B;;;;;;OAMG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI3D;;;;;;OAMG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMrE;;;;;;OAMG;IACH,uBAAuB,CACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC;IAOhB;;;;;;OAMG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI7D;;;;;;;OAOG;IACH,qBAAqB,CACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpB;;;;;;OAMG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E;;;;;;OAMG;IACH,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMvE;;;;;;OAMG;IACH,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAIjE;;;;;;OAMG;IACH,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAK5E"}
1
+ {"version":3,"file":"ContactsClient.d.ts","sourceRoot":"","sources":["../../src/clients/ContactsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE/D,qBAAa,cAAe,SAAQ,aAAa,CAAC,OAAO,gBAAgB,CAAC;gBAC5D,MAAM,EAAE,SAAS;IAI7B;;;;;;OAMG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI3D;;;;;;OAMG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMrE;;;;;;OAMG;IACH,uBAAuB,CACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC;IAOhB;;;;;;OAMG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI7D;;;;;;;;OAQG;IACH,qBAAqB,CACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMpB;;;;;;;OAOG;IACH,oBAAoB,CAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;;OAMG;IACH,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMvE;;;;;;OAMG;IACH,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAIjE;;;;;;OAMG;IACH,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAK5E"}
@@ -35,7 +35,7 @@ class ContactsClient extends BaseEsiClient_1.BaseEsiClient {
35
35
  * @requires Authentication
36
36
  */
37
37
  deleteCharacterContacts(characterId, contactIds) {
38
- return this.api.deleteCharacterContacts(characterId, contactIds);
38
+ return this.api.deleteCharacterContacts(characterId, contactIds.join(','));
39
39
  }
40
40
  /**
41
41
  * Retrieve a character's contact list.
@@ -51,22 +51,24 @@ class ContactsClient extends BaseEsiClient_1.BaseEsiClient {
51
51
  * Add contacts to a character's contact list via a POST request.
52
52
  *
53
53
  * @param characterId - The ID of the character to add contacts for
54
- * @param contacts - Contact data including IDs, standings, and optional labels
54
+ * @param standing - Standing value for the contacts (-10 to 10)
55
+ * @param contactIds - Array of character/corporation/alliance IDs to add
55
56
  * @returns An array of contact IDs that were successfully added
56
57
  * @requires Authentication
57
58
  */
58
- postCharacterContacts(characterId, contacts) {
59
- return this.api.addContacts(characterId, contacts);
59
+ postCharacterContacts(characterId, standing, contactIds) {
60
+ return this.api.addContacts(characterId, standing, contactIds);
60
61
  }
61
62
  /**
62
63
  * Update existing contacts in a character's contact list via a PUT request.
63
64
  *
64
65
  * @param characterId - The ID of the character whose contacts to update
65
- * @param contacts - Updated contact data including IDs, standings, and optional labels
66
+ * @param standing - New standing value for the contacts (-10 to 10)
67
+ * @param contactIds - Array of contact IDs to update
66
68
  * @requires Authentication
67
69
  */
68
- putCharacterContacts(characterId, contacts) {
69
- return this.api.editContacts(characterId, contacts);
70
+ putCharacterContacts(characterId, standing, contactIds) {
71
+ return this.api.editContacts(characterId, standing, contactIds);
70
72
  }
71
73
  /**
72
74
  * Retrieve custom contact labels for a character.
@@ -74,7 +74,7 @@ export declare class FleetClient extends BaseEsiClient<typeof fleetEndpoints> {
74
74
  *
75
75
  * @param fleetId - The ID of the fleet
76
76
  * @param squadId - The ID of the squad to rename
77
- * @param name - The new name for the squad
77
+ * @param name - The new name for the squad (max 10 characters)
78
78
  * @requires Authentication
79
79
  */
80
80
  renameFleetSquad(fleetId: number, squadId: number, name: string): Promise<void>;
@@ -110,7 +110,7 @@ export declare class FleetClient extends BaseEsiClient<typeof fleetEndpoints> {
110
110
  *
111
111
  * @param fleetId - The ID of the fleet
112
112
  * @param wingId - The ID of the wing to rename
113
- * @param name - The new name for the wing
113
+ * @param name - The new name for the wing (max 10 characters)
114
114
  * @requires Authentication
115
115
  */
116
116
  renameFleetWing(fleetId: number, wingId: number, name: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"FleetClient.d.ts","sourceRoot":"","sources":["../../src/clients/FleetClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,WAAY,SAAQ,aAAa,CAAC,OAAO,cAAc,CAAC;gBACvD,MAAM,EAAE,SAAS;IAI7B;;;;;;OAMG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMvE;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIxD;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIxD;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;;;;OAOG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;;;;OAOG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpD;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAM5E;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D;;;;;;;OAOG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;;;OAOG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAKjC"}
1
+ {"version":3,"file":"FleetClient.d.ts","sourceRoot":"","sources":["../../src/clients/FleetClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,WAAY,SAAQ,aAAa,CAAC,OAAO,cAAc,CAAC;gBACvD,MAAM,EAAE,SAAS;IAI7B;;;;;;OAMG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMvE;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIxD;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIxD;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;;;;OAOG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;;;;OAOG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpD;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAM5E;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D;;;;;;;OAOG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;;;;OAOG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAKjC"}
@@ -93,10 +93,13 @@ class FleetClient extends BaseEsiClient_1.BaseEsiClient {
93
93
  *
94
94
  * @param fleetId - The ID of the fleet
95
95
  * @param squadId - The ID of the squad to rename
96
- * @param name - The new name for the squad
96
+ * @param name - The new name for the squad (max 10 characters)
97
97
  * @requires Authentication
98
98
  */
99
99
  renameFleetSquad(fleetId, squadId, name) {
100
+ if (name.length > 10) {
101
+ return Promise.reject(new Error(`Fleet squad name "${name}" exceeds ESI maximum of 10 characters`));
102
+ }
100
103
  return this.api.renameFleetSquad(fleetId, squadId, name);
101
104
  }
102
105
  /**
@@ -135,10 +138,13 @@ class FleetClient extends BaseEsiClient_1.BaseEsiClient {
135
138
  *
136
139
  * @param fleetId - The ID of the fleet
137
140
  * @param wingId - The ID of the wing to rename
138
- * @param name - The new name for the wing
141
+ * @param name - The new name for the wing (max 10 characters)
139
142
  * @requires Authentication
140
143
  */
141
144
  renameFleetWing(fleetId, wingId, name) {
145
+ if (name.length > 10) {
146
+ return Promise.reject(new Error(`Fleet wing name "${name}" exceeds ESI maximum of 10 characters`));
147
+ }
142
148
  return this.api.renameFleetWing(fleetId, wingId, name);
143
149
  }
144
150
  /**
@@ -15,6 +15,6 @@ export declare class SovereigntyClient extends BaseEsiClient<typeof sovereigntyE
15
15
  *
16
16
  * @returns A list of sovereignty systems with ownership, ADM indices, and anchored structures
17
17
  */
18
- getSovereigntySystems(): Promise<SovereigntySystem[]>;
18
+ getSovereigntySystems(): Promise<SovereigntySystem>;
19
19
  }
20
20
  //# sourceMappingURL=SovereigntyClient.d.ts.map