From 7f2584fe7697fbe4861420c623ca83f860720aef Mon Sep 17 00:00:00 2001 From: Gregor Becker Date: Sun, 19 Jul 2026 23:38:39 +0200 Subject: [PATCH] feat(axios): support persistBy fresh to replace store data The response of an api call can now replace all existing records of the entity by setting persistBy to 'fresh', making the api response the single source of truth. closes #1885 --- .../2.axios/1.guide/2.configuration.md | 7 ++ packages/axios/src/api/Response.ts | 2 +- packages/axios/src/types/config.ts | 2 +- .../test/feature/Request_PersistBy.spec.ts | 76 +++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 packages/axios/test/feature/Request_PersistBy.spec.ts 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' }, + }, + }) + }) +})