import {AuthenticationInterface} from "./authentication"; export enum Method { GET = 'GET', POST = 'POST', PUT = 'PUT', PATCH = 'PATCH', } export let hasQuery = (method: Method) => { return Method.GET === method } export interface SchemaInterface { url: string, method: Method contentType: string | null } export class Context { debouncing?: number useMemory?: boolean memoryKey?: string } interface SchemaClientOptionsInterface { baseUrl?: string authentication?: AuthenticationInterface } export class SchemaClient { baseUrl: string | null = null authentication: AuthenticationInterface | null = null context: Context | null = null memory: Record = {} constructor(options: SchemaClientOptionsInterface) { this.baseUrl = options.baseUrl || null this.authentication = options.authentication || null } debouncing(time: number) { let context = this.grabContext() context.debouncing = time return this } useMemory(key?: string) { let context = this.grabContext() context.useMemory = true context.memoryKey = key return this } async send(schema: SchemaInterface, data: any) { if (this.baseUrl === null) { throw new Error('Base url not defined!'); } let context = this.context this.context = null if (context?.useMemory) { let memoryKey = context?.memoryKey || schema.url if (typeof this.memory[memoryKey] !== 'undefined') { return this.memory[memoryKey] } } let url = `${this.baseUrl}${schema.url}` let {url: preparedUrl, data: preparedData} = this.processAttributes(url, data) if (hasQuery(schema.method)) { preparedUrl += '?' + new URLSearchParams(preparedData) } let token = '' if (typeof localStorage !== 'undefined') { let tokenId = localStorage.getItem('token') token = localStorage.getItem(tokenId || '') || '' } let headers: Record = { ...(schema.contentType ? {'Content-Type': schema.contentType} : {}), 'X-Plugin-Token': 'passw0rd', } if (this.authentication) { headers[this.authentication.key] = this.authentication.token(); } let response = await fetch(preparedUrl, { method: schema.method.toString(), headers, body: hasQuery(schema.method) ? null : JSON.stringify(preparedData) }); let responseData = response.headers.get('Content-Type')?.toString().includes('application/json') ? await response.json() : await response.text() let result = {responseData: responseData, headers: response.headers} if (context?.useMemory) { let memoryKey = context?.memoryKey || schema.url this.memory[memoryKey] = result } return result } private processAttributes(url: string, data: any) { const preparedData = data for (const key in data) { if (url.indexOf('{' + key + '}') > -1) { url = url.replace('{' + key + '}', preparedData[key]) delete preparedData[key] } } return {url, data: preparedData } } private grabContext(): Context { if (this.context) { return this.context } return this.context = new Context() } }