UNPKG

@rws-framework/client

Version:

This package provides the core client-side framework for Realtime Web Suit (RWS), enabling modular, asynchronous web components, state management, and integration with backend services. It is located in `.dev/client`.

162 lines (132 loc) 5.88 kB
import TheService from './_service'; import axios from 'axios'; //@4DI import ConfigService, { ConfigServiceInstance } from './ConfigService'; import { backend } from './_api/backend'; import { calls } from './_api/calls'; interface RequestOptions { method?: string; headers: HeadersInit; body?: string; } interface IAPIOptions { headers?: Headers, routeParams?: { [key: string]: string }, queryParams?: { [key: string]: string } } interface IHTTProute<P = { [key: string]: any }> { name: string; path: string | string[]; method: string; noParams?: boolean; options?: any; plugins?: P } interface IPrefixedHTTProutes<P = { [key: string]: any }> { prefix: string; controllerName: string; exportAutoRoutes?: boolean, routes: IHTTProute<P>[]; } type IBackendRoute = IHTTProute | IPrefixedHTTProutes; interface UploadFunctionOptions { headers?: Record<string, string>; method?: 'POST' | 'PUT' | 'PATCH'; onProgress?: (progress: number) => void; } class ApiService extends TheService { static _DEFAULT: boolean = true; public token?: string; public apiKey?: string; private defaultUploadOptions: () => UploadFunctionOptions = () => ({ headers: this.getAuthHeaders(), method: 'POST' as const, onProgress: (progress: number) => null, }); constructor(@ConfigService public config: ConfigServiceInstance) { super(); } private getAuthHeaders(): Record<string, string> { const headers: Record<string, string> = {}; if (this.token) { headers['Authorization'] = `Bearer ${this.token}`; } if (this.apiKey) { headers['x-api-key'] = this.apiKey; } return headers; } public setToken(token: string) { this.token = token; } public setApiKey(apiKey: string) { this.apiKey = apiKey; } public async isGetTargetReachable(url: string, options: IAPIOptions = {}): Promise<boolean> { try { return !!(await calls.pureGet.bind(this)(url, options)); } catch (error) { return false; } } async uploadFiles<T = any, P = any>(url: string, files: Record<string, File>, payload: P = undefined, uploadOptions: UploadFunctionOptions = this.defaultUploadOptions()): Promise<T> { const formData = new FormData(); // Add files to FormData Object.entries(files).forEach(([key, file]) => { formData.append(key, file); }); // Add payload data to FormData if(payload){ Object.entries(payload).forEach(([key, value]) => { if (value !== undefined && value !== null) { formData.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value)); } }); } const options = { ...this.defaultUploadOptions(), ...uploadOptions }; const method = options.method || 'POST'; const axiosConfig = { method: method.toLowerCase() as any, url, data: formData, headers: { 'Content-Type': 'multipart/form-data', ...options.headers }, onUploadProgress: (progressEvent: any) => { console.log({progressEvent}); if (options.onProgress && progressEvent.total) { const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total); options.onProgress(progress); } } }; console.log({axiosConfig}); return (await axios(axiosConfig)).data; } public pureGet = calls.pureGet; public get = calls.get; public post = calls.post; public put = calls.put; public delete = calls.delete; public back = { get: async <T>(routeName: string, options?: IAPIOptions, token?: string): Promise<T> => calls.get.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), options) as Promise<T>, post: async <T, P extends object = object>(routeName: string, payload?: P, options?: IAPIOptions): Promise<T> => calls.post.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), payload, options) as Promise<T>, put: async <T, P extends object = object>(routeName: string, payload: P, options?: IAPIOptions): Promise<T> => calls.put.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), payload, options) as Promise<T>, delete: async <T>(routeName: string, options?: IAPIOptions): Promise<T> => calls.delete.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), options) as Promise<T>, uploadFiles: async <T = any, P = any>(routeName: string, files: Record<string, File>, payload: P = undefined, uploadOptions: UploadFunctionOptions = this.defaultUploadOptions(), options: IAPIOptions = {}): Promise<T> => this.uploadFiles<T, P>(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), files, payload, uploadOptions), }; async getResource(resourceName: string): Promise<any> { return calls.get.bind(this)(`${this.config.get('backendUrl')}${this.config.get('apiPrefix') || ''}/api/rws/resource/${resourceName}`) as Promise<ITypesResponse> } getBackendUrl: (routeName: string, params?: { [key: string]: string }, queryParams?: { [key: string]: string }) => string = backend.getBackendUrl.bind(this); } export default ApiService.getSingleton(); export { IBackendRoute, RequestOptions, ApiService as ApiServiceInstance, IHTTProute, IPrefixedHTTProutes, IAPIOptions, UploadFunctionOptions };