@void-snippets/core

Adapter System

VSAdapters and createDefaultAdapters() for decoupling API shapes.

#What adapters do

Adapters are the one-time translation layer between your API's response shape and the internal format the library expects. Define them once and every hook call site gets normalised data automatically.

#VSAdapters

typescript
interface VSAdapters<TListRaw, TBase, TSingleRaw, TDetail> {
  fromList:   (raw: TListRaw)   => VSListResult<TBase>;
  fromSingle: (raw: TSingleRaw) => TDetail;
}

#createDefaultAdapters()

Returns pre-built adapters for the default response shape shown above. Use this when your API matches the convention.

typescript
import { createDefaultAdapters } from '@void-snippets/core';
import type { Contact } from './contacts.types';

// No arguments — pass your types as generics
const defaultAdapters = createDefaultAdapters<Contact.Base, Contact.Detail>();

#Writing a custom adapter

When your API returns a different shape, implement VSAdapters yourself and pass it to createResourceHooks.

typescript
// contacts/contacts.adapters.ts

// Say your API returns this for list requests:
// { results: [...], meta: { currentPage, perPage, lastPage, total } }
import type { VSAdapters, VSListResult } from '@void-snippets/core';
import type { Contact } from './contacts.types';

type ApiList   = { results: Contact.Base[]; meta: { currentPage: number; perPage: number; lastPage: number; total: number } };
type ApiSingle = { contact: Contact.Detail };

export const contactAdapters: VSAdapters<ApiList, Contact.Base, ApiSingle, Contact.Detail> = {
  fromList: (raw): VSListResult<Contact.Base> => ({
    items: raw.results,
    pagination: {
      page:           raw.meta.currentPage,
      limit:          raw.meta.perPage,
      totalPages:     raw.meta.lastPage,
      totalDocuments: raw.meta.total,
    },
  }),
  fromSingle: (raw): Contact.Detail => raw.contact,
};

// Pass it when creating hooks:
export const contactHooks = createResourceHooks('contacts', ContactsApis, {
  adapters: contactAdapters,
});