pinia-orm-fetch
v1.0.1
Published
ofetch/$fetch plugin for pinia-orm (replaces @pinia-orm/axios)
Downloads
199
Readme
pinia-orm-fetch
An ofetch / $fetch plugin for Pinia ORM — a drop-in replacement for @pinia-orm/axios.
Use Nuxt's native $fetch (including NuxtAuthSanctum's useSanctumClient()) instead of Axios for all your Pinia ORM API calls. Auth headers, interceptors, and base URLs are handled automatically by your $fetch instance.
Why not Axios?
If you're using Nuxt, you already have $fetch built in. Adding Axios means:
- An extra dependency (~30 kB) that duplicates what
$fetchalready does - Manual configuration to forward auth headers, cookies, and CSRF tokens
- Two different HTTP clients in the same app with different interceptor patterns
pinia-orm-fetch removes Axios entirely and lets you pass in any $fetch instance — including the one from useSanctumClient() that already has your auth headers attached.
Install
npm install pinia-orm-fetchPeer dependencies: ofetch, pinia, pinia-orm
Quick Start
1. Register the plugin
// plugins/pinia-orm.ts
import { createORM } from 'pinia-orm'
import { createPiniaOrmFetch } from 'pinia-orm-fetch'
export default defineNuxtPlugin((nuxtApp) => {
const piniaOrm = createORM({
plugins: [
createPiniaOrmFetch({
baseURL: '/api',
dataKey: 'data', // if your API wraps responses in { data: ... }
}),
],
})
nuxtApp.vueApp.use(piniaOrm)
})2. With NuxtAuthSanctum
// plugins/pinia-orm.ts
import { createORM } from 'pinia-orm'
import { createPiniaOrmFetch } from 'pinia-orm-fetch'
import { useSanctumClient } from 'nuxt-auth-sanctum'
export default defineNuxtPlugin((nuxtApp) => {
const sanctumFetch = useSanctumClient()
const piniaOrm = createORM({
plugins: [
createPiniaOrmFetch({
fetch: sanctumFetch, // auth headers included automatically
baseURL: '/api',
dataKey: 'data',
}),
],
})
nuxtApp.vueApp.use(piniaOrm)
})3. Define a model
// models/User.ts
import { Model } from 'pinia-orm'
export class User extends Model {
static entity = 'users'
static fields() {
return {
id: this.uid(),
name: this.string(''),
email: this.string(''),
}
}
}4. Use in components
import { useFetchRepo } from 'pinia-orm-fetch'
import { User } from '~/models/User'
const userRepo = useFetchRepo(User)
// GET /api/users — response auto-saved to store
await userRepo.api().get('/users')
// POST /api/users
await userRepo.api().post('/users', {
name: 'Jerm',
email: '[email protected]',
})
// PUT /api/users/1
await userRepo.api().put('/users/1', { name: 'Jeremy' })
// PATCH /api/users/1
await userRepo.api().patch('/users/1', { name: 'Jeremy' })
// DELETE /api/users/1
await userRepo.api().delete('/users/1')Configuration
Global config
Passed to createPiniaOrmFetch():
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| fetch | $Fetch | undefined | The $fetch instance to use. In Nuxt, pass useSanctumClient() or useRequestFetch(). |
| baseURL | string | undefined | Base URL prepended to all request URLs. |
| dataKey | string | undefined | Key to extract from response body (e.g. 'data' if your API returns { data: [...] }). |
| save | boolean | true | Auto-save response data to the Pinia ORM store. |
| persistBy | 'save' \| 'insert' | 'save' | Pinia ORM persist method — save upserts, insert always creates new. |
| actions | object | undefined | Custom named actions (see below). |
All ofetch options (headers, query, retry, timeout, etc.) are also supported since Config extends FetchOptions.
Per-request config
await userRepo.api().get('/users', {
dataKey: 'results',
save: false, // don't auto-save to store
})Per-model config
export class User extends Model {
static entity = 'users'
static $config() {
return {
fetchApi: {
dataKey: 'data',
actions: {
fetchActive: { method: 'get', url: '/users?active=true' },
},
},
}
}
}API
createPiniaOrmFetch(config?)
Creates the Pinia ORM plugin. Pass your $fetch instance and global options.
useFetchRepo(Model)
Returns a FetchRepository bound to the given model. Use .api() to make requests.
useFetchApi(repository)
Returns a Request instance from an existing repository. Typically you'll use repo.api() instead.
FetchRepository
Extends Pinia ORM's Repository. Additional methods:
.api()— get aRequestinstance for making HTTP calls.setFetch(fetchInstance)— override the$fetchinstance for this repo
Response
Returned by all API calls. Properties:
| Property | Type | Description |
|----------|------|-------------|
| response | FetchResponse | The raw ofetch response (access ._data, .status, .headers) |
| entities | Collection \| null | Records saved to the store |
| isSaved | boolean | Whether data was persisted to the store |
dataTransformer
For APIs with non-standard response shapes:
await userRepo.api().get('/users', {
dataTransformer: (response) => {
// response is FetchResponse — use ._data (not .data)
return response._data.results.map(user => ({
id: user.uid,
name: `${user.first_name} ${user.last_name}`,
email: user.email_address,
}))
},
})Differences from @pinia-orm/axios
What changed
| Concept | @pinia-orm/axios | pinia-orm-fetch |
|---------|-------------------|-------------------|
| HTTP client | Axios | ofetch / $fetch |
| Plugin factory | createPiniaOrmAxios({ axios }) | createPiniaOrmFetch({ fetch }) |
| Composable (repo) | useAxiosRepo(Model) | useFetchRepo(Model) |
| Composable (api) | useAxiosApi(repo) | useFetchApi(repo) |
| Repository class | AxiosRepository | FetchRepository |
| Set client | repo.setAxios(instance) | repo.setFetch(instance) |
| Client property | repo.axios | repo.fetchClient |
| Request body | data (2nd arg) | body (2nd arg) |
| Response data | response.data | response._data |
| Model config key | axiosApi | fetchApi |
| Install config key | axiosApi | fetchApi |
| dataTransformer arg | AxiosResponse (.data) | FetchResponse (._data) |
What stayed the same
.get(),.post(),.put(),.patch(),.delete()method signaturesdataKey,save,persistBy,deleteoptions- Custom
actions(both object and function styles) - Auto-save behavior and store persistence
- Plugin registration via
createORM({ plugins: [...] })
Migration from @pinia-orm/axios
Replace the dependency:
npm uninstall @pinia-orm/axios axios npm install pinia-orm-fetchUpdate imports:
- import { createPiniaOrmAxios } from '@pinia-orm/axios' + import { createPiniaOrmFetch } from 'pinia-orm-fetch' - import { useAxiosRepo } from '@pinia-orm/axios' + import { useFetchRepo } from 'pinia-orm-fetch'Update plugin registration:
- createPiniaOrmAxios({ axios: axiosInstance }) + createPiniaOrmFetch({ fetch: $fetchInstance })Update model configs:
static $config() { return { - axiosApi: { dataKey: 'data' }, + fetchApi: { dataKey: 'data' }, } }Update
dataTransformercalls:- dataTransformer: (response) => response.data.results + dataTransformer: (response) => response._data.results
Non-Nuxt Usage
This package works in any Vue project — it depends on ofetch, not Nuxt. Just provide any $fetch instance:
import { ofetch } from 'ofetch'
import { createPiniaOrmFetch } from 'pinia-orm-fetch'
const apiFetch = ofetch.create({
baseURL: 'https://api.example.com',
headers: { Authorization: `Bearer ${token}` },
})
const piniaOrm = createORM({
plugins: [createPiniaOrmFetch({ fetch: apiFetch })],
})License
MIT
