Javascript utility

Constant

interface languageMap {
  [key: string]: string | undefined;
}

export const programmingLanguages: languageMap = {
  javascript: ".js",
  python: ".py",
  java: ".java",
  c: ".c",
  cpp: ".cpp",
  "c++": ".cpp",
  "c#": ".cs",
  ruby: ".rb",
  php: ".php",
  swift: ".swift",
  "objective-c": ".m",
  kotlin: ".kt",
  typescript: ".ts",
  go: ".go",
  perl: ".pl",
  rust: ".rs",
  scala: ".scala",
  haskell: ".hs",
  lua: ".lua",
  shell: ".sh",
  sql: ".sql",
  html: ".html",
  css: ".css",
  // add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
};

// https://developer.mozilla.org/zh-CN/docs/Web/API/Node
export const NODE_TYPE = {
  ELEMENT_NODE: 1,
  ATTRIBUTE_NODE: 2,
  TEXT_NODE: 3,
  CDATA_SECTION_NODE: 4,
  ENTITY_REFERENCE_NODE: 5,
  ENTITY_NODE: 6,
  PROCESSING_INSTRUCTION_NODE: 7,
  COMMENT_NODE: 8,
  DOCUMENT_NODE: 9,
  DOCUMENT_TYPE_NODE: 10,
  DOCUMENT_FRAGMENT_NODE: 11,
  NOTATION_NODE: 12,
};

RegExp


Date

export const isValid = (date: any) => !isNaN(Date.parse(String(date)));

Media

const isMobile = () => {
  const userAgent =
    typeof window.navigator === "undefined" ? "" : navigator.userAgent;
  const mobileRegex =
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
  return mobileRegex.test(userAgent);
};

Func

export const getRandomString = () => {
  return Date.now().toString(32) + Math.random().toString(32).substring(2);
};

export const getPageQuery = function () {
  const urlSearchParams = new URLSearchParams(window.location.search);
  return Object.fromEntries(urlSearchParams.entries());
};

export const popupWindow = function (url, width = 1000, height = 640) {
  const left = window.innerWidth / 2 - width / 2;
  const top = window.innerHeight / 2 - height / 2;
  return window.open(
    url,
    "",
    `toolbar=no, location=no, directories=no, status=no, menubar=no, 
        scrollbars=no, resizable=no, copyhistory=no, width=${width}, 
        height=${height}, top=${top}, left=${left}`
  );
};
/**
 * @params {Object} data
 */
export const exportData = (data) => {
  const blob = new Blob([JSON.stringify(data, null, 2)], {
    type: "application/json",
  });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.download = `chatbot_ui_history_${currentDate()}.json`;
  link.href = url;
  link.style.display = "none";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};
/**
 * trace client actions using beacon
 * @param {Object} data
 * @returns void
 */
export const traceLog = function (data) {
  const payload = {
    ...data,
    user: _.get(data, "user._id"),
    action: data.action || "view",
    platform: conf.FRONT_HOST,
    release: _.get(pkg, "version"),
    createdAt: new Date(),
  };
  const u = document.getElementById("root");
  if (u) payload.uuid = u.getAttribute("data-gta-id");
  if (navigator && typeof navigator.sendBeacon === "function") {
    // const blob = new Blob(payload , {type: 'application/json;charset=UTF-8'});
    // console.log('tracelog', blob)
    navigator.sendBeacon(
      `${conf.GTA_HOST}${conf.API_PREFIX}/api/beacon`,
      JSON.stringify(payload)
    );
  } else {
    const t = document.getElementById("traceLog");
    if (!u || !t) return;
    const encodeStr = encodeURIComponent(
      Buffer.from(JSON.stringify(payload)).toString("base64")
    );
    t.setAttribute(
      "src",
      `${conf.GTA_HOST}${conf.API_PREFIX}/api/sl.png?d=${encodeStr}`
    );
  }
};
export const lerp = (min: number, max: number, r: number) =>
  min + (max - min) * r;

export function sleep(n: number) {
  return new Promise((resolve) => setTimeout(() => resolve(true), n));
}

export const throttle = (callback: Function, limit: number) => {
  let waiting = false;
  return (...args: any[]) => {
    if (waiting) {
      return;
    }
    callback(...args);
    waiting = true;
    setTimeout(() => {
      waiting = false;
    }, limit);
    return;
  };
};

export const removeTrailingZeros = (num: number | string) =>
  parseFloat(String(num).replace(/0+$/g, ""));

export const html2Escape = (strHtml: string) =>
  // @ts-ignore
  strHtml.replace(/[<>&"]/g, function (c) {
    return {
      "<": "&lt;",
      ">": "&gt;",
      "&": "&amp;",
      '"': "&quot;",
    }[c];
  });

/**
 * keep only truthy key,value pairs
 * @param obj Record<string, any>
 */
export const santizeObject = (obj: Record<string, any>) => {
  const res: Record<string, any> = {};
  _.forEach(obj, (val, key) => {
    if (typeof val === "string") {
      if (_.trim(val)) res[key] = _.trim(val);
    } else {
      res[key] = val;
    }
  });
  return res;
};

export const toFileSize = (len: number) => {
  if (len < 1024) {
    return len + "B";
  } else if (len < 1024 * 1024) {
    return (len / 1024).toFixed(2) + "KB";
  } else if (len < 1024 * 1024 * 1024) {
    return (len / 1024 / 1024).toFixed(2) + "MB";
  } else {
    return (len / 1024 / 1024 / 1024).toFixed(2) + "GB";
  }
};

export const generateRandomString = (length: number, lowercase = false) => {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789"; // excluding similar looking characters like Z, 2, I, 1, O, 0
  let result = "";
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return lowercase ? result.toLowerCase() : result;
};

Page Source