Normalizes list-API response shapes into a consistent `unknown[]` array and extracts stable item identifiers across varying endpoint payload structures. Pure utility functions with no runtime dependencies — safe for server and client use. ## Key Components | Export | Signature | Description | |---|---|---| | `extractItems` | `(data: unknown) => unknown[]` | Normalizes heterogeneous response shapes into a flat array | | `extractItemId` | `(type: string, item: unknown) => string \| null` | Extracts a stable primary key from an item, handling `id` vs `external_id` variance | ### `extractItems` — Supported Response Shapes | Property | Source | |---|---| | `{ items }` | General list endpoints | | `{ posts }` | Post/blog endpoints | | `{ campaigns }` | Campaign endpoints | | `{ completed, inProgress }` | Delivery endpoints (flattened) | | `{ data }` | Generic data wrapper | | Raw `Array` | Direct array responses | ### `extractItemId` — Key Resolution Strategy For `roadmap_item`, `delivery_item`, and `internal_task` types, `external_id` is checked first (ClickUp-backed IDs). Falls back to `obj.id` as string or coerced number for all other types. ## Usage Example ```typescript import { extractItems, extractItemId } from './extract-items' // Normalize any list endpoint response const rawResponse = await fetchCampaigns() const items = extractItems(rawResponse) // always returns Item[] // Resolve a stable ID regardless of item type for (const item of items) { const id = extractItemId('roadmap_item', item) if (id) console.log('Matched item:', id) } // Delivery endpoint — flattens completed + inProgress automatically const deliveryItems = extractItems({ completed: [...], inProgress: [...] }) ``` ## Notes - **No external dependencies** — no `@tanstack/react-query` import, intentionally hoisted to keep this out of the chat hooks chunk - **Re-exported** from `lib/utils/entity-list-api.ts` in the hub repo as the single normalization implementation across both repositories - Source: [`src/lib/utils/extract-items.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/src/lib/utils/extract-items.ts)