helpers.ts
174 lines
| 1 | import { toUnicode as punyUnicode } from "punycode"; |
| 2 | |
| 3 | import { AxiosResponse } from "axios"; |
| 4 | import { toast } from "vue3-toastify"; |
| 5 | |
| 6 | import { useGeneralStoreData } from "@/stores"; |
| 7 | import { ResponseError } from "@/types"; |
| 8 | |
| 9 | /** |
| 10 | * Converts a string to Unicode using Punycode encoding. |
| 11 | * If the input string is falsy, it returns the input string itself. |
| 12 | * |
| 13 | * @param str - The string to convert to Unicode. |
| 14 | * @returns The Unicode representation of the input string, or the input string itself if it is falsy. |
| 15 | */ |
| 16 | export const toUnicode = (str: string) => (str ? punyUnicode(str) : str); |
| 17 | |
| 18 | /** |
| 19 | * Converts the first character of a word to uppercase and returns the modified word. |
| 20 | * If the word is an empty string, an empty string is returned. |
| 21 | * |
| 22 | * @param word - The word to convert to title case. |
| 23 | * @returns The word with the first character in uppercase. |
| 24 | */ |
| 25 | export const toTitleCase = (word: string = "") => |
| 26 | word.charAt(0).toUpperCase() + word.slice(1); |
| 27 | |
| 28 | /** |
| 29 | * Delays the execution for the specified number of milliseconds. |
| 30 | * @param ms - The number of milliseconds to delay the execution. |
| 31 | * @returns A Promise that resolves after the specified delay. |
| 32 | */ |
| 33 | export const timeout = (ms: number) => |
| 34 | new Promise((resolve) => setTimeout(resolve, ms)); |
| 35 | |
| 36 | /** |
| 37 | * Copies the given string to the clipboard. |
| 38 | * |
| 39 | * @param copiedString - The string to be copied. |
| 40 | * @param message - The success message to be displayed. |
| 41 | * @param toastrParams - Additional parameters for the toast notification. |
| 42 | */ |
| 43 | export const copyString = ( |
| 44 | copiedString: string, |
| 45 | message = translate("hostinger_tools_copied_successfully"), |
| 46 | toastrParams = {} |
| 47 | ) => { |
| 48 | const el = document.createElement("textarea"); |
| 49 | el.value = copiedString; |
| 50 | |
| 51 | el.setAttribute("readonly", ""); |
| 52 | document.body.appendChild(el); |
| 53 | el.select(); |
| 54 | |
| 55 | document.execCommand("copy"); |
| 56 | document.body.removeChild(el); |
| 57 | |
| 58 | const copyString = translate("hostinger_tools_text_copied_successfully"); |
| 59 | |
| 60 | if (!message) return; |
| 61 | toast.success(copyString, toastrParams); |
| 62 | }; |
| 63 | |
| 64 | /** |
| 65 | * Wraps the given value in a CSS variable. |
| 66 | * @param value - The value to be wrapped. |
| 67 | * @returns The wrapped value as a CSS variable. |
| 68 | */ |
| 69 | export const wrapInCssVar = (value: string | number) => `var(--${value})`; |
| 70 | |
| 71 | /** |
| 72 | * Capitalizes the first letter of a string. |
| 73 | * @param str - The input string. |
| 74 | * @returns The input string with the first letter capitalized. |
| 75 | */ |
| 76 | export const capitalize = (str: string) => |
| 77 | str.charAt(0).toUpperCase() + str.substring(1); |
| 78 | |
| 79 | /** |
| 80 | * Calls an asynchronous function and handles the response. |
| 81 | * @param promise - The promise to be resolved. |
| 82 | * @returns A tuple containing the response data and any error that occurred. |
| 83 | */ |
| 84 | export const asyncCall = async <T>( |
| 85 | promise: Promise<AxiosResponse<T>> |
| 86 | ): Promise<[T, ResponseError | null]> => { |
| 87 | try { |
| 88 | const response = await promise; |
| 89 | |
| 90 | if ( |
| 91 | response.data && |
| 92 | typeof response.data === "object" && |
| 93 | "error" in response.data |
| 94 | ) { |
| 95 | const apiResponse = response.data as { error?: unknown; data?: T }; |
| 96 | |
| 97 | if ( |
| 98 | !apiResponse.error || |
| 99 | (Array.isArray(apiResponse.error) && !apiResponse.error.length) |
| 100 | ) { |
| 101 | return [apiResponse.data as T, null]; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | return [response.data as T, null]; |
| 106 | } catch (er) { |
| 107 | return [{} as T, er as ResponseError]; |
| 108 | } |
| 109 | }; |
| 110 | |
| 111 | /** |
| 112 | * Retrieves the URL of an asset based on the provided path. |
| 113 | * @param path - The path of the asset. |
| 114 | * @returns The URL of the asset. |
| 115 | */ |
| 116 | export const getAssetSource = (path: string) => { |
| 117 | const { assetUrl } = useGeneralStoreData(); |
| 118 | |
| 119 | return `${assetUrl}vue-frontend/src/assets/${path}`; |
| 120 | }; |
| 121 | |
| 122 | /** |
| 123 | * Converts a kebab-case string to camelCase. |
| 124 | * @param string - The kebab-case string to convert. |
| 125 | * @returns The camelCase version of the input string. |
| 126 | */ |
| 127 | export const kebabToCamel = (string: string) => |
| 128 | string.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); |
| 129 | |
| 130 | /** |
| 131 | * Compares two version numbers and returns a comparison result. |
| 132 | * @param newVersion - The old version number. |
| 133 | * @param currentVersion - The new version number. |
| 134 | * @returns -1 if currentVersion is greater than newVersion, 1 if currentVersion is less than newVersion, 0 if they are equal. |
| 135 | */ |
| 136 | export const isNewerVerison = ({ |
| 137 | newVersion, |
| 138 | currentVersion |
| 139 | }: { |
| 140 | newVersion: string; |
| 141 | currentVersion: string; |
| 142 | }) => { |
| 143 | if (!newVersion || !currentVersion) return false; |
| 144 | |
| 145 | const newVersionParts = newVersion.split("."); |
| 146 | const currentVersionParts = currentVersion.split("."); |
| 147 | for ( |
| 148 | let i = 0; |
| 149 | i < Math.max(currentVersionParts.length, newVersionParts.length); |
| 150 | i++ |
| 151 | ) { |
| 152 | const newPart = parseInt(currentVersionParts[i]) || 0; |
| 153 | const oldPart = parseInt(newVersionParts[i]) || 0; |
| 154 | if (newPart > oldPart) return false; |
| 155 | if (newPart < oldPart) return true; |
| 156 | } |
| 157 | |
| 158 | return false; |
| 159 | }; |
| 160 | |
| 161 | /** |
| 162 | * Returns the base URL of a given URL. |
| 163 | * @param url - The input URL. |
| 164 | * @returns The base URL of the input URL. |
| 165 | */ |
| 166 | export const getBaseUrl = (url: string) => { |
| 167 | const parsedUrl = new URL(url); |
| 168 | |
| 169 | return `${parsedUrl.protocol}//${parsedUrl.host}${parsedUrl.pathname.split("/").slice(0, -1).join("/")}/`; |
| 170 | }; |
| 171 | |
| 172 | export const translate = (key: string) => |
| 173 | hostinger_tools_data.translations[key] || key; |
| 174 |