> ## Documentation Index
> Fetch the complete documentation index at: https://swc-sdk.zeltros.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating to v3.x

> Update your code for the two v3 breaking changes: Page<T> replaces raw arrays on all list() methods, and several wrapper types were removed.

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.

<Note>
  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.
</Note>

## 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.

```typescript theme={null}
// 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.

```typescript theme={null}
// 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.

```typescript theme={null}
// 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.

```typescript theme={null}
// 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:

```typescript theme={null}
// 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:

```typescript theme={null}
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`:

```typescript theme={null}
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>`                                    |

***

## Authorization header change

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.

<Warning>
  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.
</Warning>

***

## 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
