diff --git a/packages/axios/src/api/Request.ts b/packages/axios/src/api/Request.ts index a595adf30..0ad749c52 100644 --- a/packages/axios/src/api/Request.ts +++ b/packages/axios/src/api/Request.ts @@ -34,14 +34,14 @@ export class Request { * Get the axios client. */ get axios (): AxiosInstance { - this.repository.axios = this.repository.axios ?? this.repository.config.axiosApi.axios - if (!this.repository.axios) { + const axios = this.repository.axios + if (!axios) { throw new Error( '[Pinia ORM Axios] The axios instance is not registered. Please register the axios instance to the repository.', ) } - return this.repository.axios + return axios } /** diff --git a/packages/axios/src/repository/AxiosRepository.ts b/packages/axios/src/repository/AxiosRepository.ts index 6902d8a8b..8cd8afbad 100644 --- a/packages/axios/src/repository/AxiosRepository.ts +++ b/packages/axios/src/repository/AxiosRepository.ts @@ -1,20 +1,32 @@ -import type { Database, Model } from 'pinia-orm' -import type { Pinia } from 'pinia' -import { Repository, config } from 'pinia-orm' +import type { Model } from 'pinia-orm' +import { Repository } from 'pinia-orm' import type { AxiosInstance } from 'axios' import { useAxiosApi } from '../index' import type { Config, GlobalConfig } from '../types/config' export class AxiosRepository extends Repository { - axios: AxiosInstance - globalApiConfig: GlobalConfig - apiConfig: Config + apiConfig: Config = {} - constructor (database: Database, pinia?: Pinia) { - super(database, pinia) - this.axios = config?.axiosApi?.axios || null - this.globalApiConfig = config?.axiosApi || {} - this.apiConfig = {} + protected axiosInstance: AxiosInstance | null = null + + /** + * The axios instance from the plugin config, unless an instance was set + * explicitly via `setAxios`. The plugin config is resolved lazily because + * plugins are registered after the repository has been constructed. + */ + get axios (): AxiosInstance | null { + return this.axiosInstance ?? this.globalApiConfig.axios ?? null + } + + set axios (axios: AxiosInstance | null) { + this.axiosInstance = axios + } + + /** + * The global plugin config passed to `createPiniaOrmAxios`. + */ + get globalApiConfig (): GlobalConfig { + return this.config.axiosApi ?? {} } api () { diff --git a/packages/axios/test/feature/Request_GlobalConfig.spec.ts b/packages/axios/test/feature/Request_GlobalConfig.spec.ts new file mode 100644 index 000000000..0f49a7625 --- /dev/null +++ b/packages/axios/test/feature/Request_GlobalConfig.spec.ts @@ -0,0 +1,66 @@ +import axios from 'axios' +import MockAdapter from 'axios-mock-adapter' +import { createPinia, setActivePinia } from 'pinia' +import { createApp } from 'vue' +import { Model, config, createORM } from 'pinia-orm' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { assertState } from '../helpers' +import { createPiniaOrmAxios, useAxiosRepo } from '../../src' + +describe('Feature - Request - Global Config', () => { + 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('applies global plugin options like baseURL and dataKey on first repository use', async () => { + // Simulate a freshly booted app where no repository has been used yet, + // so the axios plugin has not been applied to the global config. + delete config.axiosApi + + const app = createApp({}) + const pinia = createPinia() + pinia.use(createORM({ + plugins: [ + createPiniaOrmAxios({ + axios, + baseURL: 'https://example.com/api', + dataKey: 'data', + }), + ], + })) + app.use(pinia) + setActivePinia(pinia) + + mock.onGet('https://example.com/api/users').reply(200, { + data: [{ id: 1, name: 'John Doe' }], + }) + + const userStore = useAxiosRepo(User) + + await userStore.api().get('/users') + + expect(mock.history.get[0].baseURL).toBe('https://example.com/api') + + assertState({ + users: { + 1: { id: 1, name: 'John Doe' }, + }, + }) + }) +})