2025-03-08 07:11:57 +00:00
|
|
|
import { UpdateField } from '@components/options/ToolOptions';
|
2025-07-07 14:18:47 +01:00
|
|
|
import { getToolsByCategory } from '@tools/index';
|
2025-07-14 14:51:46 +01:00
|
|
|
import { ToolCategory } from '@tools/defineTool';
|
2025-07-14 18:04:30 +01:00
|
|
|
import { I18nNamespaces, validNamespaces } from '../i18n';
|
2025-07-15 18:30:02 +01:00
|
|
|
import { TFunction } from 'i18next';
|
2025-03-08 07:11:57 +00:00
|
|
|
|
2025-06-05 23:36:52 +02:00
|
|
|
// Here starting the shared values for string manipulation.
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This map is used to replace special characters with their visual representations.
|
|
|
|
|
* It is useful for displaying strings in a more readable format, especially in tools
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
export const specialCharMap: { [key: string]: string } = {
|
|
|
|
|
'': '␀',
|
|
|
|
|
' ': '␣',
|
|
|
|
|
'\n': '↲',
|
|
|
|
|
'\t': '⇥',
|
|
|
|
|
'\r': '␍',
|
|
|
|
|
'\f': '␌',
|
|
|
|
|
'\v': '␋'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Here starting the utility functions for string manipulation.
|
|
|
|
|
|
2024-06-25 09:35:44 +01:00
|
|
|
export function capitalizeFirstLetter(string: string | undefined) {
|
|
|
|
|
if (!string) return '';
|
2024-06-23 01:26:04 +01:00
|
|
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
|
|
|
}
|
2024-06-27 16:51:40 +00:00
|
|
|
|
2025-03-24 20:23:28 +00:00
|
|
|
export function isNumber(number: any): boolean {
|
2024-06-27 16:51:40 +00:00
|
|
|
return !isNaN(parseFloat(number)) && isFinite(number);
|
2024-06-27 18:55:20 +01:00
|
|
|
}
|
2024-07-09 21:58:08 +01:00
|
|
|
|
2025-03-08 07:11:57 +00:00
|
|
|
export const updateNumberField = <T>(
|
|
|
|
|
val: string,
|
|
|
|
|
key: keyof T,
|
|
|
|
|
updateField: UpdateField<T>
|
|
|
|
|
) => {
|
|
|
|
|
if (val === '') {
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
updateField(key, '');
|
|
|
|
|
} else if (isNumber(val)) {
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
updateField(key, Number(val));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-07-09 21:58:08 +01:00
|
|
|
export const replaceSpecialCharacters = (str: string) => {
|
|
|
|
|
return str
|
2025-02-27 13:05:38 +00:00
|
|
|
.replace(/\\"/g, '"')
|
2024-07-09 21:58:08 +01:00
|
|
|
.replace(/\\n/g, '\n')
|
|
|
|
|
.replace(/\\t/g, '\t')
|
|
|
|
|
.replace(/\\r/g, '\r')
|
|
|
|
|
.replace(/\\b/g, '\b')
|
|
|
|
|
.replace(/\\f/g, '\f')
|
|
|
|
|
.replace(/\\v/g, '\v');
|
|
|
|
|
};
|
2024-07-10 14:33:20 +00:00
|
|
|
|
|
|
|
|
export function reverseString(input: string): string {
|
|
|
|
|
return input.split('').reverse().join('');
|
|
|
|
|
}
|
2025-03-24 20:23:28 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if the input string contains only digits.
|
|
|
|
|
* @param input - The string to validate.
|
2025-03-26 17:39:51 +00:00
|
|
|
* @returns True if the input contains only digits including float, false otherwise.
|
2025-03-24 20:23:28 +00:00
|
|
|
*/
|
|
|
|
|
export function containsOnlyDigits(input: string): boolean {
|
2025-03-26 17:39:51 +00:00
|
|
|
return /^\d+(\.\d+)?$/.test(input.trim());
|
2025-03-24 20:23:28 +00:00
|
|
|
}
|
2025-04-05 03:50:55 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* unquote a string if properly quoted.
|
|
|
|
|
* @param value - The string to unquote.
|
|
|
|
|
* @param quoteCharacter - The character used for quoting (e.g., '"', "'").
|
|
|
|
|
* @returns The unquoted string if it was quoted, otherwise the original string.
|
|
|
|
|
*/
|
|
|
|
|
export function unquoteIfQuoted(value: string, quoteCharacter: string): string {
|
2025-04-06 01:45:56 +02:00
|
|
|
if (
|
|
|
|
|
quoteCharacter &&
|
|
|
|
|
value.startsWith(quoteCharacter) &&
|
|
|
|
|
value.endsWith(quoteCharacter)
|
|
|
|
|
) {
|
2025-04-05 03:50:55 +02:00
|
|
|
return value.slice(1, -1); // Remove first and last character
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2025-06-05 23:36:52 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Count the occurence of items.
|
|
|
|
|
* @param array - array get from user with a custom delimiter.
|
|
|
|
|
* @param ignoreItemCase - boolean status to ignore the case i .
|
|
|
|
|
* @returns Dict of Items count {[Item]: occcurence}.
|
|
|
|
|
*/
|
|
|
|
|
export function itemCounter(
|
|
|
|
|
array: string[],
|
|
|
|
|
ignoreItemCase: boolean
|
|
|
|
|
): { [key: string]: number } {
|
|
|
|
|
const dict: { [key: string]: number } = {};
|
|
|
|
|
for (const item of array) {
|
|
|
|
|
let key = ignoreItemCase ? item.toLowerCase() : item;
|
|
|
|
|
|
|
|
|
|
if (key in specialCharMap) {
|
|
|
|
|
key = specialCharMap[key];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dict[key] = (dict[key] || 0) + 1;
|
|
|
|
|
}
|
|
|
|
|
return dict;
|
|
|
|
|
}
|
2025-07-07 14:18:47 +01:00
|
|
|
|
2025-07-15 18:30:02 +01:00
|
|
|
export const getToolCategoryTitle = (
|
|
|
|
|
categoryName: string,
|
|
|
|
|
t: TFunction<I18nNamespaces[]>
|
|
|
|
|
): string =>
|
2025-07-18 15:03:26 -07:00
|
|
|
getToolsByCategory([], t).find((category) => category.type === categoryName)!
|
2025-07-07 14:18:47 +01:00
|
|
|
.rawTitle;
|
2025-07-14 14:51:46 +01:00
|
|
|
|
|
|
|
|
// Type guard to check if a value is a valid I18nNamespaces
|
|
|
|
|
const isValidI18nNamespace = (value: string): value is I18nNamespaces => {
|
|
|
|
|
return validNamespaces.includes(value as I18nNamespaces);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getI18nNamespaceFromToolCategory = (
|
|
|
|
|
category: ToolCategory
|
|
|
|
|
): I18nNamespaces => {
|
|
|
|
|
// Map image-related categories to 'image'
|
|
|
|
|
if (['png', 'image-generic'].includes(category)) {
|
|
|
|
|
return 'image';
|
|
|
|
|
} else if (['gif'].includes(category)) {
|
|
|
|
|
return 'video';
|
|
|
|
|
}
|
|
|
|
|
// Use type guard to check if category is a valid I18nNamespaces
|
|
|
|
|
if (isValidI18nNamespace(category)) {
|
|
|
|
|
return category;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 'translation';
|
|
|
|
|
};
|