2026-06-16 23:14:52 +03:00
|
|
|
import { snakeCase } from 'lodash'
|
|
|
|
|
|
2026-06-13 03:10:00 +03:00
|
|
|
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
|
|
|
|
|
|
2026-06-16 23:14:52 +03:00
|
|
|
export const paramsString = (params = {}) => {
|
|
|
|
|
if (params == null || params === undefined) return ''
|
|
|
|
|
|
|
|
|
|
if (typeof params !== 'object' || Array.isArray(params)) {
|
|
|
|
|
throw new Error('Params are not an object!')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const entries = (() => {
|
|
|
|
|
if (params instanceof Map) {
|
|
|
|
|
return params.entries()
|
|
|
|
|
} else {
|
|
|
|
|
return Object.entries(params)
|
|
|
|
|
}
|
|
|
|
|
})()
|
|
|
|
|
|
|
|
|
|
if (entries.length === 0) return ''
|
|
|
|
|
|
|
|
|
|
const arrays = []
|
|
|
|
|
const nonArrays = []
|
|
|
|
|
|
|
|
|
|
entries.forEach(([k, v]) => {
|
|
|
|
|
if (v == null) return // Drop nulls
|
|
|
|
|
if (
|
|
|
|
|
(typeof v === 'object' && !Array.isArray(v)) ||
|
|
|
|
|
typeof v === 'function'
|
|
|
|
|
) {
|
|
|
|
|
throw new Error('Param cannot be non-primitive!')
|
|
|
|
|
}
|
|
|
|
|
if (Array.isArray(v)) {
|
|
|
|
|
arrays.push([k, v])
|
|
|
|
|
} else {
|
|
|
|
|
nonArrays.push([k, v])
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
arrays.forEach(([k, array]) => {
|
|
|
|
|
array.forEach((v) => {
|
|
|
|
|
if (
|
|
|
|
|
typeof v === 'object' ||
|
|
|
|
|
typeof v === 'function' ||
|
|
|
|
|
typeof v === 'undefined'
|
|
|
|
|
)
|
|
|
|
|
throw new Error('Array param cannot contain non-primitives!')
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
'?' +
|
|
|
|
|
[
|
|
|
|
|
...nonArrays.map(([k, v]) => [snakeCase(k), v]),
|
|
|
|
|
// turning [a,[1,2,3]] into [[a[],1],[a[],2],[a[],3]]
|
|
|
|
|
...arrays.reduce(
|
|
|
|
|
(acc, [k, arrayValue]) => [
|
|
|
|
|
...acc,
|
|
|
|
|
...arrayValue.map((v) => [snakeCase(k) + '[]', v]),
|
|
|
|
|
],
|
|
|
|
|
[],
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
.map(([k, v]) => `${k}=${window.encodeURIComponent(v)}`)
|
|
|
|
|
.join('&')
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-17 13:33:30 +03:00
|
|
|
export const promisedRequest = async ({
|
2026-06-13 03:10:00 +03:00
|
|
|
method,
|
|
|
|
|
url,
|
|
|
|
|
payload,
|
|
|
|
|
formData,
|
|
|
|
|
credentials,
|
|
|
|
|
headers = {},
|
|
|
|
|
}) => {
|
|
|
|
|
const options = {
|
|
|
|
|
method,
|
|
|
|
|
credentials: 'same-origin',
|
|
|
|
|
headers: {
|
|
|
|
|
Accept: 'application/json',
|
|
|
|
|
...headers,
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-06-17 14:26:41 +03:00
|
|
|
|
2026-06-13 03:10:00 +03:00
|
|
|
if (!formData) {
|
|
|
|
|
options.headers['Content-Type'] = 'application/json'
|
|
|
|
|
}
|
2026-06-17 14:26:41 +03:00
|
|
|
|
2026-06-13 03:10:00 +03:00
|
|
|
if (formData || payload) {
|
|
|
|
|
options.body = formData || JSON.stringify(payload)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (credentials) {
|
|
|
|
|
options.headers = {
|
|
|
|
|
...options.headers,
|
|
|
|
|
...authHeaders(credentials),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-17 17:58:14 +03:00
|
|
|
let response = null
|
2026-06-17 13:33:30 +03:00
|
|
|
try {
|
2026-06-17 17:58:14 +03:00
|
|
|
response = await fetch(url, options)
|
|
|
|
|
const data = await (async () => {
|
|
|
|
|
const [contentType] = response.headers
|
|
|
|
|
.get('content-type')
|
|
|
|
|
.split(';')
|
|
|
|
|
.map((x) => x.toLowerCase().trim())
|
2026-06-22 16:13:30 +03:00
|
|
|
const contentLength = parseInt(response.headers.get('content-length'))
|
|
|
|
|
if (contentLength === 0) return null
|
2026-06-17 17:58:14 +03:00
|
|
|
|
|
|
|
|
switch (contentType) {
|
|
|
|
|
case 'text/plain':
|
|
|
|
|
return await response.text()
|
|
|
|
|
case 'application/json':
|
|
|
|
|
return await response.json()
|
|
|
|
|
default:
|
|
|
|
|
return await response.bytes()
|
2026-06-17 13:33:30 +03:00
|
|
|
}
|
2026-06-17 17:58:14 +03:00
|
|
|
})()
|
2026-06-17 13:33:30 +03:00
|
|
|
|
2026-06-17 17:58:14 +03:00
|
|
|
const { ok, status } = response
|
2026-06-17 13:33:30 +03:00
|
|
|
|
2026-06-17 17:58:14 +03:00
|
|
|
if (ok) {
|
|
|
|
|
return { response, status, data }
|
|
|
|
|
} else {
|
2026-06-17 14:26:41 +03:00
|
|
|
throw new StatusCodeError(
|
|
|
|
|
response.status,
|
2026-06-17 17:58:14 +03:00
|
|
|
data,
|
2026-06-17 14:26:41 +03:00
|
|
|
{ url, options },
|
|
|
|
|
response,
|
|
|
|
|
)
|
|
|
|
|
}
|
2026-06-17 13:33:30 +03:00
|
|
|
} catch (error) {
|
2026-06-22 20:54:34 +03:00
|
|
|
throw new Error(error, { url, options }, response)
|
2026-06-17 13:33:30 +03:00
|
|
|
}
|
2026-06-13 03:10:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const authHeaders = (accessToken) => {
|
|
|
|
|
if (accessToken) {
|
|
|
|
|
return { Authorization: `Bearer ${accessToken}` }
|
|
|
|
|
} else {
|
|
|
|
|
return {}
|
|
|
|
|
}
|
|
|
|
|
}
|