import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios'; import axios from 'axios'; // import LoginModule from '../Modules/Auth/LoginStore' import { toolsext } from '@src/store/Modules/toolsext'; import { serv_constants } from '@src/store/Modules/serv_constants'; import { useGlobalStore } from '@store/globalStore'; import { useUserStore } from '@store/UserStore'; import { tools } from '@src/store/Modules/tools'; import * as Types from './ApiTypes'; import type { Observable } from 'rxjs'; import { from } from 'rxjs'; import { mergeMap, toArray } from 'rxjs/operators'; export let API_URL = ''; export const axiosInstance: AxiosInstance = axios.create({ baseURL: API_URL, headers: { Accept: 'application/json', }, }); /*axiosInstance.interceptors.response.use( (response) => { if (import.meta.env.VITE_DEBUG === '1') console.log(response); return response; }, (error) => { const globalStore = useGlobalStore(); // console.log('error', error) if (error.response) { if (import.meta.env.VITE_DEBUG === '1') console.log('Status = ', error.response.status); console.log('Request Error: ', error.response); if (error.response.status !== 0) { globalStore.setStateConnection('online'); } else { globalStore.setStateConnection('offline'); } } else { globalStore.setStateConnection('offline'); } return Promise.reject(error); } ); */ export const addAuthHeaders = () => { // axiosInstance.defaults.headers.Authorization = `Bearer ${LoginModule.userInfos.userToken}` }; //export const removeAuthHeaders = () => { // delete axiosInstance.defaults.headers.Authorization //} async function generateStream( path: string, payload: any, config?: RequestInit, options?: any ): Promise> { const userStore = useUserStore(); const mieiparam: any = { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-auth': userStore.x_auth_token, 'x-refrtok': userStore.refreshToken, }, body: JSON.stringify(payload), signal: options?.signal, ...config, }; console.log('marams: ', mieiparam); const response = await fetch(path, mieiparam); console.log('USCITA DA FETCH... !!!!!'); if (response.status !== 200) throw new Error(response.status.toString()); return getIterableStream(response); } function getIterableStream(stream: NodeJS.ReadableStream): AsyncIterable { return { [Symbol.asyncIterator](): AsyncIterator { let buffer = ''; return { async next(): Promise> { while (true) { const chunk = await new Promise((resolve, reject) => { stream.once('data', (data: Buffer) => resolve(data.toString())); stream.once('error', (err) => reject(err)); stream.once('end', () => resolve('')); }); buffer += chunk; if (buffer.includes('\n\n')) { const event = buffer.slice(0, buffer.indexOf('\n\n')); buffer = buffer.slice(buffer.indexOf('\n\n') + 2); try { return { value: JSON.parse(event.slice('data: '.length)), done: false }; } catch (error) { console.error('Error parsing event data:', error); } } else if (chunk === '') { return { value: undefined, done: true }; } } }, }; }, }; } // Funzione helper per inviare la richiesta HTTP async function Request( type: string, path: string, payload: any, responsedata = {}, options: any = {} ) { const userStore = useUserStore(); const globalStore = useGlobalStore(); const baseURL = globalStore.getServerHost(); try { if (tools.isDebug()) console.log('Axios Request', path, type, tools.notshowPwd(payload)); const isFormData = type === 'postFormData'; let config: AxiosRequestConfig = { baseURL, timeout: 60000, headers: { 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json', 'x-auth': userStore.x_auth_token, 'x-refrtok': userStore.refreshToken, }, ...responsedata, }; // ✅ AGGIUNGI IL TIMEOUT DALLE OPTIONS if (options?.timeout) { config.timeout = options.timeout; // in millisecondi (es. 300000 = 5 minuti) } if (options?.stream) config.responseType = 'stream'; let response: any; const method = type.toLowerCase(); // Gestione dinamica del metodo HTTP if (['post', 'put', 'patch'].includes(method)) { if (options?.stream) { // Gestione stream (riconosciuta come promise) const stream = await generateStream(path, payload, config, options); return new Promise((resolve, reject) => { from(stream) .pipe( mergeMap((event) => from([event])), toArray() ) .subscribe( (data) => { console.log('Received data:', data); resolve({ data, status: response.status, statusText: response.statusText, headers: response.headers, config: response.config, }); }, (error) => { console.error('Stream error:', error); reject(error); }, () => console.log('Stream completed') ); }); } else { response = await axiosInstance[method](path, payload, config); } } else if (['get', 'delete'].includes(method)) { config.params = payload; config.headers = { ...config.headers, 'Content-Type': 'application/json', }; //console.log('FACCIO LA CHIAMATA axiosInstance' + method) //console.log('. path', path); //console.log('. config', config); response = await axiosInstance[method](path, config ? config : {}); // ✅ CORRETTO //console.log('. USCITO DALLA CHIAMATA !', response); /* response = await axiosInstance[method](path, { baseURL, params: payload, headers: { 'Content-Type': 'application/json', 'x-auth': userStore.x_auth_token, 'x-refrtok': userStore.refreshToken, }, ...responsedata, });*/ } else if (type === 'postFormData') { response = await axiosInstance.post(path, payload, config); } else { throw new Error(`Unsupported request type: ${type}`); } // Gestione aggiornamento token se necessario const setAuthToken = path === '/updatepwd' || path === '/users/login'; if ( response && response.status === 200 && (setAuthToken || path === '/users/login') ) { const x_auth_token = String(response.headers['x-auth'] || ''); const refreshToken = String(response.headers['x-refrtok'] || ''); if (!x_auth_token) { userStore.setServerCode(toolsext.ERR_AUTHENTICATION); } if (setAuthToken) { userStore.updatePwd(x_auth_token, refreshToken); localStorage.setItem(toolsext.localStorage.token, x_auth_token); localStorage.setItem(toolsext.localStorage.refreshToken, refreshToken); } userStore.setAuth(x_auth_token, refreshToken); localStorage.setItem(toolsext.localStorage.token, x_auth_token); localStorage.setItem(toolsext.localStorage.refreshToken, refreshToken); } globalStore.setStateConnection('online'); userStore.setServerCode(tools.OK); return new Types.AxiosSuccess(response.data, response.status); } catch (error) { // Aggiornamento asincrono dello stato di connessione (setTimeout per dare tempo a eventuali animazioni) console.error('Errore funzione Request', error) setTimeout(() => { if (['get'].includes(type.toLowerCase())) { globalStore.connData.downloading_server = globalStore.connData.downloading_server === 1 ? -1 : globalStore.connData.downloading_server; } else { globalStore.connData.uploading_server = globalStore.connData.uploading_server === 1 ? -1 : globalStore.connData.uploading_server; globalStore.connData.downloading_server = globalStore.connData.downloading_server === 1 ? -1 : globalStore.connData.downloading_server; } }, 1000); if (import.meta.env.DEV) { console.log('ERROR using', path); if (error && error.response) { // console.log('error.response=', JSON.stringify(error.response, null, 2)); } } let mycode = 0; if (error.response) { const code = error.response.data?.code || 0; mycode = code; userStore.setServerCode(mycode); return Promise.reject( new Types.AxiosError(error.response.status, error.response.data, code) ); } return Promise.reject(new Types.AxiosError(0, null, mycode, error)); } } export default Request;