diff --git a/docs/content/3.plugins/2.axios/1.guide/2.configuration.md b/docs/content/3.plugins/2.axios/1.guide/2.configuration.md index 7ddb4c092..020e00bb2 100644 --- a/docs/content/3.plugins/2.axios/1.guide/2.configuration.md +++ b/docs/content/3.plugins/2.axios/1.guide/2.configuration.md @@ -151,6 +151,13 @@ In addition to [axios request options](https://github.com/axios/axios#request-co You can set this option to any one of the following string values: - `insert` + - `fresh` + + With `fresh`, the response data replaces all existing records of the entity in the store — records that are no longer returned by the API are removed. This makes the API response the single source of truth. + + ```js + useAxiosRepo(User).api().get('/api/users', { persistBy: 'fresh' }) + ``` ### `save` diff --git a/packages/axios/src/api/Response.ts b/packages/axios/src/api/Response.ts index 5d96dcc76..1304fecec 100644 --- a/packages/axios/src/api/Response.ts +++ b/packages/axios/src/api/Response.ts @@ -135,6 +135,6 @@ export class Response { * Pinia ORM persist methods. */ protected validatePersistAction (action: string): action is PersistMethods { - return ['save', 'insert'].includes(action) + return ['save', 'insert', 'fresh'].includes(action) } } diff --git a/packages/axios/src/types/config.ts b/packages/axios/src/types/config.ts index 70708f57a..23c27432d 100644 --- a/packages/axios/src/types/config.ts +++ b/packages/axios/src/types/config.ts @@ -1,7 +1,7 @@ import type { Element } from 'pinia-orm' import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' -export type PersistMethods = 'save' | 'insert' +export type PersistMethods = 'save' | 'insert' | 'fresh' export type PersistOptions = { [P in PersistMethods]?: string[] } diff --git a/packages/axios/test/feature/Request_PersistBy.spec.ts b/packages/axios/test/feature/Request_PersistBy.spec.ts new file mode 100644 index 000000000..efd69c823 --- /dev/null +++ b/packages/axios/test/feature/Request_PersistBy.spec.ts @@ -0,0 +1,76 @@ +import axios from 'axios' +import MockAdapter from 'axios-mock-adapter' +import { Model, useRepo } from 'pinia-orm' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { assertState } from '../helpers' +import { useAxiosRepo } from '../../src' + +describe('Feature - Request - Persist By', () => { + let mock: MockAdapter + + class User extends Model { + static entity = 'users' + + static fields () { + return { + id: this.attr(null), + name: this.attr(''), + } + } + } + + beforeEach(() => { + mock = new MockAdapter(axios) + }) + afterEach(() => { + mock.reset() + }) + + it('replaces all existing records with `persistBy: fresh`', async () => { + useRepo(User).save([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Deleted Elsewhere' }, + ]) + + mock.onGet('/users').reply(200, [ + { id: 1, name: 'John Doe' }, + { id: 3, name: 'Jane Doe' }, + ]) + + const userStore = useAxiosRepo(User) + + const result = await userStore.api().get('/users', { + persistBy: 'fresh', + }) + + expect(result.entities).toHaveLength(2) + + assertState({ + users: { + 1: { id: 1, name: 'John Doe' }, + 3: { id: 3, name: 'Jane Doe' }, + }, + }) + }) + + it('inserts records with `persistBy: insert`', async () => { + useRepo(User).save({ id: 1, name: 'John Doe' }) + + mock.onGet('/users').reply(200, [ + { id: 2, name: 'Jane Doe' }, + ]) + + const userStore = useAxiosRepo(User) + + await userStore.api().get('/users', { + persistBy: 'insert', + }) + + assertState({ + users: { + 1: { id: 1, name: 'John Doe' }, + 2: { id: 2, name: 'Jane Doe' }, + }, + }) + }) +})