@pinia-orm/axios-edge
Version:
Axios plugin for pinia-orm
281 lines (272 loc) • 7.63 kB
JavaScript
'use strict';
const piniaOrm = require('pinia-orm');
const pinia = require('pinia');
class Response {
/**
* The repository that called the request.
*/
repository;
/**
* The request configuration.
*/
config;
/**
* The axios response instance.
*/
response;
/**
* Entities created by Pinia ORM.
*/
entities = null;
/**
* Whether if response data is saved to the store or not.
*/
isSaved = false;
/**
* Create a new response instance.
*/
constructor(repository, config, response) {
this.repository = repository;
this.config = config;
this.response = response;
}
/**
* Save response data to the store.
*/
async save() {
const data = this.getDataFromResponse();
if (!this.validateData(data)) {
console.warn(
"[Pinia ORM Axios] The response data could not be saved to the store because it is not an object or an array. You might want to use `dataTransformer` option to handle non-array/object response before saving it to the store."
);
return;
}
let method = this.config.persistBy || "save";
if (!this.validatePersistAction(method)) {
console.warn(
'[Pinia ORM Axios] The "persistBy" option configured is not a recognized value. Response data will be persisted by the default `save` method.'
);
method = "save";
}
const result = await this.repository[method](data);
this.entities = Array.isArray(result) ? result : [result];
this.isSaved = true;
}
/**
* Delete the entity record where the `delete` option is configured.
*/
async delete() {
if (this.config.delete === void 0) {
throw new Error(
"[Pinia ORM Axios] Could not delete records because the `delete` option is not set."
);
}
await this.repository.query().destroy(this.config.delete);
}
/**
* Get the response data from the axios response object. If a `dataTransformer`
* option is configured, it will be applied to the response object. If the
* `dataKey` option is configured, it will return the data from the given
* property within the response body.
*/
getDataFromResponse() {
if (this.config.dataTransformer) {
return this.config.dataTransformer(this.response);
}
if (this.config.dataKey) {
return this.response.data[this.config.dataKey];
}
return this.response.data;
}
/**
* Get persist options if any set in config.
*/
// protected getPersistOptions (): PersistOptions | undefined {
// const persistOptions = this.config.persistOptions
//
// if (!persistOptions || typeof persistOptions !== 'object') {
// return
// }
//
// return Object.keys(persistOptions)
// .filter(this.validatePersistAction) // Filter to avoid polluting the payload.
// .reduce((carry, key) => {
// carry[key] = persistOptions[key]
// return carry
// }, {} as PersistOptions)
// }
/**
* Validate the given data to ensure the Pinia ORM persist methods accept it.
*/
validateData(data) {
return data !== null && typeof data === "object";
}
/**
* Validate the given string as to ensure it correlates with the available
* Pinia ORM persist methods.
*/
validatePersistAction(action) {
return ["save", "insert"].includes(action);
}
}
class Request {
/**
* The repository class.
*/
repository;
/**
* The default config.
*/
config = {
save: true
};
/**
* Create a new api instance.
*/
constructor(repository) {
this.repository = repository;
this.registerActions();
}
/**
* Get the axios client.
*/
get axios() {
this.repository.axios = this.repository.axios ?? this.repository.config.axiosApi.axios;
if (!this.repository.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;
}
/**
* Register actions from the repository config.
*/
registerActions() {
const actions = { ...this.repository.config.axiosApi?.actions, ...this.repository.getModel().$config()?.axiosApi?.actions };
if (!actions) {
return;
}
for (const name in actions) {
const action = actions[name];
typeof action === "function" ? this.registerFunctionAction(name, action) : this.registerObjectAction(name, action);
}
}
/**
* Register the given object action.
*/
registerObjectAction(name, action) {
this[name] = (config) => {
return this.request({ ...action, ...config });
};
}
/**
* Register the given function action.
*/
registerFunctionAction(name, action) {
this[name] = action.bind(this);
}
/**
* Perform a get request.
*/
get(url, config = {}) {
return this.request({ method: "get", url, ...config });
}
/**
* Perform a post request.
*/
post(url, data = {}, config = {}) {
return this.request({ method: "post", url, data, ...config });
}
/**
* Perform a put request.
*/
put(url, data = {}, config = {}) {
return this.request({ method: "put", url, data, ...config });
}
/**
* Perform a patch request.
*/
patch(url, data = {}, config = {}) {
return this.request({ method: "patch", url, data, ...config });
}
/**
* Perform a delete request.
*/
delete(url, config = {}) {
return this.request({ method: "delete", url, ...config });
}
/**
* Perform an api request.
*/
async request(config) {
const requestConfig = this.createConfig(config);
const axiosResponse = await this.axios.request(requestConfig);
return this.createResponse(axiosResponse, requestConfig);
}
/**
* Create a new config by merging the global config, the repository config,
* and the given config.
*/
createConfig(config) {
return {
...this.config,
...this.repository.globalApiConfig,
...this.repository.apiConfig,
...config
};
}
/**
* Create a new response instance by applying a few initialization processes.
* For example, it saves response data if `save` option id set to `true`.
*/
async createResponse(axiosResponse, config) {
const response = new Response(this.repository, config, axiosResponse);
if (config.delete !== void 0) {
await response.delete();
return response;
}
config.save && await response.save();
return response;
}
}
class AxiosRepository extends piniaOrm.Repository {
axios;
globalApiConfig;
apiConfig;
constructor(database, pinia) {
super(database, pinia);
this.axios = piniaOrm.config?.axiosApi?.axios || null;
this.globalApiConfig = piniaOrm.config?.axiosApi || {};
this.apiConfig = {};
}
api() {
return useAxiosApi(this);
}
setAxios(axios) {
this.axios = axios;
return this;
}
}
function useAxiosApi(repository) {
return new Request(repository);
}
function useAxiosRepo(model) {
const pinia$1 = pinia.getActivePinia();
AxiosRepository.useModel = model;
return piniaOrm.useRepo(AxiosRepository, pinia$1);
}
function createPiniaOrmAxios(axiosConfig) {
return piniaOrm.definePiniaOrmPlugin((context) => {
context.config.axiosApi = axiosConfig;
return context;
});
}
const piniaOrmPluginAxios = createPiniaOrmAxios();
exports.AxiosRepository = AxiosRepository;
exports.Request = Request;
exports.Response = Response;
exports.createPiniaOrmAxios = createPiniaOrmAxios;
exports.piniaOrmPluginAxios = piniaOrmPluginAxios;
exports.useAxiosApi = useAxiosApi;
exports.useAxiosRepo = useAxiosRepo;