@krainovsd/js-helpers 0.15.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/index.cjs +658 -560
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/{lib/api/middlewares/console-post-middleware.js → api/after/logger-after-handler.js} +5 -5
- package/lib/esm/api/after/logger-after-handler.js.map +1 -0
- package/lib/esm/api/api.constants.js +23 -0
- package/lib/esm/api/api.constants.js.map +1 -0
- package/lib/esm/api/api.js +343 -0
- package/lib/esm/api/api.js.map +1 -0
- package/lib/esm/{lib/api/middlewares/console-middleware.js → api/before/logger-before-handler.js} +4 -4
- package/lib/esm/api/before/logger-before-handler.js.map +1 -0
- package/lib/esm/{lib/api/middlewares/oauth-middleware.js → api/before/oauth-before-handler.js} +15 -15
- package/lib/esm/api/before/oauth-before-handler.js.map +1 -0
- package/lib/esm/{lib/api/oauth/token.js → api/oauth.js} +33 -27
- package/lib/esm/api/oauth.js.map +1 -0
- package/lib/esm/constants/errors.js +16 -0
- package/lib/esm/constants/errors.js.map +1 -0
- package/lib/esm/constants/index.js +27 -0
- package/lib/esm/constants/index.js.map +1 -0
- package/lib/esm/index.js +9 -8
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/lib/colors/get-color-format.js +1 -2
- package/lib/esm/lib/colors/get-color-format.js.map +1 -1
- package/lib/esm/lib/colors/take-opacity-colors.js +1 -2
- package/lib/esm/lib/colors/take-opacity-colors.js.map +1 -1
- package/lib/esm/lib/colors/transform-to-color.js +1 -2
- package/lib/esm/lib/colors/transform-to-color.js.map +1 -1
- package/lib/esm/lib/date/get-date-by-rules.js +1 -2
- package/lib/esm/lib/date/get-date-by-rules.js.map +1 -1
- package/lib/esm/lib/date/is-yesterday.js +0 -1
- package/lib/esm/lib/date/is-yesterday.js.map +1 -1
- package/lib/esm/lib/utils/build-query-string.js.map +1 -1
- package/lib/esm/lib/utils/{create-url-with-params.js → create-url-with-queries.js} +3 -3
- package/lib/esm/lib/utils/create-url-with-queries.js.map +1 -0
- package/lib/esm/lib/utils/field-view-format.js +1 -2
- package/lib/esm/lib/utils/field-view-format.js.map +1 -1
- package/lib/index.d.ts +226 -171
- package/package.json +4 -2
- package/lib/esm/constants/api.js +0 -10
- package/lib/esm/constants/api.js.map +0 -1
- package/lib/esm/constants/colors.js +0 -9
- package/lib/esm/constants/colors.js.map +0 -1
- package/lib/esm/constants/date.js +0 -11
- package/lib/esm/constants/date.js.map +0 -1
- package/lib/esm/constants/fields.js +0 -11
- package/lib/esm/constants/fields.js.map +0 -1
- package/lib/esm/lib/api/constants.js +0 -4
- package/lib/esm/lib/api/constants.js.map +0 -1
- package/lib/esm/lib/api/core.js +0 -187
- package/lib/esm/lib/api/core.js.map +0 -1
- package/lib/esm/lib/api/middlewares/console-middleware.js.map +0 -1
- package/lib/esm/lib/api/middlewares/console-post-middleware.js.map +0 -1
- package/lib/esm/lib/api/middlewares/index.js +0 -64
- package/lib/esm/lib/api/middlewares/index.js.map +0 -1
- package/lib/esm/lib/api/middlewares/oauth-middleware.js.map +0 -1
- package/lib/esm/lib/api/oauth/token.js.map +0 -1
- package/lib/esm/lib/api/oauth/user.js +0 -35
- package/lib/esm/lib/api/oauth/user.js.map +0 -1
- package/lib/esm/lib/utils/create-url-with-params.js.map +0 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -9,22 +9,19 @@ const yesterdayPlugin = require('dayjs/plugin/isYesterday');
|
|
|
9
9
|
const get = require('lodash/get');
|
|
10
10
|
const set = require('lodash/set');
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
const POST_API_MIDDLEWARES = {
|
|
26
|
-
Logger: "logger",
|
|
27
|
-
};
|
|
12
|
+
class ResponseError extends Error {
|
|
13
|
+
status;
|
|
14
|
+
code;
|
|
15
|
+
description;
|
|
16
|
+
headers;
|
|
17
|
+
constructor({ message, status, description, code, headers }) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.description = description;
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.headers = headers;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
28
25
|
|
|
29
26
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
30
27
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
@@ -49,7 +46,14 @@ const COLOR_FORMATS = {
|
|
|
49
46
|
Rgba: "RGBA",
|
|
50
47
|
Hsl: "HSL",
|
|
51
48
|
};
|
|
52
|
-
|
|
49
|
+
const DATE_TYPES = {
|
|
50
|
+
Days: "days",
|
|
51
|
+
Months: "months",
|
|
52
|
+
Years: "years",
|
|
53
|
+
Seconds: "seconds",
|
|
54
|
+
Minutes: "minutes",
|
|
55
|
+
Hours: "hours",
|
|
56
|
+
};
|
|
53
57
|
const FIELD_TYPES = {
|
|
54
58
|
Date: "date",
|
|
55
59
|
Time: "time",
|
|
@@ -320,7 +324,7 @@ function buildQueryString(params) {
|
|
|
320
324
|
return queryString.join("&");
|
|
321
325
|
}
|
|
322
326
|
|
|
323
|
-
function
|
|
327
|
+
function createURLWithQueries(options) {
|
|
324
328
|
const url = options.baseURL;
|
|
325
329
|
if (!options.params) {
|
|
326
330
|
return url;
|
|
@@ -1308,554 +1312,81 @@ function extractQueries() {
|
|
|
1308
1312
|
return queryMap;
|
|
1309
1313
|
}
|
|
1310
1314
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
}
|
|
1325
|
-
// eslint-disable-next-line no-console
|
|
1326
|
-
console.log(request);
|
|
1327
|
-
resolve(true);
|
|
1328
|
-
});
|
|
1329
|
-
};
|
|
1315
|
+
function getColorFormat(color) {
|
|
1316
|
+
if (color.startsWith("#")) {
|
|
1317
|
+
return COLOR_FORMATS.Hex;
|
|
1318
|
+
}
|
|
1319
|
+
if (color.startsWith("rgba")) {
|
|
1320
|
+
return COLOR_FORMATS.Rgba;
|
|
1321
|
+
}
|
|
1322
|
+
if (color.startsWith("rgb")) {
|
|
1323
|
+
return COLOR_FORMATS.Rgb;
|
|
1324
|
+
}
|
|
1325
|
+
if (color.startsWith("hsl")) {
|
|
1326
|
+
return COLOR_FORMATS.Hsl;
|
|
1327
|
+
}
|
|
1330
1328
|
}
|
|
1331
1329
|
|
|
1332
|
-
function
|
|
1333
|
-
return (
|
|
1334
|
-
return new Promise((resolve) => {
|
|
1335
|
-
void (async function logger() {
|
|
1336
|
-
try {
|
|
1337
|
-
if (!response ||
|
|
1338
|
-
(options.filter && !options.filter(response)) ||
|
|
1339
|
-
(options.filterStatus && !options.filterStatus(response.status)) ||
|
|
1340
|
-
(options.filterUrl && !options.filterUrl(response.url)) ||
|
|
1341
|
-
(options.filterHeaders && !options.filterHeaders(response.headers))) {
|
|
1342
|
-
resolve(true);
|
|
1343
|
-
return;
|
|
1344
|
-
}
|
|
1345
|
-
const contentType = response.headers.get("content-type");
|
|
1346
|
-
let result;
|
|
1347
|
-
if (contentType?.includes?.("text")) {
|
|
1348
|
-
result = await response.text();
|
|
1349
|
-
}
|
|
1350
|
-
else if (contentType?.includes?.("json")) {
|
|
1351
|
-
result = await response.json();
|
|
1352
|
-
}
|
|
1353
|
-
else {
|
|
1354
|
-
result = await response.blob();
|
|
1355
|
-
}
|
|
1356
|
-
Object.defineProperty(response, RESPONSE_DATA_SYMBOL, {
|
|
1357
|
-
value: result,
|
|
1358
|
-
writable: false,
|
|
1359
|
-
enumerable: false,
|
|
1360
|
-
configurable: true,
|
|
1361
|
-
});
|
|
1362
|
-
console.log({
|
|
1363
|
-
url: response.url,
|
|
1364
|
-
status: response.status,
|
|
1365
|
-
headers: response.headers,
|
|
1366
|
-
body: result,
|
|
1367
|
-
});
|
|
1368
|
-
resolve(true);
|
|
1369
|
-
}
|
|
1370
|
-
catch {
|
|
1371
|
-
if (response) {
|
|
1372
|
-
console.log({ url: response.url, status: response.status, headers: response.headers });
|
|
1373
|
-
}
|
|
1374
|
-
resolve(true);
|
|
1375
|
-
}
|
|
1376
|
-
})().finally(() => {
|
|
1377
|
-
resolve(true);
|
|
1378
|
-
});
|
|
1379
|
-
});
|
|
1380
|
-
};
|
|
1330
|
+
function transformHEXtoRGB(hex) {
|
|
1331
|
+
return `rgb(${hex.match(/\w\w/g)?.map((x) => +`0x${x}`)})`;
|
|
1381
1332
|
}
|
|
1382
1333
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
if (expires != undefined && !Number.isNaN(+expires) && Date.now() < +expires)
|
|
1388
|
-
return;
|
|
1389
|
-
waiting = true;
|
|
1390
|
-
const url = new URL(typeof options.refreshTokenWindowUrl === "function"
|
|
1391
|
-
? options.refreshTokenWindowUrl()
|
|
1392
|
-
: (options.refreshTokenWindowUrl ?? window.origin));
|
|
1393
|
-
url.searchParams.append(options.onlyRefreshTokenWindowQueryName, "true");
|
|
1394
|
-
let windowInstance = window.open(url.toString(), "_blank", "width=800,height=600,left=100,top=100");
|
|
1395
|
-
windowInstance ??= window.open(url.toString(), "_blank");
|
|
1396
|
-
if (windowInstance) {
|
|
1397
|
-
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName);
|
|
1398
|
-
const windowCloseObserver = setInterval(() => {
|
|
1399
|
-
if (windowInstance.closed) {
|
|
1400
|
-
if (waiting) {
|
|
1401
|
-
waiting = false;
|
|
1402
|
-
channel.close();
|
|
1403
|
-
clearInterval(windowCloseObserver);
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}, options.closeObserveInterval ?? 500);
|
|
1407
|
-
channel.onmessage = () => {
|
|
1408
|
-
if (waiting) {
|
|
1409
|
-
waiting = false;
|
|
1410
|
-
channel.close();
|
|
1411
|
-
clearInterval(windowCloseObserver);
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
setTimeout(() => {
|
|
1415
|
-
if (waiting) {
|
|
1416
|
-
waiting = false;
|
|
1417
|
-
channel.close();
|
|
1418
|
-
clearInterval(windowCloseObserver);
|
|
1419
|
-
}
|
|
1420
|
-
if (windowInstance && !windowInstance.closed) {
|
|
1421
|
-
windowInstance.close();
|
|
1422
|
-
}
|
|
1423
|
-
}, options.wait ?? 15000);
|
|
1424
|
-
}
|
|
1425
|
-
else {
|
|
1426
|
-
if (options.onWindowOpenError)
|
|
1427
|
-
options.onWindowOpenError();
|
|
1428
|
-
waiting = false;
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
await waitUntil(() => waiting);
|
|
1334
|
+
function transformRGBtoRGBA(rgb, opacity) {
|
|
1335
|
+
const code = rgb.match(/\d+/g);
|
|
1336
|
+
code?.push(String(opacity / 100));
|
|
1337
|
+
return `rgba(${code?.join(",")})`;
|
|
1432
1338
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
options.expiresTokenQueryName,
|
|
1439
|
-
options.onlyRefreshTokenWindowQueryName,
|
|
1440
|
-
]);
|
|
1441
|
-
const refreshQuery = queries?.[options.onlyRefreshTokenWindowQueryName];
|
|
1442
|
-
const expiresQuery = queries?.[options.expiresTokenQueryName];
|
|
1443
|
-
/** Is OnlyRefresh window */
|
|
1444
|
-
const isRefresh = isString(refreshQuery)
|
|
1445
|
-
? refreshQuery === "true"
|
|
1446
|
-
: isArray(refreshQuery)
|
|
1447
|
-
? refreshQuery[refreshQuery.length - 1] === "true"
|
|
1448
|
-
: false;
|
|
1449
|
-
/** Expires token */
|
|
1450
|
-
const expiresFromQuery = isString(expiresQuery)
|
|
1451
|
-
? expiresQuery
|
|
1452
|
-
: isArray(expiresQuery)
|
|
1453
|
-
? expiresQuery[expiresQuery.length - 1]
|
|
1454
|
-
: false;
|
|
1455
|
-
/** Extract expires from query */
|
|
1456
|
-
if (!expires && expiresFromQuery) {
|
|
1457
|
-
expires = expiresFromQuery;
|
|
1458
|
-
if (!expires || Number.isNaN(+expires) || Date.now() > +expires)
|
|
1459
|
-
expires = null;
|
|
1460
|
-
}
|
|
1461
|
-
/** OAuth flow if not expires */
|
|
1462
|
-
if (!expires) {
|
|
1463
|
-
window.location.replace(typeof options.oauthUrl === "function" ? options.oauthUrl() : options.oauthUrl);
|
|
1464
|
-
return null;
|
|
1465
|
-
}
|
|
1466
|
-
localStorage.setItem(options.expiresTokenStorageName, expires);
|
|
1467
|
-
/** Close if OnlyRefresh window */
|
|
1468
|
-
if (isRefresh) {
|
|
1469
|
-
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName);
|
|
1470
|
-
channel.postMessage(true);
|
|
1471
|
-
channel.close();
|
|
1472
|
-
window.close();
|
|
1473
|
-
}
|
|
1474
|
-
/** Delete expires query */
|
|
1475
|
-
if (expiresFromQuery) {
|
|
1476
|
-
const url = new URL(window.location.href);
|
|
1477
|
-
url.searchParams.delete(options.expiresTokenQueryName);
|
|
1478
|
-
window.location.replace(url.toString());
|
|
1479
|
-
return null;
|
|
1480
|
-
}
|
|
1481
|
-
return expires;
|
|
1339
|
+
|
|
1340
|
+
function transformRGBAtoRGB(rgba) {
|
|
1341
|
+
const code = rgba.match(/\d+/g);
|
|
1342
|
+
code?.splice(3);
|
|
1343
|
+
return `rgb(${code?.join(",")})`;
|
|
1482
1344
|
}
|
|
1483
1345
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
if (
|
|
1487
|
-
return
|
|
1346
|
+
function takeOpacityColors(color, opacities) {
|
|
1347
|
+
let rgbColor = color;
|
|
1348
|
+
if (!rgbColor)
|
|
1349
|
+
return [];
|
|
1350
|
+
if (getColorFormat(rgbColor) === COLOR_FORMATS.Hex) {
|
|
1351
|
+
rgbColor = transformHEXtoRGB(rgbColor);
|
|
1488
1352
|
}
|
|
1489
|
-
if (
|
|
1490
|
-
|
|
1353
|
+
else if (getColorFormat(rgbColor) === COLOR_FORMATS.Rgba) {
|
|
1354
|
+
rgbColor = transformRGBAtoRGB(rgbColor);
|
|
1491
1355
|
}
|
|
1492
|
-
|
|
1356
|
+
if (getColorFormat(rgbColor) !== COLOR_FORMATS.Rgb)
|
|
1357
|
+
return [];
|
|
1358
|
+
return [...opacities.map((opacity) => transformRGBtoRGBA(rgbColor, opacity))];
|
|
1493
1359
|
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1360
|
+
|
|
1361
|
+
function transformToColor(currentColor, defaultColor = "black", defaultFormat = COLOR_FORMATS.Hex) {
|
|
1362
|
+
if (!isString(currentColor))
|
|
1363
|
+
return defaultColor;
|
|
1364
|
+
let correctColor = currentColor;
|
|
1365
|
+
if (!getColorFormat(correctColor)) {
|
|
1366
|
+
switch (defaultFormat) {
|
|
1367
|
+
case COLOR_FORMATS.Hex: {
|
|
1368
|
+
correctColor = `#${correctColor}`;
|
|
1369
|
+
break;
|
|
1370
|
+
}
|
|
1371
|
+
case COLOR_FORMATS.Rgb: {
|
|
1372
|
+
correctColor = `rgb(${correctColor})`;
|
|
1373
|
+
break;
|
|
1374
|
+
}
|
|
1375
|
+
case COLOR_FORMATS.Rgba: {
|
|
1376
|
+
correctColor = `rgba(${correctColor})`;
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1379
|
+
case COLOR_FORMATS.Hsl: {
|
|
1380
|
+
correctColor = `hsl(${correctColor})`;
|
|
1381
|
+
break;
|
|
1382
|
+
}
|
|
1383
|
+
default: {
|
|
1384
|
+
correctColor = `#${correctColor}`;
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1503
1387
|
}
|
|
1504
|
-
const result = (await response.json());
|
|
1505
|
-
return result;
|
|
1506
|
-
}
|
|
1507
|
-
catch {
|
|
1508
|
-
if (status >= 500)
|
|
1509
|
-
return undefined;
|
|
1510
|
-
return null;
|
|
1511
1388
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
let isFetchingAccessToken = false;
|
|
1515
|
-
const generateOauthMiddleware = (options) => async (request) => {
|
|
1516
|
-
if (!options.expiresTokenStorageName) {
|
|
1517
|
-
throw new Error("Auth middleware hasn't required options");
|
|
1518
|
-
}
|
|
1519
|
-
const isSameOrigin = !startWith(request.path, "http");
|
|
1520
|
-
if (request.token) {
|
|
1521
|
-
if (!isSameOrigin)
|
|
1522
|
-
request.headers = {
|
|
1523
|
-
...request.headers,
|
|
1524
|
-
Authorization: `Bearer ${request.token}`,
|
|
1525
|
-
};
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
if (isFetchingAccessToken)
|
|
1529
|
-
await waitUntil(() => isFetchingAccessToken);
|
|
1530
|
-
const expires = localStorage.getItem(options.expiresTokenStorageName);
|
|
1531
|
-
let token;
|
|
1532
|
-
if (!expires || Number.isNaN(+expires) || Date.now() > +expires) {
|
|
1533
|
-
isFetchingAccessToken = true;
|
|
1534
|
-
await getOauthTokenFromOtherWindow({
|
|
1535
|
-
onlyRefreshTokenWindowQueryName: options.onlyRefreshTokenWindowQueryName,
|
|
1536
|
-
onWindowOpenError: options.onWindowOpenError,
|
|
1537
|
-
refreshTokenWindowUrl: options.refreshTokenWindowUrl,
|
|
1538
|
-
wait: options.wait,
|
|
1539
|
-
expiresTokenStorageName: options.expiresTokenStorageName,
|
|
1540
|
-
closeObserveInterval: options.closeObserveInterval,
|
|
1541
|
-
});
|
|
1542
|
-
if (options.tokenRequest) {
|
|
1543
|
-
token = await options.tokenRequest();
|
|
1544
|
-
if (token != undefined && options.tokenStorageName) {
|
|
1545
|
-
localStorage.setItem(options.tokenStorageName, token);
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
isFetchingAccessToken = false;
|
|
1549
|
-
}
|
|
1550
|
-
if (!isSameOrigin && token)
|
|
1551
|
-
request.headers = {
|
|
1552
|
-
...request.headers,
|
|
1553
|
-
Authorization: `Bearer ${token}`,
|
|
1554
|
-
};
|
|
1555
|
-
};
|
|
1556
|
-
|
|
1557
|
-
function generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlewares) {
|
|
1558
|
-
const selectedMiddlewares = customMiddlewares;
|
|
1559
|
-
for (const key of activeMiddlewares) {
|
|
1560
|
-
switch (key) {
|
|
1561
|
-
case API_MIDDLEWARES.Oauth: {
|
|
1562
|
-
if (middlewareOptions.oauth && (IS_BROWSER || IS_JEST))
|
|
1563
|
-
selectedMiddlewares.push(generateOauthMiddleware(middlewareOptions.oauth));
|
|
1564
|
-
continue;
|
|
1565
|
-
}
|
|
1566
|
-
case API_MIDDLEWARES.Logger: {
|
|
1567
|
-
selectedMiddlewares.push(generateConsoleMiddleware(middlewareOptions.logger));
|
|
1568
|
-
continue;
|
|
1569
|
-
}
|
|
1570
|
-
default: {
|
|
1571
|
-
continue;
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
return function executeMiddlewares(request) {
|
|
1576
|
-
return new Promise((resolve) => {
|
|
1577
|
-
void (async () => {
|
|
1578
|
-
for (const middleware of selectedMiddlewares) {
|
|
1579
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1580
|
-
await middleware(request);
|
|
1581
|
-
}
|
|
1582
|
-
resolve(1);
|
|
1583
|
-
})();
|
|
1584
|
-
});
|
|
1585
|
-
};
|
|
1586
|
-
}
|
|
1587
|
-
function generatePostMiddlewares(activePostMiddlewares, postMiddlewaresOptions, customPostMiddlewares) {
|
|
1588
|
-
const selectedMiddlewares = customPostMiddlewares;
|
|
1589
|
-
for (const key of activePostMiddlewares) {
|
|
1590
|
-
switch (key) {
|
|
1591
|
-
case POST_API_MIDDLEWARES.Logger: {
|
|
1592
|
-
selectedMiddlewares.push(generateConsolePostMiddleware(postMiddlewaresOptions.logger));
|
|
1593
|
-
continue;
|
|
1594
|
-
}
|
|
1595
|
-
default: {
|
|
1596
|
-
continue;
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
return function executeMiddlewares(response) {
|
|
1601
|
-
return new Promise((resolve) => {
|
|
1602
|
-
void (async () => {
|
|
1603
|
-
for (const middleware of selectedMiddlewares) {
|
|
1604
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1605
|
-
await middleware(response);
|
|
1606
|
-
}
|
|
1607
|
-
resolve(1);
|
|
1608
|
-
})();
|
|
1609
|
-
});
|
|
1610
|
-
};
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
class ResponseError extends Error {
|
|
1614
|
-
status;
|
|
1615
|
-
code;
|
|
1616
|
-
description;
|
|
1617
|
-
headers;
|
|
1618
|
-
constructor({ message, status, description, code, headers }) {
|
|
1619
|
-
super(message);
|
|
1620
|
-
this.status = status;
|
|
1621
|
-
this.description = description;
|
|
1622
|
-
this.code = code;
|
|
1623
|
-
this.headers = headers;
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
function createRequestClientInstance(options) {
|
|
1627
|
-
let executeMiddlewares;
|
|
1628
|
-
let executePostMiddlewares;
|
|
1629
|
-
function setMiddlewares({ activeMiddlewares = [], middlewareOptions = {}, customMiddlewares = [], activePostMiddlewares = [], postMiddlewaresOptions = {}, customPostMiddlewares = [], } = {}) {
|
|
1630
|
-
executeMiddlewares = generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlewares);
|
|
1631
|
-
executePostMiddlewares = generatePostMiddlewares(activePostMiddlewares, postMiddlewaresOptions, customPostMiddlewares);
|
|
1632
|
-
}
|
|
1633
|
-
setMiddlewares(options);
|
|
1634
|
-
async function handleRequest(request, responseWithStatus) {
|
|
1635
|
-
if (request.delay) {
|
|
1636
|
-
await wait(request.delay);
|
|
1637
|
-
}
|
|
1638
|
-
if (request.mock) {
|
|
1639
|
-
const mock = typeof request.mock === "function" ? request.mock() : request.mock;
|
|
1640
|
-
const transformedResult = request.transformIncomingData
|
|
1641
|
-
? request.transformIncomingData(mock)
|
|
1642
|
-
: mock;
|
|
1643
|
-
return responseWithStatus
|
|
1644
|
-
? { data: transformedResult, status: 200, headers: {} }
|
|
1645
|
-
: transformedResult;
|
|
1646
|
-
}
|
|
1647
|
-
await executeMiddlewares(request);
|
|
1648
|
-
const { method, body, path, params, headers = {} } = request;
|
|
1649
|
-
const url = createURLWithParams({ baseURL: path, params });
|
|
1650
|
-
const [, requestContentType] = Object.entries(headers).find(([header]) => header.toLowerCase() === "content-type") ?? [];
|
|
1651
|
-
let preparedBody = body;
|
|
1652
|
-
if (request.transformOutcomingData) {
|
|
1653
|
-
preparedBody = request.transformOutcomingData(body);
|
|
1654
|
-
}
|
|
1655
|
-
if (requestContentType == undefined &&
|
|
1656
|
-
!(preparedBody instanceof FormData) &&
|
|
1657
|
-
preparedBody != undefined &&
|
|
1658
|
-
!isString(preparedBody)) {
|
|
1659
|
-
headers["content-type"] = "application/json; charset=UTF-8";
|
|
1660
|
-
}
|
|
1661
|
-
if ((requestContentType == undefined || requestContentType.toLowerCase().includes("json")) &&
|
|
1662
|
-
preparedBody != undefined &&
|
|
1663
|
-
!(preparedBody instanceof FormData) &&
|
|
1664
|
-
!isString(preparedBody)) {
|
|
1665
|
-
preparedBody = JSON.stringify(preparedBody);
|
|
1666
|
-
}
|
|
1667
|
-
const response = await options.client(url, {
|
|
1668
|
-
method,
|
|
1669
|
-
body: preparedBody,
|
|
1670
|
-
headers: headers,
|
|
1671
|
-
signal: request.signal,
|
|
1672
|
-
});
|
|
1673
|
-
await executePostMiddlewares(response);
|
|
1674
|
-
if (!response) {
|
|
1675
|
-
throw new Error("hasn't response");
|
|
1676
|
-
}
|
|
1677
|
-
if (!response.ok) {
|
|
1678
|
-
if (response.status === 304) {
|
|
1679
|
-
return responseWithStatus
|
|
1680
|
-
? {
|
|
1681
|
-
data: undefined,
|
|
1682
|
-
status: response.status,
|
|
1683
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
1684
|
-
}
|
|
1685
|
-
: undefined;
|
|
1686
|
-
}
|
|
1687
|
-
if (request.defaultResponse) {
|
|
1688
|
-
const defaultResponse = typeof request.defaultResponse === "function"
|
|
1689
|
-
? request.defaultResponse()
|
|
1690
|
-
: request.defaultResponse;
|
|
1691
|
-
const transformedResult = request.transformIncomingData
|
|
1692
|
-
? request.transformIncomingData(defaultResponse)
|
|
1693
|
-
: defaultResponse;
|
|
1694
|
-
return responseWithStatus
|
|
1695
|
-
? {
|
|
1696
|
-
data: transformedResult,
|
|
1697
|
-
status: response.status,
|
|
1698
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
1699
|
-
}
|
|
1700
|
-
: transformedResult;
|
|
1701
|
-
}
|
|
1702
|
-
let result;
|
|
1703
|
-
try {
|
|
1704
|
-
const contentType = response.headers.get("content-type");
|
|
1705
|
-
if (contentType?.includes?.("text")) {
|
|
1706
|
-
result = await response.text();
|
|
1707
|
-
}
|
|
1708
|
-
else if (contentType?.includes?.("json")) {
|
|
1709
|
-
result = await response.json();
|
|
1710
|
-
}
|
|
1711
|
-
else {
|
|
1712
|
-
result = await response.blob();
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
catch {
|
|
1716
|
-
if (RESPONSE_DATA_SYMBOL in response)
|
|
1717
|
-
result = response[RESPONSE_DATA_SYMBOL];
|
|
1718
|
-
}
|
|
1719
|
-
throw new ResponseError({
|
|
1720
|
-
status: response.status,
|
|
1721
|
-
message: `HTTP error! Status: ${response.status}`,
|
|
1722
|
-
description: result,
|
|
1723
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
1724
|
-
});
|
|
1725
|
-
}
|
|
1726
|
-
if (request.downloadFile) {
|
|
1727
|
-
const data = await response.blob();
|
|
1728
|
-
const mimeType = response.headers.get("content-type");
|
|
1729
|
-
const fileName = response.headers.get("content-disposition");
|
|
1730
|
-
if (!mimeType || !fileName)
|
|
1731
|
-
throw new Error("Download Error! Empty info!");
|
|
1732
|
-
if (IS_BROWSER)
|
|
1733
|
-
downloadFile({
|
|
1734
|
-
data: data,
|
|
1735
|
-
fileName,
|
|
1736
|
-
mimeType,
|
|
1737
|
-
});
|
|
1738
|
-
return responseWithStatus
|
|
1739
|
-
? {
|
|
1740
|
-
data: data,
|
|
1741
|
-
status: response.status,
|
|
1742
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
1743
|
-
}
|
|
1744
|
-
: data;
|
|
1745
|
-
}
|
|
1746
|
-
const contentType = response.headers.get("content-type");
|
|
1747
|
-
let result = undefined;
|
|
1748
|
-
try {
|
|
1749
|
-
if (contentType?.includes?.("text")) {
|
|
1750
|
-
result = (await response.text());
|
|
1751
|
-
}
|
|
1752
|
-
else if (contentType?.includes?.("json")) {
|
|
1753
|
-
result = (await response.json());
|
|
1754
|
-
}
|
|
1755
|
-
else {
|
|
1756
|
-
result = (await response.blob());
|
|
1757
|
-
}
|
|
1758
|
-
}
|
|
1759
|
-
catch { }
|
|
1760
|
-
const transformedResult = request.transformIncomingData
|
|
1761
|
-
? request.transformIncomingData(result)
|
|
1762
|
-
: result;
|
|
1763
|
-
return responseWithStatus
|
|
1764
|
-
? {
|
|
1765
|
-
data: transformedResult,
|
|
1766
|
-
status: response.status,
|
|
1767
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
1768
|
-
}
|
|
1769
|
-
: transformedResult;
|
|
1770
|
-
}
|
|
1771
|
-
async function requestApi(request) {
|
|
1772
|
-
return handleRequest(request, false);
|
|
1773
|
-
}
|
|
1774
|
-
async function requestApiWithMeta(request) {
|
|
1775
|
-
return handleRequest(request, true);
|
|
1776
|
-
}
|
|
1777
|
-
return {
|
|
1778
|
-
requestApi,
|
|
1779
|
-
requestApiWithMeta,
|
|
1780
|
-
setMiddlewares,
|
|
1781
|
-
};
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
function getColorFormat(color) {
|
|
1785
|
-
if (color.startsWith("#")) {
|
|
1786
|
-
return COLOR_FORMATS.Hex;
|
|
1787
|
-
}
|
|
1788
|
-
if (color.startsWith("rgba")) {
|
|
1789
|
-
return COLOR_FORMATS.Rgba;
|
|
1790
|
-
}
|
|
1791
|
-
if (color.startsWith("rgb")) {
|
|
1792
|
-
return COLOR_FORMATS.Rgb;
|
|
1793
|
-
}
|
|
1794
|
-
if (color.startsWith("hsl")) {
|
|
1795
|
-
return COLOR_FORMATS.Hsl;
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
function transformHEXtoRGB(hex) {
|
|
1800
|
-
return `rgb(${hex.match(/\w\w/g)?.map((x) => +`0x${x}`)})`;
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
function transformRGBtoRGBA(rgb, opacity) {
|
|
1804
|
-
const code = rgb.match(/\d+/g);
|
|
1805
|
-
code?.push(String(opacity / 100));
|
|
1806
|
-
return `rgba(${code?.join(",")})`;
|
|
1807
|
-
}
|
|
1808
|
-
|
|
1809
|
-
function transformRGBAtoRGB(rgba) {
|
|
1810
|
-
const code = rgba.match(/\d+/g);
|
|
1811
|
-
code?.splice(3);
|
|
1812
|
-
return `rgb(${code?.join(",")})`;
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
function takeOpacityColors(color, opacities) {
|
|
1816
|
-
let rgbColor = color;
|
|
1817
|
-
if (!rgbColor)
|
|
1818
|
-
return [];
|
|
1819
|
-
if (getColorFormat(rgbColor) === COLOR_FORMATS.Hex) {
|
|
1820
|
-
rgbColor = transformHEXtoRGB(rgbColor);
|
|
1821
|
-
}
|
|
1822
|
-
else if (getColorFormat(rgbColor) === COLOR_FORMATS.Rgba) {
|
|
1823
|
-
rgbColor = transformRGBAtoRGB(rgbColor);
|
|
1824
|
-
}
|
|
1825
|
-
if (getColorFormat(rgbColor) !== COLOR_FORMATS.Rgb)
|
|
1826
|
-
return [];
|
|
1827
|
-
return [...opacities.map((opacity) => transformRGBtoRGBA(rgbColor, opacity))];
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
function transformToColor(currentColor, defaultColor = "black", defaultFormat = COLOR_FORMATS.Hex) {
|
|
1831
|
-
if (!isString(currentColor))
|
|
1832
|
-
return defaultColor;
|
|
1833
|
-
let correctColor = currentColor;
|
|
1834
|
-
if (!getColorFormat(correctColor)) {
|
|
1835
|
-
switch (defaultFormat) {
|
|
1836
|
-
case COLOR_FORMATS.Hex: {
|
|
1837
|
-
correctColor = `#${correctColor}`;
|
|
1838
|
-
break;
|
|
1839
|
-
}
|
|
1840
|
-
case COLOR_FORMATS.Rgb: {
|
|
1841
|
-
correctColor = `rgb(${correctColor})`;
|
|
1842
|
-
break;
|
|
1843
|
-
}
|
|
1844
|
-
case COLOR_FORMATS.Rgba: {
|
|
1845
|
-
correctColor = `rgba(${correctColor})`;
|
|
1846
|
-
break;
|
|
1847
|
-
}
|
|
1848
|
-
case COLOR_FORMATS.Hsl: {
|
|
1849
|
-
correctColor = `hsl(${correctColor})`;
|
|
1850
|
-
break;
|
|
1851
|
-
}
|
|
1852
|
-
default: {
|
|
1853
|
-
correctColor = `#${correctColor}`;
|
|
1854
|
-
break;
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
return correctColor;
|
|
1389
|
+
return correctColor;
|
|
1859
1390
|
}
|
|
1860
1391
|
|
|
1861
1392
|
function getRandomColor() {
|
|
@@ -2068,7 +1599,570 @@ function throttle({ interval }, func) {
|
|
|
2068
1599
|
return throttled;
|
|
2069
1600
|
}
|
|
2070
1601
|
|
|
2071
|
-
|
|
1602
|
+
const RESPONSE_DATA_SYMBOL = Symbol("response data");
|
|
1603
|
+
const REQUEST_ERROR = {
|
|
1604
|
+
HTTP_ERROR: "http",
|
|
1605
|
+
NETWORK_ERROR: "network",
|
|
1606
|
+
TIMEOUT_ERROR: "timeout",
|
|
1607
|
+
ABORT_ERROR: "abort",
|
|
1608
|
+
VALIDATION_ERROR: "validation",
|
|
1609
|
+
CACHE_ERROR: "cache",
|
|
1610
|
+
UNKNOWN_ERROR: "unknown",
|
|
1611
|
+
};
|
|
1612
|
+
class OauthState {
|
|
1613
|
+
_fetching = false;
|
|
1614
|
+
get fetching() {
|
|
1615
|
+
return this._fetching;
|
|
1616
|
+
}
|
|
1617
|
+
set fetching(value) {
|
|
1618
|
+
this._fetching = value;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
const OAUTH_STATE = new OauthState();
|
|
1622
|
+
|
|
1623
|
+
async function getOauthTokenFromOtherWindow(options) {
|
|
1624
|
+
let waiting = true;
|
|
1625
|
+
const url = new URL(typeof options.refreshTokenWindowUrl === "function"
|
|
1626
|
+
? options.refreshTokenWindowUrl()
|
|
1627
|
+
: (options.refreshTokenWindowUrl ?? window.origin));
|
|
1628
|
+
url.searchParams.append(options.onlyRefreshTokenWindowQueryName, "true");
|
|
1629
|
+
let windowInstance = window.open(url.toString(), "_blank", "width=800,height=600,left=100,top=100");
|
|
1630
|
+
windowInstance ??= window.open(url.toString(), "_blank");
|
|
1631
|
+
if (windowInstance) {
|
|
1632
|
+
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName);
|
|
1633
|
+
const windowCloseObserver = setInterval(() => {
|
|
1634
|
+
if (windowInstance.closed) {
|
|
1635
|
+
if (waiting) {
|
|
1636
|
+
waiting = false;
|
|
1637
|
+
channel.close();
|
|
1638
|
+
clearInterval(windowCloseObserver);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}, options.closeObserveInterval ?? 500);
|
|
1642
|
+
channel.onmessage = () => {
|
|
1643
|
+
if (waiting) {
|
|
1644
|
+
waiting = false;
|
|
1645
|
+
channel.close();
|
|
1646
|
+
clearInterval(windowCloseObserver);
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
setTimeout(() => {
|
|
1650
|
+
if (waiting) {
|
|
1651
|
+
waiting = false;
|
|
1652
|
+
channel.close();
|
|
1653
|
+
clearInterval(windowCloseObserver);
|
|
1654
|
+
}
|
|
1655
|
+
if (windowInstance && !windowInstance.closed) {
|
|
1656
|
+
windowInstance.close();
|
|
1657
|
+
}
|
|
1658
|
+
}, options.wait ?? 15000);
|
|
1659
|
+
}
|
|
1660
|
+
else {
|
|
1661
|
+
if (options.onWindowOpenError)
|
|
1662
|
+
options.onWindowOpenError();
|
|
1663
|
+
waiting = false;
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
await waitUntil(() => waiting);
|
|
1667
|
+
}
|
|
1668
|
+
async function refetchAfterOauth(options, refetch) {
|
|
1669
|
+
OAUTH_STATE.fetching = true;
|
|
1670
|
+
await getOauthTokenFromOtherWindow({
|
|
1671
|
+
onlyRefreshTokenWindowQueryName: options.onlyRefreshTokenWindowQueryName,
|
|
1672
|
+
onWindowOpenError: options.onWindowOpenError,
|
|
1673
|
+
refreshTokenWindowUrl: options.refreshTokenWindowUrl,
|
|
1674
|
+
wait: options.wait,
|
|
1675
|
+
expiresTokenStorageName: options.expiresTokenStorageName,
|
|
1676
|
+
closeObserveInterval: options.closeObserveInterval,
|
|
1677
|
+
});
|
|
1678
|
+
if (options.tokenRequest) {
|
|
1679
|
+
const token = await options.tokenRequest();
|
|
1680
|
+
if (token != undefined && options.tokenStorageName) {
|
|
1681
|
+
localStorage.setItem(options.tokenStorageName, token);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
OAUTH_STATE.fetching = false;
|
|
1685
|
+
return await refetch();
|
|
1686
|
+
}
|
|
1687
|
+
function getOauthToken(options) {
|
|
1688
|
+
const queries = getQueryValues([
|
|
1689
|
+
options.expiresTokenQueryName,
|
|
1690
|
+
options.onlyRefreshTokenWindowQueryName,
|
|
1691
|
+
]);
|
|
1692
|
+
const refreshQuery = queries?.[options.onlyRefreshTokenWindowQueryName];
|
|
1693
|
+
const expiresQuery = queries?.[options.expiresTokenQueryName];
|
|
1694
|
+
/** Is OnlyRefresh window */
|
|
1695
|
+
const isRefresh = isString(refreshQuery)
|
|
1696
|
+
? refreshQuery === "true"
|
|
1697
|
+
: isArray(refreshQuery)
|
|
1698
|
+
? refreshQuery[refreshQuery.length - 1] === "true"
|
|
1699
|
+
: false;
|
|
1700
|
+
/** Expires token */
|
|
1701
|
+
const expires = isString(expiresQuery)
|
|
1702
|
+
? expiresQuery
|
|
1703
|
+
: isArray(expiresQuery)
|
|
1704
|
+
? expiresQuery[expiresQuery.length - 1]
|
|
1705
|
+
: false;
|
|
1706
|
+
/** OAuth flow if not expires */
|
|
1707
|
+
if (!expires) {
|
|
1708
|
+
window.location.replace(typeof options.oauthUrl === "function" ? options.oauthUrl() : options.oauthUrl);
|
|
1709
|
+
return null;
|
|
1710
|
+
}
|
|
1711
|
+
localStorage.setItem(options.expiresTokenStorageName, expires);
|
|
1712
|
+
/** Close if OnlyRefresh window */
|
|
1713
|
+
if (isRefresh) {
|
|
1714
|
+
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName);
|
|
1715
|
+
channel.postMessage(true);
|
|
1716
|
+
channel.close();
|
|
1717
|
+
window.close();
|
|
1718
|
+
}
|
|
1719
|
+
/** Delete expires query */
|
|
1720
|
+
if (expires) {
|
|
1721
|
+
const url = new URL(window.location.href);
|
|
1722
|
+
url.searchParams.delete(options.expiresTokenQueryName);
|
|
1723
|
+
window.location.replace(url.toString());
|
|
1724
|
+
return null;
|
|
1725
|
+
}
|
|
1726
|
+
return expires;
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
function createFetchClient(options) {
|
|
1730
|
+
let client = options.client;
|
|
1731
|
+
let oauthOptions = options.oauthOptions;
|
|
1732
|
+
let beforeHandlers = options.beforeHandlers;
|
|
1733
|
+
let afterHandlers = options.afterHandlers;
|
|
1734
|
+
let retries = options.retries;
|
|
1735
|
+
let timeout = options.timeout;
|
|
1736
|
+
function recreate(options) {
|
|
1737
|
+
if ("client" in options) {
|
|
1738
|
+
client = options.client;
|
|
1739
|
+
}
|
|
1740
|
+
if ("oauthOptions" in options) {
|
|
1741
|
+
oauthOptions = options.oauthOptions;
|
|
1742
|
+
}
|
|
1743
|
+
if ("beforeHandlers" in options) {
|
|
1744
|
+
beforeHandlers = options.beforeHandlers;
|
|
1745
|
+
}
|
|
1746
|
+
if ("afterHandlers" in options) {
|
|
1747
|
+
afterHandlers = options.afterHandlers;
|
|
1748
|
+
}
|
|
1749
|
+
if ("retries" in options) {
|
|
1750
|
+
retries = options.retries;
|
|
1751
|
+
}
|
|
1752
|
+
if ("timeout" in options) {
|
|
1753
|
+
timeout = options.timeout;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
async function handleRequest(request) {
|
|
1757
|
+
const timeoutController = new AbortController();
|
|
1758
|
+
const requestController = new AbortController();
|
|
1759
|
+
const requestTimeout = request.timeout ?? timeout;
|
|
1760
|
+
const requestRetries = request.retries ?? retries;
|
|
1761
|
+
try {
|
|
1762
|
+
if (request.delay) {
|
|
1763
|
+
await wait(request.delay);
|
|
1764
|
+
}
|
|
1765
|
+
if (request.mock) {
|
|
1766
|
+
const mock = typeof request.mock === "function" ? request.mock() : request.mock;
|
|
1767
|
+
const transformedResult = request.transformIncomingData
|
|
1768
|
+
? request.transformIncomingData(mock)
|
|
1769
|
+
: mock;
|
|
1770
|
+
return { data: transformedResult, error: null, response: null };
|
|
1771
|
+
}
|
|
1772
|
+
if (requestTimeout != undefined && requestTimeout != 0) {
|
|
1773
|
+
setTimeout(() => {
|
|
1774
|
+
if (requestController.signal.aborted)
|
|
1775
|
+
return;
|
|
1776
|
+
timeoutController.abort();
|
|
1777
|
+
}, requestTimeout);
|
|
1778
|
+
timeoutController.signal.addEventListener("abort", () => requestController.abort(), {
|
|
1779
|
+
once: true,
|
|
1780
|
+
signal: requestController.signal,
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
if (request.signal) {
|
|
1784
|
+
request.signal.addEventListener("abort", () => requestController.abort(), {
|
|
1785
|
+
once: true,
|
|
1786
|
+
signal: requestController.signal,
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
{
|
|
1790
|
+
let handlers = [];
|
|
1791
|
+
if (request.beforeHandlers) {
|
|
1792
|
+
handlers = request.beforeHandlers;
|
|
1793
|
+
}
|
|
1794
|
+
else if (beforeHandlers) {
|
|
1795
|
+
handlers = beforeHandlers;
|
|
1796
|
+
}
|
|
1797
|
+
if (request.additionalBeforeHandlers) {
|
|
1798
|
+
handlers = handlers.concat(request.additionalBeforeHandlers);
|
|
1799
|
+
}
|
|
1800
|
+
if (handlers.length > 0) {
|
|
1801
|
+
await executeBeforeHandlers(handlers, request);
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
const { method, body, path, queries, headers = {}, refetchNoAuth = true } = request;
|
|
1805
|
+
const url = createURLWithQueries({ baseURL: path, params: queries });
|
|
1806
|
+
let [, requestContentType] = Object.entries(headers).find(([header]) => header.toLowerCase() === "content-type") ?? [];
|
|
1807
|
+
if (isArray(requestContentType)) {
|
|
1808
|
+
requestContentType = requestContentType[0];
|
|
1809
|
+
}
|
|
1810
|
+
let preparedBody = body;
|
|
1811
|
+
if (request.transformOutcomingData) {
|
|
1812
|
+
preparedBody = request.transformOutcomingData(body);
|
|
1813
|
+
}
|
|
1814
|
+
if (requestContentType == undefined &&
|
|
1815
|
+
!(preparedBody instanceof FormData) &&
|
|
1816
|
+
preparedBody != undefined &&
|
|
1817
|
+
!isString(preparedBody)) {
|
|
1818
|
+
headers["content-type"] = "application/json; charset=UTF-8";
|
|
1819
|
+
}
|
|
1820
|
+
if ((requestContentType == undefined || requestContentType.toLowerCase().includes("json")) &&
|
|
1821
|
+
preparedBody != undefined &&
|
|
1822
|
+
!(preparedBody instanceof FormData) &&
|
|
1823
|
+
!isString(preparedBody)) {
|
|
1824
|
+
preparedBody = JSON.stringify(preparedBody);
|
|
1825
|
+
}
|
|
1826
|
+
const response = await client(url, {
|
|
1827
|
+
method,
|
|
1828
|
+
body: preparedBody,
|
|
1829
|
+
headers: headers,
|
|
1830
|
+
signal: requestController.signal,
|
|
1831
|
+
cache: request.cache,
|
|
1832
|
+
credentials: request.credentials,
|
|
1833
|
+
integrity: request.integrity,
|
|
1834
|
+
keepalive: request.keepalive,
|
|
1835
|
+
mode: request.mode,
|
|
1836
|
+
priority: request.priority,
|
|
1837
|
+
redirect: request.redirect,
|
|
1838
|
+
referrer: request.referrer,
|
|
1839
|
+
referrerPolicy: request.referrerPolicy,
|
|
1840
|
+
compress: request.compress,
|
|
1841
|
+
follow: request.follow,
|
|
1842
|
+
});
|
|
1843
|
+
{
|
|
1844
|
+
let handlers = [];
|
|
1845
|
+
if (request.afterHandlers) {
|
|
1846
|
+
handlers = request.afterHandlers;
|
|
1847
|
+
}
|
|
1848
|
+
else if (afterHandlers) {
|
|
1849
|
+
handlers = afterHandlers;
|
|
1850
|
+
}
|
|
1851
|
+
if (request.additionalAfterHandlers) {
|
|
1852
|
+
handlers = handlers.concat(request.additionalAfterHandlers);
|
|
1853
|
+
}
|
|
1854
|
+
if (handlers.length > 0) {
|
|
1855
|
+
await executeAfterHandlers(handlers, request, response);
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
if (!response.ok) {
|
|
1859
|
+
if (response.status === 304) {
|
|
1860
|
+
const error = new ResponseError({
|
|
1861
|
+
message: REQUEST_ERROR.CACHE_ERROR,
|
|
1862
|
+
status: response.status,
|
|
1863
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
1864
|
+
});
|
|
1865
|
+
request.onError?.(REQUEST_ERROR.CACHE_ERROR, error);
|
|
1866
|
+
return { data: error, error: REQUEST_ERROR.CACHE_ERROR, response };
|
|
1867
|
+
}
|
|
1868
|
+
if (response.status === 401 && refetchNoAuth && oauthOptions) {
|
|
1869
|
+
return await refetchAfterOauth(oauthOptions, () => handleRequest({ ...request, refetchNoAuth: false }));
|
|
1870
|
+
}
|
|
1871
|
+
if (request.defaultResponse) {
|
|
1872
|
+
const defaultResponse = typeof request.defaultResponse === "function"
|
|
1873
|
+
? request.defaultResponse()
|
|
1874
|
+
: request.defaultResponse;
|
|
1875
|
+
const transformedResult = request.transformIncomingData
|
|
1876
|
+
? request.transformIncomingData(defaultResponse)
|
|
1877
|
+
: defaultResponse;
|
|
1878
|
+
return {
|
|
1879
|
+
data: transformedResult,
|
|
1880
|
+
error: null,
|
|
1881
|
+
response: null,
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
if (requestRetries && requestRetries.length > 0) {
|
|
1885
|
+
await wait(requestRetries[0]);
|
|
1886
|
+
return await handleRequest({ ...request, retries: requestRetries.slice(1) });
|
|
1887
|
+
}
|
|
1888
|
+
let result;
|
|
1889
|
+
try {
|
|
1890
|
+
const contentType = response.headers.get("content-type");
|
|
1891
|
+
if (RESPONSE_DATA_SYMBOL in response) {
|
|
1892
|
+
result = response[RESPONSE_DATA_SYMBOL];
|
|
1893
|
+
}
|
|
1894
|
+
else if (contentType?.includes?.("text")) {
|
|
1895
|
+
result = await response.text();
|
|
1896
|
+
}
|
|
1897
|
+
else if (contentType?.includes?.("json")) {
|
|
1898
|
+
result = await response.json();
|
|
1899
|
+
}
|
|
1900
|
+
else {
|
|
1901
|
+
result = await response.blob();
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
catch { }
|
|
1905
|
+
const error = new ResponseError({
|
|
1906
|
+
status: response.status,
|
|
1907
|
+
message: REQUEST_ERROR.HTTP_ERROR,
|
|
1908
|
+
description: result,
|
|
1909
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
1910
|
+
});
|
|
1911
|
+
request.onError?.(REQUEST_ERROR.HTTP_ERROR, error);
|
|
1912
|
+
return {
|
|
1913
|
+
data: error,
|
|
1914
|
+
error: REQUEST_ERROR.HTTP_ERROR,
|
|
1915
|
+
response,
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
if (request.download) {
|
|
1919
|
+
const data = await response.blob();
|
|
1920
|
+
const mimeType = response.headers.get("content-type");
|
|
1921
|
+
const fileName = response.headers.get("content-disposition");
|
|
1922
|
+
if (!mimeType) {
|
|
1923
|
+
console.warn("couldn't download file because content-type header is not exist");
|
|
1924
|
+
}
|
|
1925
|
+
else if (!fileName) {
|
|
1926
|
+
console.warn("couldn't download file because content-disposition header is not exist");
|
|
1927
|
+
}
|
|
1928
|
+
if (IS_BROWSER && mimeType && fileName)
|
|
1929
|
+
downloadFile({
|
|
1930
|
+
data: data,
|
|
1931
|
+
fileName,
|
|
1932
|
+
mimeType,
|
|
1933
|
+
});
|
|
1934
|
+
return {
|
|
1935
|
+
data: data,
|
|
1936
|
+
error: null,
|
|
1937
|
+
response,
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
const contentType = response.headers.get("content-type");
|
|
1941
|
+
let result = undefined;
|
|
1942
|
+
if (RESPONSE_DATA_SYMBOL in response) {
|
|
1943
|
+
result = response[RESPONSE_DATA_SYMBOL];
|
|
1944
|
+
}
|
|
1945
|
+
else if (contentType?.includes?.("text")) {
|
|
1946
|
+
result = (await response.text());
|
|
1947
|
+
}
|
|
1948
|
+
else if (contentType?.includes?.("json")) {
|
|
1949
|
+
result = (await response.json());
|
|
1950
|
+
}
|
|
1951
|
+
else {
|
|
1952
|
+
result = (await response.blob());
|
|
1953
|
+
}
|
|
1954
|
+
const transformedResult = request.transformIncomingData
|
|
1955
|
+
? request.transformIncomingData(result)
|
|
1956
|
+
: result;
|
|
1957
|
+
return {
|
|
1958
|
+
data: transformedResult,
|
|
1959
|
+
error: null,
|
|
1960
|
+
response,
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
catch (err) {
|
|
1964
|
+
if (request.defaultResponse) {
|
|
1965
|
+
const defaultResponse = typeof request.defaultResponse === "function"
|
|
1966
|
+
? request.defaultResponse()
|
|
1967
|
+
: request.defaultResponse;
|
|
1968
|
+
const transformedResult = request.transformIncomingData
|
|
1969
|
+
? request.transformIncomingData(defaultResponse)
|
|
1970
|
+
: defaultResponse;
|
|
1971
|
+
return {
|
|
1972
|
+
data: transformedResult,
|
|
1973
|
+
error: null,
|
|
1974
|
+
response: null,
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
if (requestRetries && requestRetries.length > 0 && request?.signal?.aborted !== true) {
|
|
1978
|
+
await wait(requestRetries[0]);
|
|
1979
|
+
return await handleRequest({ ...request, retries: requestRetries.slice(1) });
|
|
1980
|
+
}
|
|
1981
|
+
if (err instanceof TypeError) {
|
|
1982
|
+
const error = new ResponseError({
|
|
1983
|
+
message: REQUEST_ERROR.NETWORK_ERROR,
|
|
1984
|
+
status: 0,
|
|
1985
|
+
description: String(err.message),
|
|
1986
|
+
});
|
|
1987
|
+
request.onError?.(REQUEST_ERROR.NETWORK_ERROR, error);
|
|
1988
|
+
return { data: error, error: REQUEST_ERROR.NETWORK_ERROR, response: null };
|
|
1989
|
+
}
|
|
1990
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
1991
|
+
if (timeoutController.signal.aborted) {
|
|
1992
|
+
const error = new ResponseError({
|
|
1993
|
+
message: REQUEST_ERROR.TIMEOUT_ERROR,
|
|
1994
|
+
status: 0,
|
|
1995
|
+
});
|
|
1996
|
+
request.onError?.(REQUEST_ERROR.TIMEOUT_ERROR, error);
|
|
1997
|
+
return { data: error, error: REQUEST_ERROR.TIMEOUT_ERROR, response: null };
|
|
1998
|
+
}
|
|
1999
|
+
const error = new ResponseError({
|
|
2000
|
+
message: REQUEST_ERROR.ABORT_ERROR,
|
|
2001
|
+
status: 0,
|
|
2002
|
+
});
|
|
2003
|
+
request.onError?.(REQUEST_ERROR.ABORT_ERROR, error);
|
|
2004
|
+
return { data: error, error: REQUEST_ERROR.ABORT_ERROR, response: null };
|
|
2005
|
+
}
|
|
2006
|
+
const error = new ResponseError({
|
|
2007
|
+
message: REQUEST_ERROR.UNKNOWN_ERROR,
|
|
2008
|
+
status: 0,
|
|
2009
|
+
description: String(err),
|
|
2010
|
+
});
|
|
2011
|
+
request.onError?.(REQUEST_ERROR.UNKNOWN_ERROR, error);
|
|
2012
|
+
return { data: error, error: REQUEST_ERROR.UNKNOWN_ERROR, response: null };
|
|
2013
|
+
}
|
|
2014
|
+
finally {
|
|
2015
|
+
requestController.abort();
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
async function requestWithArrayResponse(request) {
|
|
2019
|
+
const response = await handleRequest(request);
|
|
2020
|
+
return [response.data, response.error, response.response];
|
|
2021
|
+
}
|
|
2022
|
+
async function requestWithObjectResponse(request) {
|
|
2023
|
+
return handleRequest(request);
|
|
2024
|
+
}
|
|
2025
|
+
return {
|
|
2026
|
+
requestWithArrayResponse,
|
|
2027
|
+
requestWithObjectResponse,
|
|
2028
|
+
recreate,
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
function executeBeforeHandlers(handlers, request) {
|
|
2032
|
+
return new Promise((resolve) => {
|
|
2033
|
+
void (async () => {
|
|
2034
|
+
for (const handler of handlers) {
|
|
2035
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2036
|
+
await handler(request);
|
|
2037
|
+
}
|
|
2038
|
+
resolve(1);
|
|
2039
|
+
})();
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
function executeAfterHandlers(handlers, request, response) {
|
|
2043
|
+
return new Promise((resolve) => {
|
|
2044
|
+
void (async () => {
|
|
2045
|
+
for (const handler of handlers) {
|
|
2046
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2047
|
+
await handler(request, response);
|
|
2048
|
+
}
|
|
2049
|
+
resolve(1);
|
|
2050
|
+
})();
|
|
2051
|
+
});
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
function loggerAfterHandler(options = {}) {
|
|
2055
|
+
return (request, response) => {
|
|
2056
|
+
return new Promise((resolve) => {
|
|
2057
|
+
void (async function logger() {
|
|
2058
|
+
try {
|
|
2059
|
+
if (!response ||
|
|
2060
|
+
(options.filter && !options.filter(response)) ||
|
|
2061
|
+
(options.filterStatus && !options.filterStatus(response.status)) ||
|
|
2062
|
+
(options.filterUrl && !options.filterUrl(response.url)) ||
|
|
2063
|
+
(options.filterHeaders && !options.filterHeaders(response.headers))) {
|
|
2064
|
+
resolve(true);
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
const contentType = response.headers.get("content-type");
|
|
2068
|
+
let result;
|
|
2069
|
+
if (contentType?.includes?.("text")) {
|
|
2070
|
+
result = await response.text();
|
|
2071
|
+
}
|
|
2072
|
+
else if (contentType?.includes?.("json")) {
|
|
2073
|
+
result = await response.json();
|
|
2074
|
+
}
|
|
2075
|
+
else {
|
|
2076
|
+
result = await response.blob();
|
|
2077
|
+
}
|
|
2078
|
+
Object.defineProperty(response, RESPONSE_DATA_SYMBOL, {
|
|
2079
|
+
value: result,
|
|
2080
|
+
writable: false,
|
|
2081
|
+
enumerable: false,
|
|
2082
|
+
configurable: true,
|
|
2083
|
+
});
|
|
2084
|
+
console.log({
|
|
2085
|
+
url: response.url,
|
|
2086
|
+
status: response.status,
|
|
2087
|
+
headers: response.headers,
|
|
2088
|
+
body: result,
|
|
2089
|
+
});
|
|
2090
|
+
resolve(true);
|
|
2091
|
+
}
|
|
2092
|
+
catch {
|
|
2093
|
+
if (response) {
|
|
2094
|
+
console.log({ url: response.url, status: response.status, headers: response.headers });
|
|
2095
|
+
}
|
|
2096
|
+
resolve(true);
|
|
2097
|
+
}
|
|
2098
|
+
})().finally(() => {
|
|
2099
|
+
resolve(true);
|
|
2100
|
+
});
|
|
2101
|
+
});
|
|
2102
|
+
};
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
function loggerBeforeHandler(options = {}) {
|
|
2106
|
+
return (request) => {
|
|
2107
|
+
return new Promise((resolve) => {
|
|
2108
|
+
if ((options.filter &&
|
|
2109
|
+
!options.filter(request)) ||
|
|
2110
|
+
(options.filterHeaders && !options.filterHeaders(request.headers)) ||
|
|
2111
|
+
(options.filterMethod && !options.filterMethod(request.method)) ||
|
|
2112
|
+
(options.filterParams && !options.filterParams(request.queries)) ||
|
|
2113
|
+
(options.filterPath && !options.filterPath(request.path))) {
|
|
2114
|
+
resolve(true);
|
|
2115
|
+
return;
|
|
2116
|
+
}
|
|
2117
|
+
// eslint-disable-next-line no-console
|
|
2118
|
+
console.log(request);
|
|
2119
|
+
resolve(true);
|
|
2120
|
+
});
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
const oauthBeforeHandler = (options) => async (request) => {
|
|
2125
|
+
if (!options.expiresTokenStorageName) {
|
|
2126
|
+
throw new Error("Auth middleware hasn't required options");
|
|
2127
|
+
}
|
|
2128
|
+
const isSameOrigin = !startWith(request.path, "http");
|
|
2129
|
+
if (request.token) {
|
|
2130
|
+
if (!isSameOrigin)
|
|
2131
|
+
request.headers = {
|
|
2132
|
+
...request.headers,
|
|
2133
|
+
Authorization: `Bearer ${request.token}`,
|
|
2134
|
+
};
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (OAUTH_STATE.fetching)
|
|
2138
|
+
await waitUntil(() => OAUTH_STATE.fetching);
|
|
2139
|
+
const expires = localStorage.getItem(options.expiresTokenStorageName);
|
|
2140
|
+
let token;
|
|
2141
|
+
if (!expires || Number.isNaN(+expires) || Date.now() > +expires) {
|
|
2142
|
+
OAUTH_STATE.fetching = true;
|
|
2143
|
+
await getOauthTokenFromOtherWindow({
|
|
2144
|
+
onlyRefreshTokenWindowQueryName: options.onlyRefreshTokenWindowQueryName,
|
|
2145
|
+
onWindowOpenError: options.onWindowOpenError,
|
|
2146
|
+
refreshTokenWindowUrl: options.refreshTokenWindowUrl,
|
|
2147
|
+
wait: options.wait,
|
|
2148
|
+
expiresTokenStorageName: options.expiresTokenStorageName,
|
|
2149
|
+
closeObserveInterval: options.closeObserveInterval,
|
|
2150
|
+
});
|
|
2151
|
+
if (options.tokenRequest) {
|
|
2152
|
+
token = await options.tokenRequest();
|
|
2153
|
+
if (token != undefined && options.tokenStorageName) {
|
|
2154
|
+
localStorage.setItem(options.tokenStorageName, token);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
OAUTH_STATE.fetching = false;
|
|
2158
|
+
}
|
|
2159
|
+
if (!isSameOrigin && token)
|
|
2160
|
+
request.headers = {
|
|
2161
|
+
...request.headers,
|
|
2162
|
+
Authorization: `Bearer ${token}`,
|
|
2163
|
+
};
|
|
2164
|
+
};
|
|
2165
|
+
|
|
2072
2166
|
exports.COLOR_FORMATS = COLOR_FORMATS;
|
|
2073
2167
|
exports.DATE_TYPES = DATE_TYPES;
|
|
2074
2168
|
exports.FIELD_TYPES = FIELD_TYPES;
|
|
@@ -2078,17 +2172,19 @@ exports.IS_DENO = IS_DENO;
|
|
|
2078
2172
|
exports.IS_JEST = IS_JEST;
|
|
2079
2173
|
exports.IS_NODE = IS_NODE;
|
|
2080
2174
|
exports.IS_WEB_WORKER = IS_WEB_WORKER;
|
|
2081
|
-
exports.
|
|
2175
|
+
exports.OAUTH_STATE = OAUTH_STATE;
|
|
2176
|
+
exports.REQUEST_ERROR = REQUEST_ERROR;
|
|
2177
|
+
exports.RESPONSE_DATA_SYMBOL = RESPONSE_DATA_SYMBOL;
|
|
2082
2178
|
exports.ResponseError = ResponseError;
|
|
2083
2179
|
exports.arrayToMapByKey = arrayToMapByKey;
|
|
2084
2180
|
exports.buildQueryString = buildQueryString;
|
|
2085
2181
|
exports.checkType = checkType;
|
|
2086
2182
|
exports.cloneDeep = cloneDeep;
|
|
2087
2183
|
exports.copyToClipboard = copyToClipboard;
|
|
2184
|
+
exports.createFetchClient = createFetchClient;
|
|
2088
2185
|
exports.createGlobalId = createGlobalId;
|
|
2089
2186
|
exports.createLocalIdGenerator = createLocalIdGenerator;
|
|
2090
|
-
exports.
|
|
2091
|
-
exports.createURLWithParams = createURLWithParams;
|
|
2187
|
+
exports.createURLWithQueries = createURLWithQueries;
|
|
2092
2188
|
exports.dateDifference = dateDifference;
|
|
2093
2189
|
exports.dateFormat = dateFormat;
|
|
2094
2190
|
exports.debounce = debounce;
|
|
@@ -2101,7 +2197,6 @@ exports.downloadJson = downloadJson;
|
|
|
2101
2197
|
exports.execAnimation = execAnimation;
|
|
2102
2198
|
exports.extractQueries = extractQueries;
|
|
2103
2199
|
exports.fieldViewFormat = fieldViewFormat;
|
|
2104
|
-
exports.getAuthUser = getAuthUser;
|
|
2105
2200
|
exports.getByPath = getByPath;
|
|
2106
2201
|
exports.getCallerFunctionName = getCallerFunctionName;
|
|
2107
2202
|
exports.getColorFormat = getColorFormat;
|
|
@@ -2133,9 +2228,13 @@ exports.isYesterday = isYesterday;
|
|
|
2133
2228
|
exports.joinPaths = joinPaths;
|
|
2134
2229
|
exports.jsonParse = jsonParse;
|
|
2135
2230
|
exports.limitStreamOfRequests = limitStreamOfRequests;
|
|
2231
|
+
exports.loggerAfterHandler = loggerAfterHandler;
|
|
2232
|
+
exports.loggerBeforeHandler = loggerBeforeHandler;
|
|
2233
|
+
exports.oauthBeforeHandler = oauthBeforeHandler;
|
|
2136
2234
|
exports.randomNumber = randomNumber;
|
|
2137
2235
|
exports.randomString = randomString;
|
|
2138
2236
|
exports.readFile = readFile;
|
|
2237
|
+
exports.refetchAfterOauth = refetchAfterOauth;
|
|
2139
2238
|
exports.setByPath = setByPath;
|
|
2140
2239
|
exports.speedTest = speedTest;
|
|
2141
2240
|
exports.startWith = startWith;
|
|
@@ -2151,7 +2250,6 @@ exports.transformToNumber = transformToNumber;
|
|
|
2151
2250
|
exports.translit = translit;
|
|
2152
2251
|
exports.trimUrl = trimUrl;
|
|
2153
2252
|
exports.type = type;
|
|
2154
|
-
exports.updateAuthUser = updateAuthUser;
|
|
2155
2253
|
exports.wait = wait;
|
|
2156
2254
|
exports.waitUntil = waitUntil;
|
|
2157
2255
|
//# sourceMappingURL=index.cjs.map
|