@krainovsd/js-helpers 0.8.1 → 0.10.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 +230 -14
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/constants/api.js +5 -1
- package/lib/esm/constants/api.js.map +1 -1
- package/lib/esm/index.js +2 -2
- package/lib/esm/lib/api/auth/token.js +73 -1
- package/lib/esm/lib/api/auth/token.js.map +1 -1
- package/lib/esm/lib/api/core.js +26 -3
- package/lib/esm/lib/api/core.js.map +1 -1
- package/lib/esm/lib/api/middlewares/auth-no-refresh-middleware.js +43 -0
- package/lib/esm/lib/api/middlewares/auth-no-refresh-middleware.js.map +1 -0
- package/lib/esm/lib/api/middlewares/console-middleware.js +19 -8
- package/lib/esm/lib/api/middlewares/console-middleware.js.map +1 -1
- package/lib/esm/lib/api/middlewares/console-post-middleware.js +47 -0
- package/lib/esm/lib/api/middlewares/console-post-middleware.js.map +1 -0
- package/lib/esm/lib/api/middlewares/index.js +36 -4
- package/lib/esm/lib/api/middlewares/index.js.map +1 -1
- package/lib/index.d.ts +59 -5
- package/package.json +1 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -20,6 +20,10 @@ const DATE_TYPES = {
|
|
|
20
20
|
|
|
21
21
|
const API_MIDDLEWARES = {
|
|
22
22
|
Auth: "auth",
|
|
23
|
+
AuthNoRefresh: "authNoRefresh",
|
|
24
|
+
Logger: "logger",
|
|
25
|
+
};
|
|
26
|
+
const POST_API_MIDDLEWARES = {
|
|
23
27
|
Logger: "logger",
|
|
24
28
|
};
|
|
25
29
|
|
|
@@ -1317,6 +1321,76 @@ function transformData(data, pathToToken, pathToTokenExpires) {
|
|
|
1317
1321
|
token,
|
|
1318
1322
|
};
|
|
1319
1323
|
}
|
|
1324
|
+
async function getAuthTokenNoRefresh(options) {
|
|
1325
|
+
let waiting = true;
|
|
1326
|
+
const url = new URL(window.origin);
|
|
1327
|
+
url.searchParams.append(options.queryTokenExpiresName, "true");
|
|
1328
|
+
let windowInstance = window.open(url.toString(), "_blank", "width=800,height=600,left=100,top=100");
|
|
1329
|
+
if (!windowInstance) {
|
|
1330
|
+
windowInstance = window.open(url.toString());
|
|
1331
|
+
}
|
|
1332
|
+
if (!windowInstance) {
|
|
1333
|
+
if (options.onWindowOpenError)
|
|
1334
|
+
options.onWindowOpenError();
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
const channel = new BroadcastChannel(options.queryIsRefreshTokenName);
|
|
1338
|
+
channel.onmessage = () => {
|
|
1339
|
+
if (waiting) {
|
|
1340
|
+
waiting = false;
|
|
1341
|
+
channel.close();
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
setTimeout(() => {
|
|
1345
|
+
if (waiting) {
|
|
1346
|
+
waiting = false;
|
|
1347
|
+
channel.close();
|
|
1348
|
+
}
|
|
1349
|
+
if (windowInstance && !windowInstance.closed) {
|
|
1350
|
+
windowInstance.close();
|
|
1351
|
+
}
|
|
1352
|
+
}, 15000);
|
|
1353
|
+
await waitUntil(() => waiting);
|
|
1354
|
+
}
|
|
1355
|
+
async function updateAuthTokenNoRefresh(options) {
|
|
1356
|
+
let expires = localStorage.getItem(options.storageTokenExpiresName);
|
|
1357
|
+
if (expires && !Number.isNaN(+expires) && Date.now() > +expires)
|
|
1358
|
+
expires = null;
|
|
1359
|
+
let hasExpiresQuery = false;
|
|
1360
|
+
if (!expires) {
|
|
1361
|
+
const queries = window.location.search.substring(1).split("&");
|
|
1362
|
+
for (const query of queries) {
|
|
1363
|
+
const [key, value] = query.split("=");
|
|
1364
|
+
if (key === options.queryTokenExpiresName && value) {
|
|
1365
|
+
expires = value;
|
|
1366
|
+
hasExpiresQuery = true;
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (expires && !Number.isNaN(+expires) && Date.now() > +expires)
|
|
1371
|
+
expires = null;
|
|
1372
|
+
}
|
|
1373
|
+
if (!expires) {
|
|
1374
|
+
return void window.location.replace(options.authUrl());
|
|
1375
|
+
}
|
|
1376
|
+
localStorage.setItem(options.storageTokenExpiresName, expires);
|
|
1377
|
+
const queries = window.location.search.substring(1).split("&");
|
|
1378
|
+
for (const query of queries) {
|
|
1379
|
+
const [key, value] = query.split("=");
|
|
1380
|
+
if (key === options.queryIsRefreshTokenName && value === "true") {
|
|
1381
|
+
const channel = new BroadcastChannel(options.queryIsRefreshTokenName);
|
|
1382
|
+
channel.postMessage(true);
|
|
1383
|
+
channel.close();
|
|
1384
|
+
window.close();
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
if (hasExpiresQuery) {
|
|
1388
|
+
const url = new URL(window.location.href);
|
|
1389
|
+
url.searchParams.delete(options.queryTokenExpiresName);
|
|
1390
|
+
window.location.replace(url.toString());
|
|
1391
|
+
await wait(300);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1320
1394
|
|
|
1321
1395
|
async function updateAuthUser(options) {
|
|
1322
1396
|
const userInfo = await (options.userRequest ? options.userRequest() : getAuthUser(options));
|
|
@@ -1348,7 +1422,7 @@ async function getAuthUser(options) {
|
|
|
1348
1422
|
}
|
|
1349
1423
|
}
|
|
1350
1424
|
|
|
1351
|
-
let isFetchingAccessToken = false;
|
|
1425
|
+
let isFetchingAccessToken$1 = false;
|
|
1352
1426
|
const generateAuthMiddleWare = (options) => async (request) => {
|
|
1353
1427
|
if (!options.authTokenUrl ||
|
|
1354
1428
|
!options.authUrl ||
|
|
@@ -1368,14 +1442,14 @@ const generateAuthMiddleWare = (options) => async (request) => {
|
|
|
1368
1442
|
};
|
|
1369
1443
|
return;
|
|
1370
1444
|
}
|
|
1371
|
-
if (isFetchingAccessToken)
|
|
1372
|
-
await waitUntil(() => isFetchingAccessToken);
|
|
1445
|
+
if (isFetchingAccessToken$1)
|
|
1446
|
+
await waitUntil(() => isFetchingAccessToken$1);
|
|
1373
1447
|
const expires = localStorage.getItem(options.storageTokenExpiresName);
|
|
1374
1448
|
let token = localStorage.getItem(options.storageTokenName);
|
|
1375
1449
|
if (!expires || Date.now() > +expires || !token) {
|
|
1376
|
-
isFetchingAccessToken = true;
|
|
1450
|
+
isFetchingAccessToken$1 = true;
|
|
1377
1451
|
token = await (options.tokenRequest ? options.tokenRequest() : getAuthToken(options));
|
|
1378
|
-
isFetchingAccessToken = false;
|
|
1452
|
+
isFetchingAccessToken$1 = false;
|
|
1379
1453
|
if (isNull(token)) {
|
|
1380
1454
|
return void window.location.replace(options.authUrl());
|
|
1381
1455
|
}
|
|
@@ -1390,14 +1464,100 @@ const generateAuthMiddleWare = (options) => async (request) => {
|
|
|
1390
1464
|
};
|
|
1391
1465
|
};
|
|
1392
1466
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1467
|
+
let isFetchingAccessToken = false;
|
|
1468
|
+
const generateAuthNoRefreshMiddleWare = (options) => async (request) => {
|
|
1469
|
+
if (!options.authUrl || !options.storageTokenExpiresName || !options.errorUrl) {
|
|
1470
|
+
throw new Error("Auth middleware hasn't required options");
|
|
1471
|
+
}
|
|
1472
|
+
const isSameOrigin = !startWith(request.path, "http");
|
|
1473
|
+
if (request.token) {
|
|
1474
|
+
if (!isSameOrigin)
|
|
1475
|
+
request.headers = {
|
|
1476
|
+
...request.headers,
|
|
1477
|
+
Authorization: `Bearer ${request.token}`,
|
|
1478
|
+
};
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
1481
|
+
if (isFetchingAccessToken)
|
|
1482
|
+
await waitUntil(() => isFetchingAccessToken);
|
|
1483
|
+
const expires = localStorage.getItem(options.storageTokenExpiresName);
|
|
1484
|
+
if (!expires) {
|
|
1485
|
+
isFetchingAccessToken = true;
|
|
1486
|
+
await (options.tokenRequest ? options.tokenRequest() : getAuthTokenNoRefresh(options));
|
|
1487
|
+
isFetchingAccessToken = false;
|
|
1488
|
+
}
|
|
1489
|
+
const token = options.storageTokenName ? localStorage.getItem(options.storageTokenName) : null;
|
|
1490
|
+
if (!isSameOrigin && token)
|
|
1491
|
+
request.headers = {
|
|
1492
|
+
...request.headers,
|
|
1493
|
+
Authorization: `Bearer ${token}`,
|
|
1494
|
+
};
|
|
1399
1495
|
};
|
|
1400
1496
|
|
|
1497
|
+
function generateConsoleMiddleware(options = {}) {
|
|
1498
|
+
return (request) => {
|
|
1499
|
+
return new Promise((resolve) => {
|
|
1500
|
+
if ((options.filter &&
|
|
1501
|
+
!options.filter(request)) ||
|
|
1502
|
+
(options.filterHeaders && !options.filterHeaders(request.headers)) ||
|
|
1503
|
+
(options.filterMethod && !options.filterMethod(request.method)) ||
|
|
1504
|
+
(options.filterParams && !options.filterParams(request.params)) ||
|
|
1505
|
+
(options.filterPath && !options.filterPath(request.path))) {
|
|
1506
|
+
resolve(true);
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
// eslint-disable-next-line no-console
|
|
1510
|
+
console.log(request);
|
|
1511
|
+
resolve(true);
|
|
1512
|
+
});
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
function generateConsolePostMiddleware(options = {}) {
|
|
1517
|
+
return (response) => {
|
|
1518
|
+
return new Promise((resolve) => {
|
|
1519
|
+
void (async function logger() {
|
|
1520
|
+
try {
|
|
1521
|
+
if (!response ||
|
|
1522
|
+
(options.filter && !options.filter(response)) ||
|
|
1523
|
+
(options.filterStatus && !options.filterStatus(response.status)) ||
|
|
1524
|
+
(options.filterUrl && !options.filterUrl(response.url)) ||
|
|
1525
|
+
(options.filterHeaders && !options.filterHeaders(response.headers))) {
|
|
1526
|
+
resolve(true);
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
const contentType = response.headers.get("content-type");
|
|
1530
|
+
let result;
|
|
1531
|
+
if (contentType?.includes?.("text")) {
|
|
1532
|
+
result = await response.text();
|
|
1533
|
+
}
|
|
1534
|
+
else if (contentType?.includes?.("json")) {
|
|
1535
|
+
result = await response.json();
|
|
1536
|
+
}
|
|
1537
|
+
else {
|
|
1538
|
+
result = await response.blob();
|
|
1539
|
+
}
|
|
1540
|
+
console.log({
|
|
1541
|
+
url: response.url,
|
|
1542
|
+
status: response.status,
|
|
1543
|
+
headers: response.headers,
|
|
1544
|
+
body: result,
|
|
1545
|
+
});
|
|
1546
|
+
resolve(true);
|
|
1547
|
+
}
|
|
1548
|
+
catch {
|
|
1549
|
+
if (response) {
|
|
1550
|
+
console.log({ url: response.url, status: response.status, headers: response.headers });
|
|
1551
|
+
}
|
|
1552
|
+
resolve(true);
|
|
1553
|
+
}
|
|
1554
|
+
})().finally(() => {
|
|
1555
|
+
resolve(true);
|
|
1556
|
+
});
|
|
1557
|
+
});
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1401
1561
|
function generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlewares) {
|
|
1402
1562
|
const selectedMiddlewares = customMiddlewares;
|
|
1403
1563
|
for (const key of activeMiddlewares) {
|
|
@@ -1407,8 +1567,13 @@ function generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlew
|
|
|
1407
1567
|
selectedMiddlewares.push(generateAuthMiddleWare(middlewareOptions.auth));
|
|
1408
1568
|
continue;
|
|
1409
1569
|
}
|
|
1570
|
+
case API_MIDDLEWARES.AuthNoRefresh: {
|
|
1571
|
+
if (middlewareOptions.authNoRefresh && (IS_BROWSER || IS_JEST))
|
|
1572
|
+
selectedMiddlewares.push(generateAuthNoRefreshMiddleWare(middlewareOptions.authNoRefresh));
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1410
1575
|
case API_MIDDLEWARES.Logger: {
|
|
1411
|
-
selectedMiddlewares.push(
|
|
1576
|
+
selectedMiddlewares.push(generateConsoleMiddleware(middlewareOptions.logger));
|
|
1412
1577
|
continue;
|
|
1413
1578
|
}
|
|
1414
1579
|
default: {
|
|
@@ -1428,6 +1593,31 @@ function generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlew
|
|
|
1428
1593
|
});
|
|
1429
1594
|
};
|
|
1430
1595
|
}
|
|
1596
|
+
function generatePostMiddlewares(activePostMiddlewares, postMiddlewaresOptions, customPostMiddlewares) {
|
|
1597
|
+
const selectedMiddlewares = customPostMiddlewares;
|
|
1598
|
+
for (const key of activePostMiddlewares) {
|
|
1599
|
+
switch (key) {
|
|
1600
|
+
case POST_API_MIDDLEWARES.Logger: {
|
|
1601
|
+
selectedMiddlewares.push(generateConsolePostMiddleware(postMiddlewaresOptions.logger));
|
|
1602
|
+
continue;
|
|
1603
|
+
}
|
|
1604
|
+
default: {
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
return function executeMiddlewares(response) {
|
|
1610
|
+
return new Promise((resolve) => {
|
|
1611
|
+
void (async () => {
|
|
1612
|
+
for (const middleware of selectedMiddlewares) {
|
|
1613
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1614
|
+
await middleware(response);
|
|
1615
|
+
}
|
|
1616
|
+
resolve(1);
|
|
1617
|
+
})();
|
|
1618
|
+
});
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1431
1621
|
|
|
1432
1622
|
class ResponseError extends Error {
|
|
1433
1623
|
status;
|
|
@@ -1438,8 +1628,14 @@ class ResponseError extends Error {
|
|
|
1438
1628
|
this.description = description;
|
|
1439
1629
|
}
|
|
1440
1630
|
}
|
|
1441
|
-
function createRequestClientInstance(
|
|
1442
|
-
|
|
1631
|
+
function createRequestClientInstance(options = {}) {
|
|
1632
|
+
let executeMiddlewares;
|
|
1633
|
+
let executePostMiddlewares;
|
|
1634
|
+
function setMiddlewares({ activeMiddlewares = [], middlewareOptions = {}, customMiddlewares = [], activePostMiddlewares = [], postMiddlewaresOptions = {}, customPostMiddlewares = [], } = {}) {
|
|
1635
|
+
executeMiddlewares = generateMiddlewares(activeMiddlewares, middlewareOptions, customMiddlewares);
|
|
1636
|
+
executePostMiddlewares = generatePostMiddlewares(activePostMiddlewares, postMiddlewaresOptions, customPostMiddlewares);
|
|
1637
|
+
}
|
|
1638
|
+
setMiddlewares(options);
|
|
1443
1639
|
async function handleRequest(request, responseWithStatus) {
|
|
1444
1640
|
if (request.delay) {
|
|
1445
1641
|
await wait(request.delay);
|
|
@@ -1491,13 +1687,29 @@ function createRequestClientInstance({ activeMiddlewares, middlewareOptions, cus
|
|
|
1491
1687
|
signal: request.signal,
|
|
1492
1688
|
});
|
|
1493
1689
|
}
|
|
1690
|
+
await executePostMiddlewares(response);
|
|
1494
1691
|
if (!response) {
|
|
1495
1692
|
throw new Error("hasn't response");
|
|
1496
1693
|
}
|
|
1497
1694
|
if (!response.ok) {
|
|
1695
|
+
let result;
|
|
1696
|
+
try {
|
|
1697
|
+
const contentType = response.headers.get("content-type");
|
|
1698
|
+
if (contentType?.includes?.("text")) {
|
|
1699
|
+
result = await response.text();
|
|
1700
|
+
}
|
|
1701
|
+
else if (contentType?.includes?.("json")) {
|
|
1702
|
+
result = await response.json();
|
|
1703
|
+
}
|
|
1704
|
+
else {
|
|
1705
|
+
result = await response.blob();
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
catch { }
|
|
1498
1709
|
throw new ResponseError({
|
|
1499
1710
|
status: response.status,
|
|
1500
1711
|
message: `HTTP error! Status: ${response.status}`,
|
|
1712
|
+
description: result,
|
|
1501
1713
|
});
|
|
1502
1714
|
}
|
|
1503
1715
|
if (request.downloadFile) {
|
|
@@ -1559,6 +1771,7 @@ function createRequestClientInstance({ activeMiddlewares, middlewareOptions, cus
|
|
|
1559
1771
|
return {
|
|
1560
1772
|
requestApi,
|
|
1561
1773
|
requestApiWithMeta,
|
|
1774
|
+
setMiddlewares,
|
|
1562
1775
|
};
|
|
1563
1776
|
}
|
|
1564
1777
|
|
|
@@ -1654,6 +1867,7 @@ exports.IS_DENO = IS_DENO;
|
|
|
1654
1867
|
exports.IS_JEST = IS_JEST;
|
|
1655
1868
|
exports.IS_NODE = IS_NODE;
|
|
1656
1869
|
exports.IS_WEB_WORKER = IS_WEB_WORKER;
|
|
1870
|
+
exports.POST_API_MIDDLEWARES = POST_API_MIDDLEWARES;
|
|
1657
1871
|
exports.ResponseError = ResponseError;
|
|
1658
1872
|
exports.arrayToMapByKey = arrayToMapByKey;
|
|
1659
1873
|
exports.buildQueryString = buildQueryString;
|
|
@@ -1666,6 +1880,7 @@ exports.downloadFile = downloadFile;
|
|
|
1666
1880
|
exports.downloadJson = downloadJson;
|
|
1667
1881
|
exports.fieldViewFormat = fieldViewFormat;
|
|
1668
1882
|
exports.getAuthToken = getAuthToken;
|
|
1883
|
+
exports.getAuthTokenNoRefresh = getAuthTokenNoRefresh;
|
|
1669
1884
|
exports.getAuthUser = getAuthUser;
|
|
1670
1885
|
exports.getByPath = getByPath;
|
|
1671
1886
|
exports.getCallerFunctionName = getCallerFunctionName;
|
|
@@ -1708,6 +1923,7 @@ exports.transformToNumber = transformToNumber;
|
|
|
1708
1923
|
exports.translit = translit;
|
|
1709
1924
|
exports.trimUrl = trimUrl;
|
|
1710
1925
|
exports.updateAuthToken = updateAuthToken;
|
|
1926
|
+
exports.updateAuthTokenNoRefresh = updateAuthTokenNoRefresh;
|
|
1711
1927
|
exports.updateAuthUser = updateAuthUser;
|
|
1712
1928
|
exports.wait = wait;
|
|
1713
1929
|
exports.waitUntil = waitUntil;
|