Version 3.0 of the SW Combine SDK introduces two breaking changes. The first affects every list() call in your codebase: return types changed from raw arrays (or bespoke wrapper objects) to a unified Page<T> class. The second is a transparent internal change to how access tokens are transmitted. This guide walks through each change with before-and-after code so you can update your project quickly.
TypeScript will catch the Page<T> change for you. After upgrading, run tsc — the compiler flags every call site where the return type changed. The fix is almost always adding .data to access the array.
Overview of breaking changes
| Area | What changed |
|---|
All list() return types | Now return Page<T> instead of T[], FactionListResponse, NewsListResponse, etc. |
| Pagination metadata | Access via page.total, page.start, page.count instead of result.attributes.* |
listRaw() methods | Removed — list() now includes metadata |
listAll() on factions | Removed — use for await...of instead |
| Removed types | Multiple wrapper types replaced by Page<T> (see full list below) |
| Authorization header | Tokens sent via Authorization: OAuth {token} header — no code changes needed |
Updating list() calls
Array-based endpoints
Most endpoints — inventory, galaxy, events, market, datacards, character messages, credit logs, faction members, budgets, stockholders — previously returned plain arrays.
// v2
const ships = await client.inventory.entities.list({
entityType: 'ships',
uid: '1:12345',
assignType: 'owner',
});
ships.forEach(s => console.log(s.name));
console.log(`Got ${ships.length} ships`);
// v3
const ships = await client.inventory.entities.list({
entityType: 'ships',
uid: '1:12345',
assignType: 'owner',
});
ships.data.forEach(s => console.log(s.name));
console.log(`Got ${ships.data.length} of ${ships.total} ships`);
Faction list
The faction.list() endpoint previously returned a FactionListResponse wrapper with a .faction array and a .attributes metadata object.
// v2
const result = await client.faction.list();
result.faction?.forEach(f => console.log(f.value));
console.log(result.attributes?.total);
// v3
const result = await client.faction.list();
result.data.forEach(f => console.log(f.value));
console.log(result.total);
News list
The news GNS and SimNews list endpoints previously returned arrays with a .attributes metadata attachment.
// v2
const news = await client.news.gns.list();
news.forEach(n => console.log(n.value));
console.log(news.attributes.total);
// v3
const news = await client.news.gns.list();
news.data.forEach(n => console.log(n.value));
console.log(news.total);
Replacing listRaw()
The listRaw() method existed on galaxy and types resources as a way to access pagination metadata alongside the items. It is no longer needed — list() returns a Page<T> that includes both.
// v2
const raw = await client.galaxy.planets.listRaw();
console.log(raw.attributes?.total);
const planets = raw.planet || [];
// v3
const planets = await client.galaxy.planets.list();
console.log(planets.total);
// planets.data is the typed array
Replacing listAll()
FactionResource.listAll() has been removed. Use for await...of on any Page<T> to iterate through all pages automatically:
// v2
const allFactions = await client.faction.listAll();
console.log(allFactions.length);
// v3
const allFactions = [];
for await (const faction of await client.faction.list()) {
allFactions.push(faction);
}
console.log(allFactions.length);
This pattern works on every list() endpoint, not just factions.
Page<T> quick-reference
The table below maps every v2 access pattern to its v3 equivalent:
| v2 pattern | v3 equivalent |
|---|
result[0] | result.data[0] |
result.forEach(...) | result.data.forEach(...) |
result.length | result.data.length |
result.map(...) | result.data.map(...) |
result.faction?.[0] | result.data[0] |
result.attributes?.total | result.total |
result.attributes?.start | result.start |
result.attributes?.count | result.count |
listRaw() | list() |
listAll() | for await (const item of await list()) { ... } |
New capabilities in v3
Page<T> adds features that were not available in v2:
const page = await client.inventory.entities.list({ entityType: 'ships', uid: '1:12345', assignType: 'owner' });
// Check whether more pages exist
console.log(page.hasMore); // true or false
// Fetch the next page (original filters are preserved automatically)
if (page.hasMore) {
const nextPage = await page.getNextPage();
}
// Auto-paginate through every item across all pages
for await (const ship of await client.inventory.entities.list({ entityType: 'ships', uid: '1:12345', assignType: 'owner' })) {
console.log(ship.value.name);
}
// JSON serialization includes all fields cleanly
console.log(JSON.stringify(page));
// { "data": [...], "total": 100, "start": 1, "count": 50, "hasMore": true }
Removed types
If you import any of the following types, replace them with Page<T> and update your access patterns. Import Page from swcombine-sdk:
import { Page } from 'swcombine-sdk';
| Removed type | Replacement |
|---|
FactionListResponse | Page<FactionListItem> |
FactionListAttributes | Use page.total, page.start, page.count |
NewsListResponse | Page<NewsListItem> |
NewsListAttributes | Use page.total, page.start, page.count |
GalaxyListAttributes | Use page.total, page.start, page.count |
GalaxyPlanetListRawResponse | Page<GalaxyPlanetListItem> |
GalaxySectorListRawResponse | Page<GalaxySectorListItem> |
GalaxySystemListRawResponse | Page<GalaxySystemListItem> |
GalaxyStationListRawResponse | Page<GalaxyStationListItem> |
GalaxyCityListRawResponse | Page<GalaxyCityListItem> |
TypesEntitiesListRawResponse | Page<TypesEntityListItem> |
TypesShipsListRawResponse | Page<TypesEntityListItem> |
TypesEntitiesListMetaResponse | Page<TypesEntityListItem> |
TypesEntityListAttributes | Use page.total, page.start, page.count |
ListResponse<T> | Page<T> |
Access tokens are now sent in the Authorization: OAuth {token} HTTP header instead of the ?access_token=... query parameter. No code changes are required — the SDK handles this automatically.
If you have infrastructure (logging pipelines, proxies, reverse proxies) that inspects outgoing request URLs for an access_token query parameter, it will no longer appear there after upgrading to v3.
Unchanged endpoints
The following methods were not paginated lists and are unaffected by the v3 changes:
character.skills.list() — still returns CharacterSkills
character.privileges.list() — still returns PrivilegesResponse
character.permissions.list() — still returns CharacterPermissionsResponse
- All
.get() methods — still return the entity directly