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, path, payload, responsedata = {}, options = {}) { 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'; const config = { baseURL, 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; 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)) { 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) 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); console.log('error.response=', error.response); } 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