You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
fms/api/schema-client.ts

131 lines
3.5 KiB

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<string, any> = {}
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<string, any> = {
...(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()
}
}