/* eslint-disable @typescript-eslint/no-explicit-any */ import { b64EncodeUnicode } from '@warkypublic/artemis-kit/base64'; const TOKEN_KEY = 'gridler_golang_restapi_v2_token'; export type APIOptionsType = { autocreate?: boolean; autoref?: boolean; baseurl?: string; getAPIProvider?: () => { provider: string; providerKey: string }; getAuthToken?: () => string; operations?: Array; postfix?: string; prefix?: string; requestTimeoutSec?: number; }; export interface APIResponse { errmsg: string; payload?: any; retval: number; } export interface FetchAPIOperation { name?: string; op?: string; type: GoAPIHeaderTypes; //x-fieldfilter value: string; } /** * @description Types for the Go Rest API headers * @typedef {String} GoAPIEnum */ export type GoAPIEnum = | 'advsql' | 'api-key' | 'api-range-from' | 'api-range-size' | 'api-range-total' | 'api-src' | 'api' | 'association_autocreate' | 'association_autoupdate' | 'association-update' | 'cql-sel' | 'cursor-backward' // For x cursor-backward header | 'cursor-forward' // For x cursor-forward header | 'custom-sql-join' | 'custom-sql-or' | 'custom-sql-w' | 'detailapi' | 'distinct' | 'expand' | 'fetch-rownumber' | 'fieldfilter' | 'fieldfilter' | 'files' //For x files header | 'func' | 'limit' | 'no-return' | 'not-select-fields' | 'offset' | 'parm' | 'pkrow' | 'preload' | 'searchand' | 'searchfilter' | 'searchfilter' | 'searchop' | 'searchop' | 'searchor' | 'select-fields' | 'simpleapi' | 'skipcache' | 'skipcount' | 'sort'; export type GoAPIHeaderKeys = `x-${GoAPIEnum}`; export type GoAPIHeaderTypes = GoAPIEnum & string; export interface GoAPIOperation { name?: string; op?: string; type: GoAPIHeaderTypes; //x-fieldfilter value: string; } export interface MetaData { limit?: number; offset?: number; total?: number; } /** * Builds an array of objects by encoding specific values and setting headers. * * @param {Array} ops - The array of FetchAPIOperation objects to be built. * @param {Headers} [headers] - Optional headers to be set. * @return {Array} - The built array of FetchAPIOperation objects. */ const buildGoAPIOperation = ( ops: Array, headers?: Headers ): Array => { const newops = [...ops.filter((i) => i !== undefined && i.type !== undefined)]; for (let i = 0; i < newops.length; i++) { if (!newops[i].name || newops[i].name === '') { newops[i].name = ''; } if (newops[i].type === 'files' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'advsql' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'custom-sql-or' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'custom-sql-join' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'not-select-fields' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'custom-sql-w' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'select-fields' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (newops[i].type === 'cql-sel' && !newops[i].value.startsWith('__')) { newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__`; } if (headers) { if (!newops || newops.length === 0) { headers.set(`x-limit`, '10'); } if (newops[i].type === 'association_autoupdate') { headers.set(`association_autoupdate`, newops[i].value ?? '1'); } if (newops[i].type === 'association_autocreate') { headers.set(`association_autocreate`, newops[i].value ?? '1'); } if ( newops[i].type === 'searchop' || newops[i].type === 'searchor' || newops[i].type === 'searchand' ) { headers.set( encodeURIComponent(`x-${newops[i].type}-${newops[i].op}-${newops[i].name}`), String(newops[i].value) ); } else { headers.set( encodeURIComponent( `x-${newops[i].type}${newops[i].name && newops[i].name !== '' ? '-' + newops[i].name : ''}` ), String(newops[i].value) ); } } } return newops; }; /** * Retrieves the headers from an array of FetchAPIOperation objects and returns them as an object. * * @param {Array} ops - The array of FetchAPIOperation objects. * @return {{ [key: string]: string }} - The headers as an object with string keys and string values. */ const GoAPIHeaders = ( ops: Array, headers?: Headers ): { [key: string]: string } => { const head = new Headers(); const headerlist: Record = {}; const authToken = getAuthToken?.(); if (authToken && authToken !== '') { head.set('Authorization', `Token ${authToken}`); } else { const token = getAuthToken(); if (token) { head.set('Authorization', `Token ${token}`); } } if (headers) { headers.forEach((v, k) => { head.set(k, v); }); } const distinctOperations: Array = []; for (const value of ops?.filter((val) => !!val) ?? []) { const index = distinctOperations.findIndex( (searchValue) => searchValue.name === value.name && searchValue.type === value.type ); if (index === -1) { distinctOperations.push(value); } else { distinctOperations[index] = value; } } buildGoAPIOperation(distinctOperations, head); head?.forEach((v, k) => { headerlist[k] = v; }); if (headers) { for (const key of Object.keys(headerlist)) { headers.set(key, headerlist[key]); } } return headerlist; }; const callbacks = { getAuthToken: () => { if (localStorage) { const token = localStorage.getItem(TOKEN_KEY); if (token) { return token; } } return undefined; }, }; /** * Retrieves the authentication token from local storage. * * @return {string | undefined} The authentication token if found, otherwise undefined */ const getAuthToken = () => callbacks?.getAuthToken?.(); const setAuthTokenCallback = (cb: () => string) => { callbacks.getAuthToken = cb; return callbacks.getAuthToken; }; /** * Sets the authentication token in the local storage. * * @param {string} token - The authentication token to be set. */ const setAuthToken = (token: string) => { if (localStorage) { localStorage.setItem(TOKEN_KEY, token); } }; export { buildGoAPIOperation, getAuthToken, GoAPIHeaders, setAuthToken, setAuthTokenCallback };