262 lines
7.0 KiB
TypeScript
262 lines
7.0 KiB
TypeScript
/* 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<FetchAPIOperation>;
|
|
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<FetchAPIOperation>} ops - The array of FetchAPIOperation objects to be built.
|
|
* @param {Headers} [headers] - Optional headers to be set.
|
|
* @return {Array<FetchAPIOperation>} - The built array of FetchAPIOperation objects.
|
|
*/
|
|
const buildGoAPIOperation = (
|
|
ops: Array<FetchAPIOperation>,
|
|
headers?: Headers
|
|
): Array<FetchAPIOperation> => {
|
|
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<FetchAPIOperation>} 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<FetchAPIOperation>,
|
|
headers?: Headers
|
|
): { [key: string]: string } => {
|
|
const head = new Headers();
|
|
const headerlist: Record<string, string> = {};
|
|
|
|
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<FetchAPIOperation> = [];
|
|
|
|
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 };
|