import { Parser } from 'htmlparser2'
export const fetcher = async (input: RequestInfo, init?: RequestInit) => {
const res = await fetch(input, init)
return res.json()
}
export const isMobile =
typeof window !== 'undefined' &&
window.matchMedia('only screen and (max-width: 760px)').matches
export const sendRequest = async ({
url,
method,
body,
}: {
url: string
method: string
body?: Record
}): Promise<{ data?: ResponseData; error?: Error }> => {
try {
const response = await fetch(url, {
method,
mode: 'cors',
body: body ? JSON.stringify(body) : undefined,
})
if (!response.ok) throw new Error(response.statusText)
const data = await response.json()
return { data }
} catch (e) {
console.error(e)
return { error: e as Error }
}
}
export const insertItemInList = (
arr: T[],
index: number,
newItem: T
): T[] => [...arr.slice(0, index), newItem, ...arr.slice(index)]
export const preventUserFromRefreshing = (e: BeforeUnloadEvent) => {
e.preventDefault()
e.returnValue = ''
}
export const parseHtmlStringToPlainText = (html: string): string => {
let label = ''
const parser = new Parser({
ontext(text) {
label += `${text}`
},
})
parser.write(html)
parser.end()
return label
}
export const toKebabCase = (value: string) => {
const matched = value.match(
/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
)
if (!matched) return ''
return matched.map((x) => x.toLowerCase()).join('-')
}
interface Omit {
// eslint-disable-next-line @typescript-eslint/ban-types
(obj: T, ...keys: K): {
[K2 in Exclude]: T[K2]
}
}
export const omit: Omit = (obj, ...keys) => {
const ret = {} as {
[K in keyof typeof obj]: typeof obj[K]
}
let key: keyof typeof obj
for (key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key]
}
}
return ret
}
export const uploadFile = async (file: File, key: string) => {
const res = await fetch(
`/api/storage/upload-url?key=${encodeURIComponent(
key
)}&fileType=${encodeURIComponent(file.type)}`
)
const { url, fields } = await res.json()
const formData = new FormData()
Object.entries({ ...fields, file }).forEach(([key, value]) => {
formData.append(key, value as string | Blob)
})
const upload = await fetch(url, {
method: 'POST',
body: formData,
})
return {
url: upload.ok ? `${url}/${key}` : null,
}
}
export const removeUndefinedFields = (obj: T): T =>
Object.keys(obj).reduce(
(acc, key) =>
obj[key as keyof T] === undefined
? { ...acc }
: { ...acc, [key]: obj[key as keyof T] },
{} as T
)