160 lines
3.9 KiB
TypeScript
160 lines
3.9 KiB
TypeScript
import {Prisma} from '@prisma/client'
|
|
import bcrypt from 'bcryptjs'
|
|
import {type ClassValue, clsx} from 'clsx'
|
|
import {getLocale} from 'next-intl/server'
|
|
import slugify from 'slugify'
|
|
import {twMerge} from 'tailwind-merge'
|
|
|
|
import {i18nDefaultLocale} from '@/i18n-config'
|
|
|
|
/**
|
|
* Just output dump using pretty output
|
|
*
|
|
* @param variable
|
|
*/
|
|
export function dump(variable: any): [string, string] {
|
|
return [
|
|
(new Error().stack?.split('\n')[2]?.trim().split(' ')[1] as string) + ' ',
|
|
JSON.stringify(variable, null, 2)
|
|
]
|
|
}
|
|
|
|
export const toPrice = (price: any) => parseFloat(price).toFixed(2)
|
|
|
|
/**
|
|
* Create fallback avatar for showing during login process or in case if empty
|
|
*
|
|
* @param name
|
|
*/
|
|
export const avatarFallback = (name: string): string =>
|
|
name
|
|
? name
|
|
.split(' ')
|
|
.slice(0, 2)
|
|
.map(w => w[0])
|
|
.join('')
|
|
.toUpperCase()
|
|
: 'U'
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
/**
|
|
* Slugify the string based on locale using kebab case
|
|
*
|
|
* @param string
|
|
* @param locale
|
|
*/
|
|
export function slug(string: string, locale: string = 'uk'): string {
|
|
return slugify(string, {
|
|
lower: true,
|
|
strict: true,
|
|
locale
|
|
})
|
|
}
|
|
|
|
export const formatNumberWithDecimal = (num: number): string => {
|
|
const [int, decimal] = num.toString().split('.')
|
|
return decimal ? `$(num).${decimal.padEnd(2, '0')}` : int
|
|
}
|
|
|
|
export const toInt = (input: unknown): number | null => {
|
|
let output = NaN
|
|
|
|
if (typeof input === 'string' || typeof input === 'number') {
|
|
output = parseInt(input as string, 10)
|
|
}
|
|
|
|
if (isNaN(output)) {
|
|
console.log('input invalid type: ', typeof input)
|
|
return null
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
export const hashPassword = async (value: string): Promise<string> => {
|
|
return bcrypt.hash(value, 10)
|
|
}
|
|
|
|
export const verifyHashedPassword = async (
|
|
value: string,
|
|
hashPassword: string
|
|
): Promise<boolean> => {
|
|
return await bcrypt.compare(value, hashPassword)
|
|
}
|
|
|
|
/**
|
|
* Remove empty properties from the object
|
|
*
|
|
* @param queryParams
|
|
*/
|
|
export const cleanEmptyParams = (queryParams: any) => {
|
|
return Object.keys(queryParams)
|
|
.filter(key => queryParams[key] != '')
|
|
.reduce((acc, key) => Object.assign(acc, {[key]: queryParams[key]}), {})
|
|
}
|
|
|
|
/**
|
|
* Replace null value with empty string for the object and array of them as well
|
|
*
|
|
* @param data
|
|
*/
|
|
export const toEmptyParams = (data: object | object[]) => {
|
|
const result = []
|
|
const isArray = Array.isArray(data)
|
|
const toProcess: object[] = isArray ? data : [data]
|
|
|
|
for (let x in toProcess) {
|
|
const norm = Object.keys(toProcess[x]).reduce(
|
|
(obj: {}, key: string) =>
|
|
Object.assign(obj, {
|
|
// @ts-ignore
|
|
[key]: toProcess[x][key] === null ? '' : toProcess[x][key]
|
|
}),
|
|
{}
|
|
)
|
|
|
|
if (!isArray) return norm
|
|
result.push(norm)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
export const thisLocales = async (locales: any) => {
|
|
const loc = await getLocale()
|
|
return locales.filter((locale: any) => locale.lang === loc)
|
|
}
|
|
|
|
export const thisLocale = async (locales: any) => {
|
|
const loc = await getLocale()
|
|
return locales.find((locale: any) => locale.lang === loc)
|
|
}
|
|
|
|
export const dbErrorHandling = (e: unknown, message?: string | null) => {
|
|
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
|
return {error: `${e.code}: ${e.message}`}
|
|
} else if ((e as {code: string}).code === 'ETIMEDOUT') {
|
|
return {
|
|
error:
|
|
'Неможливо підключитися до бази даних. Будь ласка, спробуйте згодом.'
|
|
}
|
|
} else if ((e as {code: string}).code === '503') {
|
|
return {
|
|
error: 'Сервіс тимчасово недоступний. Будь ласка, спробуйте згодом.'
|
|
}
|
|
} else {
|
|
return {error: 'Сталася несподівана помилка. Будь ласка, спробуйте згодом.'}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the object is empty
|
|
*
|
|
* @param obj
|
|
*/
|
|
export const isEmptyObj = (obj: object): boolean =>
|
|
Object.keys(obj).length === 0
|