/* eslint-disable no-magic-numbers */ /* eslint-disable no-param-reassign */ import { pluginSchema } from '@/models/pluginSchema'; import { axiosInstance } from '@/services/api/utils/axiosInstance'; import type { MinervaPlugin } from '@/types/models'; import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; import { createAsyncThunk } from '@reduxjs/toolkit'; import axios from 'axios'; import { getErrorMessage } from '@/utils/getErrorMessage'; import { ThunkConfig } from '@/types/store'; import { getPluginHashWithoutPrefix } from '@/utils/plugins/getPluginHashWithoutPrefix'; import { apiPath } from '../apiPath'; import { PLUGIN_FETCHING_ALL_ERROR_PREFIX, PLUGIN_INIT_FETCHING_ERROR_PREFIX, PLUGIN_REGISTER_ERROR_PREFIX, } from './plugins.constants'; type RegisterPlugin = { hash: string; pluginUrl: string; pluginName: string; pluginVersion: string; isPublic: boolean; extendedPluginName: string; }; export const registerPlugin = createAsyncThunk< MinervaPlugin | undefined, RegisterPlugin, ThunkConfig >( 'plugins/registerPlugin', async ( { hash, isPublic, pluginName, pluginUrl, pluginVersion, extendedPluginName }, { rejectWithValue }, ) => { try { const hashWihtoutPrefix = getPluginHashWithoutPrefix(hash); const payload = { hash: hashWihtoutPrefix, url: pluginUrl, name: pluginName, version: pluginVersion, isPublic: isPublic.toString(), } as const; const response = await axiosInstance.post<MinervaPlugin>( apiPath.registerPluign(), new URLSearchParams(payload), { withCredentials: true, }, ); const isDataValid = validateDataUsingZodSchema(response.data, pluginSchema); if (isDataValid) { return { ...response.data, hash, name: extendedPluginName, }; } return undefined; } catch (error) { const errorMessage = getErrorMessage({ error, prefix: PLUGIN_REGISTER_ERROR_PREFIX }); return rejectWithValue(errorMessage); } }, ); type GetInitPluginsProps = { pluginsId: string[]; setHashedPlugin: ({ pluginUrl, pluginScript, }: { pluginUrl: string; pluginScript: string; }) => void; }; export const getInitPlugins = createAsyncThunk<void, GetInitPluginsProps, ThunkConfig>( 'plugins/getInitPlugins', // eslint-disable-next-line consistent-return async ({ pluginsId, setHashedPlugin }, { rejectWithValue }) => { try { /* eslint-disable no-restricted-syntax, no-await-in-loop */ for (const pluginId of pluginsId) { const hash = getPluginHashWithoutPrefix(pluginId); const res = await axiosInstance<MinervaPlugin>(apiPath.getPlugin(hash)); const isDataValid = validateDataUsingZodSchema(res.data, pluginSchema); if (isDataValid) { const { urls } = res.data; const scriptRes = await axios(urls[0]); let pluginScript = scriptRes.data; setHashedPlugin({ pluginUrl: urls[0], pluginScript }); pluginScript += `//# sourceURL=${urls[0]}`; /* eslint-disable no-new-func */ const loadPlugin = new Function(pluginScript); loadPlugin(); } } } catch (error) { const errorMessage = getErrorMessage({ error, prefix: PLUGIN_INIT_FETCHING_ERROR_PREFIX }); return rejectWithValue(errorMessage); } }, ); export const getAllPlugins = createAsyncThunk<MinervaPlugin[], void, ThunkConfig>( 'plugins/getAllPlugins', async (_, { rejectWithValue }) => { try { const response = await axiosInstance.get<MinervaPlugin[]>(apiPath.getAllPlugins()); const isPluginDataValid = (pluginData: MinervaPlugin): boolean => validateDataUsingZodSchema(pluginData, pluginSchema); const validPlugins = response.data.filter(isPluginDataValid); return validPlugins; } catch (error) { const errorMessage = getErrorMessage({ error, prefix: PLUGIN_FETCHING_ALL_ERROR_PREFIX }); return rejectWithValue(errorMessage); } }, );