use-frontbacked 5.1.5 → 5.1.7

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.
Files changed (101) hide show
  1. package/dist/cjs/index.js +416 -210
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/DownloadType/index.d.ts +12 -12
  4. package/dist/cjs/types/components/Firebase/AccessTokenDoor.d.ts +12 -12
  5. package/dist/cjs/types/components/Firebase/AuthView.d.ts +15 -15
  6. package/dist/cjs/types/components/Firebase/SignInView.d.ts +11 -11
  7. package/dist/cjs/types/components/Firebase/SignUpView.d.ts +10 -10
  8. package/dist/cjs/types/components/Firebase/data.type.d.ts +23 -23
  9. package/dist/cjs/types/components/Firebase/index.d.ts +14 -14
  10. package/dist/cjs/types/components/FrontbackedProvider/index.d.ts +55 -55
  11. package/dist/cjs/types/components/hooks/useReferralId.d.ts +5 -5
  12. package/dist/cjs/types/components/hooks/useSdkConfig.d.ts +10 -10
  13. package/dist/cjs/types/components/hooks/useTools/index.d.ts +14 -14
  14. package/dist/cjs/types/components/hooks/useTools/types.d.ts +62 -62
  15. package/dist/cjs/types/components/hooks/useTools/utils.d.ts +23 -23
  16. package/dist/cjs/types/components/index.d.ts +2 -2
  17. package/dist/cjs/types/components/types.d.ts +214 -214
  18. package/dist/cjs/types/components/widgets/AppButton.d.ts +17 -17
  19. package/dist/cjs/types/components/widgets/CopyView.d.ts +24 -24
  20. package/dist/cjs/types/components/widgets/DrawerPop/index.d.ts +25 -25
  21. package/dist/cjs/types/components/widgets/InfoLabel.d.ts +11 -11
  22. package/dist/cjs/types/components/widgets/InputBox/index.d.ts +94 -94
  23. package/dist/cjs/types/components/widgets/InputBox/utils.d.ts +1 -1
  24. package/dist/cjs/types/components/widgets/Link.d.ts +9 -9
  25. package/dist/cjs/types/components/widgets/Loading.d.ts +27 -27
  26. package/dist/cjs/types/components/widgets/ModalPop/index.d.ts +26 -26
  27. package/dist/cjs/types/components/widgets/PleaseWaitForX.d.ts +3 -3
  28. package/dist/cjs/types/index.d.ts +1 -1
  29. package/dist/cjs/types/theme.d.ts +3 -3
  30. package/dist/cjs/types/theme.type.d.ts +19 -19
  31. package/dist/cjs/types/utils/CustomError.d.ts +5 -5
  32. package/dist/cjs/types/utils/base64Images.d.ts +4 -4
  33. package/dist/cjs/types/utils/c.d.ts +33 -33
  34. package/dist/cjs/types/utils/f.d.ts +23 -23
  35. package/dist/components/DownloadType/index.d.ts +12 -12
  36. package/dist/components/Firebase/AccessTokenDoor.d.ts +12 -12
  37. package/dist/components/Firebase/AuthView.d.ts +15 -15
  38. package/dist/components/Firebase/SignInView.d.ts +11 -11
  39. package/dist/components/Firebase/SignUpView.d.ts +10 -10
  40. package/dist/components/Firebase/data.type.d.ts +23 -23
  41. package/dist/components/Firebase/index.d.ts +14 -14
  42. package/dist/components/FrontbackedProvider/index.d.ts +55 -55
  43. package/dist/components/hooks/useReferralId.d.ts +5 -5
  44. package/dist/components/hooks/useSdkConfig.d.ts +10 -10
  45. package/dist/components/hooks/useTools/index.d.ts +14 -14
  46. package/dist/components/hooks/useTools/types.d.ts +62 -62
  47. package/dist/components/hooks/useTools/utils.d.ts +23 -23
  48. package/dist/components/index.d.ts +2 -2
  49. package/dist/components/types.d.ts +214 -214
  50. package/dist/components/widgets/AppButton.d.ts +17 -17
  51. package/dist/components/widgets/CopyView.d.ts +24 -24
  52. package/dist/components/widgets/DrawerPop/index.d.ts +25 -25
  53. package/dist/components/widgets/InfoLabel.d.ts +11 -11
  54. package/dist/components/widgets/InputBox/index.d.ts +94 -94
  55. package/dist/components/widgets/InputBox/utils.d.ts +1 -1
  56. package/dist/components/widgets/Link.d.ts +9 -9
  57. package/dist/components/widgets/Loading.d.ts +27 -27
  58. package/dist/components/widgets/ModalPop/index.d.ts +26 -26
  59. package/dist/components/widgets/PleaseWaitForX.d.ts +3 -3
  60. package/dist/esm/index.es.js +416 -210
  61. package/dist/esm/index.es.js.map +1 -1
  62. package/dist/esm/types/components/DownloadType/index.d.ts +12 -12
  63. package/dist/esm/types/components/Firebase/AccessTokenDoor.d.ts +12 -12
  64. package/dist/esm/types/components/Firebase/AuthView.d.ts +15 -15
  65. package/dist/esm/types/components/Firebase/SignInView.d.ts +11 -11
  66. package/dist/esm/types/components/Firebase/SignUpView.d.ts +10 -10
  67. package/dist/esm/types/components/Firebase/data.type.d.ts +23 -23
  68. package/dist/esm/types/components/Firebase/index.d.ts +14 -14
  69. package/dist/esm/types/components/FrontbackedProvider/index.d.ts +55 -55
  70. package/dist/esm/types/components/hooks/useReferralId.d.ts +5 -5
  71. package/dist/esm/types/components/hooks/useSdkConfig.d.ts +10 -10
  72. package/dist/esm/types/components/hooks/useTools/index.d.ts +14 -14
  73. package/dist/esm/types/components/hooks/useTools/types.d.ts +62 -62
  74. package/dist/esm/types/components/hooks/useTools/utils.d.ts +23 -23
  75. package/dist/esm/types/components/index.d.ts +2 -2
  76. package/dist/esm/types/components/types.d.ts +214 -214
  77. package/dist/esm/types/components/widgets/AppButton.d.ts +17 -17
  78. package/dist/esm/types/components/widgets/CopyView.d.ts +24 -24
  79. package/dist/esm/types/components/widgets/DrawerPop/index.d.ts +25 -25
  80. package/dist/esm/types/components/widgets/InfoLabel.d.ts +11 -11
  81. package/dist/esm/types/components/widgets/InputBox/index.d.ts +94 -94
  82. package/dist/esm/types/components/widgets/InputBox/utils.d.ts +1 -1
  83. package/dist/esm/types/components/widgets/Link.d.ts +9 -9
  84. package/dist/esm/types/components/widgets/Loading.d.ts +27 -27
  85. package/dist/esm/types/components/widgets/ModalPop/index.d.ts +26 -26
  86. package/dist/esm/types/components/widgets/PleaseWaitForX.d.ts +3 -3
  87. package/dist/esm/types/index.d.ts +1 -1
  88. package/dist/esm/types/theme.d.ts +3 -3
  89. package/dist/esm/types/theme.type.d.ts +19 -19
  90. package/dist/esm/types/utils/CustomError.d.ts +5 -5
  91. package/dist/esm/types/utils/base64Images.d.ts +4 -4
  92. package/dist/esm/types/utils/c.d.ts +33 -33
  93. package/dist/esm/types/utils/f.d.ts +23 -23
  94. package/dist/index.d.ts +1 -1
  95. package/dist/theme.d.ts +3 -3
  96. package/dist/theme.type.d.ts +19 -19
  97. package/dist/utils/CustomError.d.ts +5 -5
  98. package/dist/utils/base64Images.d.ts +4 -4
  99. package/dist/utils/c.d.ts +33 -33
  100. package/dist/utils/f.d.ts +23 -23
  101. package/package.json +84 -83
package/dist/cjs/index.js CHANGED
@@ -265,6 +265,152 @@ var consoleLog = function consoleLog() {
265
265
  console.log.apply(console, args);
266
266
  }
267
267
  };
268
+ var isAppleMobileDevice = function isAppleMobileDevice() {
269
+ if (typeof navigator === "undefined") return false;
270
+ var userAgent = navigator.userAgent || "";
271
+ var platform = navigator.platform || "";
272
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
273
+ return /iPad|iPhone|iPod/i.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1;
274
+ };
275
+ var openBlobInBrowser = function openBlobInBrowser(blob, fileName, openInNewTab) {
276
+ if (openInNewTab === void 0) {
277
+ openInNewTab = false;
278
+ }
279
+ var objectUrl = URL.createObjectURL(blob);
280
+ var downloadLink = document.createElement("a");
281
+ downloadLink.href = objectUrl;
282
+ downloadLink.rel = "noopener";
283
+ downloadLink.style.display = "none";
284
+ if (openInNewTab) {
285
+ downloadLink.target = "_blank";
286
+ } else {
287
+ downloadLink.download = fileName;
288
+ }
289
+ document.body.appendChild(downloadLink);
290
+ downloadLink.click();
291
+ document.body.removeChild(downloadLink);
292
+ setTimeout(function () {
293
+ return URL.revokeObjectURL(objectUrl);
294
+ }, 30000);
295
+ };
296
+ var shareBlob = function shareBlob(blob, fileName) {
297
+ return __awaiter(void 0, void 0, void 0, function () {
298
+ var shareApi, canShare, file, shareData;
299
+ return __generator(this, function (_a) {
300
+ switch (_a.label) {
301
+ case 0:
302
+ shareApi = typeof navigator !== "undefined" ? navigator.share : null;
303
+ canShare = typeof navigator !== "undefined" ? navigator.canShare : null;
304
+ if (!shareApi || typeof File === "undefined") return [2 /*return*/, false];
305
+ file = new File([blob], fileName, {
306
+ type: blob.type || "application/octet-stream"
307
+ });
308
+ shareData = {
309
+ files: [file],
310
+ title: fileName
311
+ };
312
+ if (canShare && !canShare.call(navigator, shareData)) return [2 /*return*/, false];
313
+ return [4 /*yield*/, shareApi.call(navigator, shareData)];
314
+ case 1:
315
+ _a.sent();
316
+ return [2 /*return*/, true];
317
+ }
318
+ });
319
+ });
320
+ };
321
+ var promptAppleMobileSave = function promptAppleMobileSave(blob, fileName) {
322
+ return new Promise(function (resolve, reject) {
323
+ var overlay = document.createElement("div");
324
+ overlay.setAttribute("role", "dialog");
325
+ overlay.setAttribute("aria-modal", "true");
326
+ overlay.style.cssText = ["position:fixed", "inset:0", "z-index:2147483647", "display:flex", "align-items:center", "justify-content:center", "padding:24px", "background:rgba(15,23,42,0.58)", "font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif"].join(";");
327
+ var dialog = document.createElement("div");
328
+ dialog.style.cssText = ["width:min(360px,100%)", "border-radius:12px", "background:#fff", "box-shadow:0 20px 60px rgba(15,23,42,0.3)", "padding:18px", "color:#111827", "text-align:left"].join(";");
329
+ var title = document.createElement("div");
330
+ title.textContent = "File ready";
331
+ title.style.cssText = "font-size:17px;font-weight:700;margin-bottom:8px;";
332
+ var body = document.createElement("div");
333
+ body.textContent = "Choose where to save this file.";
334
+ body.style.cssText = "font-size:14px;line-height:1.45;color:#4b5563;margin-bottom:16px;";
335
+ var actions = document.createElement("div");
336
+ actions.style.cssText = "display:flex;gap:10px;justify-content:flex-end;";
337
+ var cancelButton = document.createElement("button");
338
+ cancelButton.type = "button";
339
+ cancelButton.textContent = "Cancel";
340
+ cancelButton.style.cssText = ["border:0", "border-radius:8px", "padding:10px 14px", "background:#f3f4f6", "color:#111827", "font-size:14px", "font-weight:600"].join(";");
341
+ var saveButton = document.createElement("button");
342
+ saveButton.type = "button";
343
+ saveButton.textContent = "Save File";
344
+ saveButton.style.cssText = ["border:0", "border-radius:8px", "padding:10px 14px", "background:#2563eb", "color:#fff", "font-size:14px", "font-weight:700"].join(";");
345
+ var cleanup = function cleanup() {
346
+ document.body.removeChild(overlay);
347
+ };
348
+ cancelButton.onclick = function () {
349
+ cleanup();
350
+ reject(new Error("File save was cancelled."));
351
+ };
352
+ saveButton.onclick = function () {
353
+ return __awaiter(void 0, void 0, void 0, function () {
354
+ var shared, error_1;
355
+ return __generator(this, function (_a) {
356
+ switch (_a.label) {
357
+ case 0:
358
+ saveButton.setAttribute("disabled", "true");
359
+ _a.label = 1;
360
+ case 1:
361
+ _a.trys.push([1, 3,, 4]);
362
+ return [4 /*yield*/, shareBlob(blob, fileName)];
363
+ case 2:
364
+ shared = _a.sent();
365
+ if (!shared) openBlobInBrowser(blob, fileName, true);
366
+ cleanup();
367
+ resolve();
368
+ return [3 /*break*/, 4];
369
+ case 3:
370
+ error_1 = _a.sent();
371
+ cleanup();
372
+ if ((error_1 === null || error_1 === void 0 ? void 0 : error_1.name) === "AbortError") {
373
+ reject(new Error("File save was cancelled."));
374
+ return [2 /*return*/];
375
+ }
376
+
377
+ openBlobInBrowser(blob, fileName, true);
378
+ resolve();
379
+ return [3 /*break*/, 4];
380
+ case 4:
381
+ return [2 /*return*/];
382
+ }
383
+ });
384
+ });
385
+ };
386
+
387
+ actions.appendChild(cancelButton);
388
+ actions.appendChild(saveButton);
389
+ dialog.appendChild(title);
390
+ dialog.appendChild(body);
391
+ dialog.appendChild(actions);
392
+ overlay.appendChild(dialog);
393
+ document.body.appendChild(overlay);
394
+ });
395
+ };
396
+ var downloadBlob = function downloadBlob(blob, fileName) {
397
+ return __awaiter(void 0, void 0, void 0, function () {
398
+ return __generator(this, function (_a) {
399
+ switch (_a.label) {
400
+ case 0:
401
+ if (!isAppleMobileDevice()) return [3 /*break*/, 2];
402
+ return [4 /*yield*/, promptAppleMobileSave(blob, fileName)];
403
+ case 1:
404
+ _a.sent();
405
+ return [2 /*return*/];
406
+ case 2:
407
+ openBlobInBrowser(blob, fileName);
408
+ return [2 /*return*/];
409
+ }
410
+ });
411
+ });
412
+ };
413
+
268
414
  var downloadSvgAsImage = function downloadSvgAsImage(svgString, format, fileName) {
269
415
  if (format === void 0) {
270
416
  format = 'png';
@@ -278,39 +424,48 @@ var downloadSvgAsImage = function downloadSvgAsImage(svgString, format, fileName
278
424
  });
279
425
  var svgUrl = URL.createObjectURL(svgBlob);
280
426
  var img = new Image();
427
+ img.crossOrigin = "anonymous";
281
428
  img.onload = function () {
282
- var canvas = document.createElement('canvas');
283
- canvas.width = img.width;
284
- canvas.height = img.height;
285
- var context = canvas.getContext('2d');
286
- if (context) {
287
- context.drawImage(img, 0, 0);
288
- var dataUrl = canvas.toDataURL("image/".concat(format));
289
- var imageBlob = dataURLToBlob(dataUrl);
290
- if (isiPhone()) {
291
- // Workaround for iPhone browsers
292
- var binaryData = [imageBlob];
293
- var iphoneBlob = new Blob(binaryData, {
294
- type: "image/".concat(format)
295
- });
296
- var iphoneUrl = URL.createObjectURL(iphoneBlob);
297
- var downloadLink = document.createElement('a');
298
- downloadLink.href = iphoneUrl;
299
- downloadLink.download = "".concat(fileName, ".").concat(format);
300
- downloadLink.click();
301
- URL.revokeObjectURL(iphoneUrl);
302
- resolve(iphoneUrl);
303
- } else {
304
- // For other browsers
305
- var downloadLink = document.createElement('a');
306
- downloadLink.href = dataUrl;
307
- downloadLink.download = "".concat(fileName, ".").concat(format);
308
- downloadLink.click();
309
- resolve(dataUrl);
310
- }
311
- } else {
312
- reject(new Error("Unsupported Browser. Please try to download from another browser."));
313
- }
429
+ return __awaiter(this, void 0, void 0, function () {
430
+ var canvas, context, dataUrl, imageBlob, error_2;
431
+ return __generator(this, function (_a) {
432
+ switch (_a.label) {
433
+ case 0:
434
+ _a.trys.push([0, 4,, 5]);
435
+ canvas = document.createElement('canvas');
436
+ canvas.width = img.width;
437
+ canvas.height = img.height;
438
+ context = canvas.getContext('2d');
439
+ if (!context) return [3 /*break*/, 2];
440
+ context.drawImage(img, 0, 0);
441
+ dataUrl = canvas.toDataURL("image/".concat(format));
442
+ imageBlob = dataURLToBlob(dataUrl);
443
+ URL.revokeObjectURL(svgUrl);
444
+ return [4 /*yield*/, downloadBlob(imageBlob, "".concat(fileName, ".").concat(format))];
445
+ case 1:
446
+ _a.sent();
447
+ resolve(dataUrl);
448
+ return [3 /*break*/, 3];
449
+ case 2:
450
+ reject(new Error("Unsupported Browser. Please try to download from another browser."));
451
+ _a.label = 3;
452
+ case 3:
453
+ return [3 /*break*/, 5];
454
+ case 4:
455
+ error_2 = _a.sent();
456
+ URL.revokeObjectURL(svgUrl);
457
+ reject(error_2);
458
+ return [3 /*break*/, 5];
459
+ case 5:
460
+ return [2 /*return*/];
461
+ }
462
+ });
463
+ });
464
+ };
465
+
466
+ img.onerror = function () {
467
+ URL.revokeObjectURL(svgUrl);
468
+ reject(new Error("Failed to render the SVG for download."));
314
469
  };
315
470
  img.src = svgUrl;
316
471
  });
@@ -328,9 +483,6 @@ function dataURLToBlob(dataURL) {
328
483
  type: mime
329
484
  });
330
485
  }
331
- function isiPhone() {
332
- return /iPhone/i.test(navigator.userAgent);
333
- }
334
486
  var getColor = function getColor(isDarkMode, colorName) {
335
487
  var color = theme[colorName];
336
488
  if (color) {
@@ -1355,69 +1507,69 @@ var InputBox = function InputBox(_a) {
1355
1507
  return null;
1356
1508
  }
1357
1509
  }))) :
1358
- /*
1359
- type == TYPES.location?
1360
- <LocationPicker disabled={disabled} ref={inputRef} w="100%" h="100%"
1361
- apiKey={apiKey || ""} defaultLatlng={defaultLatlng} geotype={geotype}
1362
- mapToSearchRatio={mapToSearchRatio}
1363
- twoDigitCountryCode={twoDigitCountryCode}
1364
- searchPlaceholder={placeholder as string}
1365
- value={value? {
1366
- name: value.name,
1367
- formatted_address: value.address,
1368
- geometry: {
1369
- location: {lat: () => value.position.lat, lng: () => value.position.lng},
1370
- viewport: {}
1371
- }
1372
- } : null}
1373
- onChange={(l) => {
1374
- const v = {
1375
- name: l.name,
1376
- address: l.formatted_address,
1377
- position: {
1378
- lat: l.geometry.location.lat(),
1379
- lng: l.geometry.location.lng()
1380
- }
1381
- }
1382
- if(!disabled && onChange) {
1383
- onChange(v)
1384
- }
1385
- if(!disabled && onCheckInfo) {
1386
- const { checker, waitTime } = onCheckInfo(v)
1387
- //only check input in "onChange" if waitTime is greater than zero.
1388
- // This is good in searching a text results as a user types in a search bar,
1389
- // or saving an article on a server as the user types
1390
- if(waitTime > 0) {
1391
- handleInputCheck(() => v, (checkedValue) => {
1392
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1393
- }, checker, waitTime)
1394
- }
1395
- }
1396
-
1397
- }}
1398
- onBlur={(l) => {
1399
- if(!disabled && onCheckInfo) {
1400
- const v = {
1401
- name: l.name,
1402
- address: l.formatted_address,
1403
- position: {
1404
- lat: l.geometry.location.lat(),
1405
- lng: l.geometry.location.lng()
1406
- }
1407
- }
1408
- const { checker, waitTime } = onCheckInfo(v)
1409
- //only check input in "onBlur" if waitTime is not set or equal to zero.
1410
- // This is good in validating an input as it looses focus when the user moves to another,
1411
- // input field
1412
- if(!waitTime) {
1413
- handleInputCheck(() => v, (checkedValue) => {
1414
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1415
- }, checker, waitTime)
1416
- }
1417
- }
1418
- }}
1419
- errorMessage={errorMessage}
1420
- />
1510
+ /*
1511
+ type == TYPES.location?
1512
+ <LocationPicker disabled={disabled} ref={inputRef} w="100%" h="100%"
1513
+ apiKey={apiKey || ""} defaultLatlng={defaultLatlng} geotype={geotype}
1514
+ mapToSearchRatio={mapToSearchRatio}
1515
+ twoDigitCountryCode={twoDigitCountryCode}
1516
+ searchPlaceholder={placeholder as string}
1517
+ value={value? {
1518
+ name: value.name,
1519
+ formatted_address: value.address,
1520
+ geometry: {
1521
+ location: {lat: () => value.position.lat, lng: () => value.position.lng},
1522
+ viewport: {}
1523
+ }
1524
+ } : null}
1525
+ onChange={(l) => {
1526
+ const v = {
1527
+ name: l.name,
1528
+ address: l.formatted_address,
1529
+ position: {
1530
+ lat: l.geometry.location.lat(),
1531
+ lng: l.geometry.location.lng()
1532
+ }
1533
+ }
1534
+ if(!disabled && onChange) {
1535
+ onChange(v)
1536
+ }
1537
+ if(!disabled && onCheckInfo) {
1538
+ const { checker, waitTime } = onCheckInfo(v)
1539
+ //only check input in "onChange" if waitTime is greater than zero.
1540
+ // This is good in searching a text results as a user types in a search bar,
1541
+ // or saving an article on a server as the user types
1542
+ if(waitTime > 0) {
1543
+ handleInputCheck(() => v, (checkedValue) => {
1544
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1545
+ }, checker, waitTime)
1546
+ }
1547
+ }
1548
+
1549
+ }}
1550
+ onBlur={(l) => {
1551
+ if(!disabled && onCheckInfo) {
1552
+ const v = {
1553
+ name: l.name,
1554
+ address: l.formatted_address,
1555
+ position: {
1556
+ lat: l.geometry.location.lat(),
1557
+ lng: l.geometry.location.lng()
1558
+ }
1559
+ }
1560
+ const { checker, waitTime } = onCheckInfo(v)
1561
+ //only check input in "onBlur" if waitTime is not set or equal to zero.
1562
+ // This is good in validating an input as it looses focus when the user moves to another,
1563
+ // input field
1564
+ if(!waitTime) {
1565
+ handleInputCheck(() => v, (checkedValue) => {
1566
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1567
+ }, checker, waitTime)
1568
+ }
1569
+ }
1570
+ }}
1571
+ errorMessage={errorMessage}
1572
+ />
1421
1573
  :*/
1422
1574
  type == TYPES.price ? /*#__PURE__*/React__default["default"].createElement(react.VStack, {
1423
1575
  w: "100%",
@@ -1526,26 +1678,26 @@ var InputBox = function InputBox(_a) {
1526
1678
  }
1527
1679
  }, /*#__PURE__*/React__default["default"].createElement(fa.FaPlus, null)))
1528
1680
  }))) :
1529
- /*
1530
- type == TYPES.select_tree?
1531
- <SelectTree disabled={disabled} options={options as SelectTreeOptionWithChildren[]}
1532
- onChange={onChange}
1533
- onBlur={(e: SelectTreeEvent) => {
1534
- const { currentNode, selectedNodes } = e
1535
- if(!disabled && onCheckInfo) {
1536
- const v = "currentNode"
1537
- const { checker, waitTime } = onCheckInfo(v)
1538
- //only check input in "onBlur" if waitTime is not set or equal to zero.
1539
- // This is good in validating an input as it looses focus when the user moves to another,
1540
- // input field
1541
- if(!waitTime) {
1542
- handleInputCheck(() => v, (checkedValue) => {
1543
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1544
- }, checker, waitTime)
1545
- }
1546
- }
1547
- }}
1548
- />
1681
+ /*
1682
+ type == TYPES.select_tree?
1683
+ <SelectTree disabled={disabled} options={options as SelectTreeOptionWithChildren[]}
1684
+ onChange={onChange}
1685
+ onBlur={(e: SelectTreeEvent) => {
1686
+ const { currentNode, selectedNodes } = e
1687
+ if(!disabled && onCheckInfo) {
1688
+ const v = "currentNode"
1689
+ const { checker, waitTime } = onCheckInfo(v)
1690
+ //only check input in "onBlur" if waitTime is not set or equal to zero.
1691
+ // This is good in validating an input as it looses focus when the user moves to another,
1692
+ // input field
1693
+ if(!waitTime) {
1694
+ handleInputCheck(() => v, (checkedValue) => {
1695
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1696
+ }, checker, waitTime)
1697
+ }
1698
+ }
1699
+ }}
1700
+ />
1549
1701
  :*/
1550
1702
  type == TYPES.none ? null : /*#__PURE__*/React__default["default"].createElement(react.InputGroup, null, iconLeft ? /*#__PURE__*/React__default["default"].createElement(react.InputLeftElement, {
1551
1703
  children: iconLeft
@@ -2421,17 +2573,52 @@ var AccessTokenDoor = function AccessTokenDoor(_a) {
2421
2573
  }, authenticating ? "Please wait..." : "Confirm Operation")));
2422
2574
  };
2423
2575
 
2576
+ function _typeof(o) {
2577
+ "@babel/helpers - typeof";
2578
+
2579
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
2580
+ return typeof o;
2581
+ } : function (o) {
2582
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
2583
+ }, _typeof(o);
2584
+ }
2585
+
2424
2586
  var MAX_RETRIES$1 = 5;
2425
2587
  var CACHE_KEY$1 = "sdk_config-metadata";
2588
+ var CACHE_BUST_KEY$1 = "_fb_cache_bust";
2426
2589
  // let sdkConfigCache: SdkConfig | null = null;
2427
2590
  // let fetchPromise: Promise<SdkConfig | null> | null = null;
2428
- var defaultFactoryData$1 = '{"etag":"W/\\"cfb2c25c60051f77c56bc81c008b2d80\\"","lastModified":"Thu, 15 May 2025 01:41:21 GMT","cachedData":{"aff_pct":10,"app_version_code":19,"contact_link":"https://t.me/frontbacked","group_link":"https://t.me/frontbacked","group_links":["https://t.me/frontbacked"],"min_deposit":7,"min_vendor_deposit":7,"parent_site_home":"https://hackbaker.com","ttl_days":2,"vendors":[{"name":"JinmiEx","number":"+2348130729216","freq":1}]}}';
2591
+ var addCacheBust$1 = function addCacheBust(url) {
2592
+ try {
2593
+ var parsedUrl = new URL(url);
2594
+ parsedUrl.searchParams.set(CACHE_BUST_KEY$1, Date.now().toString());
2595
+ return parsedUrl.toString();
2596
+ } catch (err) {
2597
+ return url;
2598
+ }
2599
+ };
2600
+ var readCachedMetadata$1 = function readCachedMetadata() {
2601
+ if (!isBrowser()) return null;
2602
+ try {
2603
+ var cachedMetadata = localStorage.getItem(CACHE_KEY$1);
2604
+ return cachedMetadata ? JSON.parse(cachedMetadata) : null;
2605
+ } catch (err) {
2606
+ localStorage.removeItem(CACHE_KEY$1);
2607
+ return null;
2608
+ }
2609
+ };
2429
2610
  var useSdkConfig = function useSdkConfig(appConfig) {
2430
2611
  var _a = React.useState(isBrowser() ? window.sdkConfigCache : null),
2431
2612
  sdkConfig = _a[0],
2432
2613
  setSdkConfig = _a[1];
2433
2614
  function parseVendors(vendorsAsTexts) {
2434
- return vendorsAsTexts.map(function (text) {
2615
+ if (vendorsAsTexts === void 0) {
2616
+ vendorsAsTexts = [];
2617
+ }
2618
+ if (!Array.isArray(vendorsAsTexts)) return [];
2619
+ return vendorsAsTexts.map(function (vendor) {
2620
+ if (typeof vendor !== "string") return vendor;
2621
+ var text = vendor;
2435
2622
  var _a = text.split(','),
2436
2623
  name = _a[0],
2437
2624
  number = _a[1],
@@ -2447,49 +2634,38 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2447
2634
  if (!(appConfig === null || appConfig === void 0 ? void 0 : appConfig.r2Domain)) return;
2448
2635
  if (window.sdkConfigCache) {
2449
2636
  setSdkConfig(window.sdkConfigCache);
2450
- return;
2451
2637
  }
2452
2638
  if (!window.fetchPromise) {
2453
2639
  window.fetchPromise = function () {
2454
2640
  return __awaiter(void 0, void 0, void 0, function () {
2455
- var attempts, headers, cachedMetadata, _a, etag, lastModified, cachedData, response, config, err_1;
2456
- var _b;
2457
- return __generator(this, function (_c) {
2458
- switch (_c.label) {
2641
+ var attempts, cachedMetadata, cachedData, response, config, err_1;
2642
+ var _a;
2643
+ return __generator(this, function (_b) {
2644
+ switch (_b.label) {
2459
2645
  case 0:
2460
2646
  attempts = 0;
2461
- headers = {};
2462
- cachedMetadata = localStorage.getItem(CACHE_KEY$1) || defaultFactoryData$1;
2647
+ cachedMetadata = readCachedMetadata$1();
2463
2648
  if (cachedMetadata) {
2464
- _a = JSON.parse(cachedMetadata), etag = _a.etag, lastModified = _a.lastModified, cachedData = _a.cachedData;
2649
+ cachedData = cachedMetadata.cachedData;
2465
2650
  if (cachedData) {
2466
2651
  window.sdkConfigCache = cachedData;
2467
2652
  setSdkConfig(cachedData);
2468
2653
  //return cachedData;
2469
2654
  }
2470
-
2471
- if (etag) headers["If-None-Match"] = etag;
2472
- if (lastModified) headers["If-Modified-Since"] = lastModified;
2473
2655
  }
2474
- consoleLog("useSdkConfig.headers: ", headers);
2475
- _c.label = 1;
2656
+
2657
+ consoleLog("useSdkConfig.refreshing");
2658
+ _b.label = 1;
2476
2659
  case 1:
2477
2660
  if (!(attempts < MAX_RETRIES$1)) return [3 /*break*/, 6];
2478
- _c.label = 2;
2661
+ _b.label = 2;
2479
2662
  case 2:
2480
- _c.trys.push([2, 4,, 5]);
2481
- return [4 /*yield*/, axios__default["default"].get("https://".concat(appConfig.r2Domain, "/sdk_config.json"), {
2482
- headers: headers,
2483
- validateStatus: function validateStatus(status) {
2484
- return status < 500;
2485
- } // Accept 304 Not Modified
2486
- })];
2487
-
2663
+ _b.trys.push([2, 4,, 5]);
2664
+ return [4 /*yield*/, axios__default["default"].get(addCacheBust$1("https://".concat(appConfig.r2Domain, "/sdk_config.json")))];
2488
2665
  case 3:
2489
- response = _c.sent();
2490
- if (response.status === 304) {
2491
- consoleLog("useSdkConfig.notModied: ", response.status);
2492
- return [2 /*return*/, window.sdkConfigCache];
2666
+ response = _b.sent();
2667
+ if (_typeof(response.data) !== "object") {
2668
+ throw new Error("Invalid SDK config response");
2493
2669
  }
2494
2670
  config = response.data;
2495
2671
  config.vendors = parseVendors(response.data.vendors);
@@ -2499,13 +2675,14 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2499
2675
  localStorage.setItem(CACHE_KEY$1, JSON.stringify({
2500
2676
  etag: response.headers["etag"],
2501
2677
  lastModified: response.headers["last-modified"],
2678
+ cachedAt: Date.now(),
2502
2679
  cachedData: config
2503
2680
  }));
2504
2681
  consoleLog("useSdkConfig.refreshed: ", response.data, " at ".concat(response.headers["last-modified"], ", with etag, ").concat(response.headers["etag"]));
2505
2682
  return [2 /*return*/, config];
2506
2683
  case 4:
2507
- err_1 = _c.sent();
2508
- if (((_b = err_1.response) === null || _b === void 0 ? void 0 : _b.status) === 404) {
2684
+ err_1 = _b.sent();
2685
+ if (((_a = err_1.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
2509
2686
  consoleLog("Error fetching SDK config: Resource not found (404): ", err_1);
2510
2687
  return [3 /*break*/, 6];
2511
2688
  }
@@ -2517,11 +2694,14 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2517
2694
  case 5:
2518
2695
  return [3 /*break*/, 1];
2519
2696
  case 6:
2697
+ if (window.sdkConfigCache) return [2 /*return*/, window.sdkConfigCache];
2520
2698
  return [2 /*return*/, null];
2521
2699
  }
2522
2700
  });
2523
2701
  });
2524
- }();
2702
+ }()["finally"](function () {
2703
+ window.fetchPromise = null;
2704
+ });
2525
2705
  }
2526
2706
  window.fetchPromise.then(function (config) {
2527
2707
  if (config) setSdkConfig(config);
@@ -2763,17 +2943,20 @@ var DownloadType = function DownloadType(_a) {
2763
2943
  }
2764
2944
  }, [adminInfo]);
2765
2945
  React.useEffect(function () {
2946
+ var _a, _b, _c, _d;
2766
2947
  if (onGetTool && toolId) {
2767
2948
  var tool = onGetTool(toolId);
2768
2949
  consoleLog("DownloadType.setDocRules", tool);
2769
- setDocRules(!tool ? null : __assign(__assign({}, docRules || {}), {
2770
- allow_freemium: (tool === null || tool === void 0 ? void 0 : tool.allow_freemium) || true,
2771
- create_price: (tool === null || tool === void 0 ? void 0 : tool.create_price) || 0,
2772
- update_price: (tool === null || tool === void 0 ? void 0 : tool.update_price) || 0,
2773
- create_price_is_monthly: (tool === null || tool === void 0 ? void 0 : tool.create_price_is_monthly) || false,
2950
+ setDocRules(!tool ? null : {
2951
+ allow_freemium: (_a = tool === null || tool === void 0 ? void 0 : tool.allow_freemium) !== null && _a !== void 0 ? _a : true,
2952
+ create_price: (_b = tool === null || tool === void 0 ? void 0 : tool.create_price) !== null && _b !== void 0 ? _b : 0,
2953
+ update_price: (_c = tool === null || tool === void 0 ? void 0 : tool.update_price) !== null && _c !== void 0 ? _c : 0,
2954
+ create_price_is_monthly: (_d = tool === null || tool === void 0 ? void 0 : tool.create_price_is_monthly) !== null && _d !== void 0 ? _d : false,
2774
2955
  yearly_price: tool === null || tool === void 0 ? void 0 : tool.yearly_price,
2775
2956
  quarterly_price: tool === null || tool === void 0 ? void 0 : tool.quarterly_price
2776
- }));
2957
+ });
2958
+ } else {
2959
+ setDocRules(null);
2777
2960
  }
2778
2961
  }, [onGetTool, toolId]);
2779
2962
  var download = function download() {
@@ -2912,7 +3095,7 @@ var DownloadType = function DownloadType(_a) {
2912
3095
  setAutoProcessOn(false);
2913
3096
  }
2914
3097
  }
2915
- }, [docRules]);
3098
+ }, [docRules, permission.isToolsEditor, toolId, updateMessage, removeFreemiumBeforeUpdate, renewSubscription, isFreemium]);
2916
3099
  if (permission.isToolsEditor && toolId == "other_tools" || !toolId || !onGetTool || !freeTitle || !freeMessage || !paidTitle || !paidMessage) return null;
2917
3100
  return /*#__PURE__*/React__default["default"].createElement(DrawerPop, {
2918
3101
  placement: "bottom",
@@ -2942,12 +3125,12 @@ var DownloadType = function DownloadType(_a) {
2942
3125
  //Or it's not an update(it's a create) but create price is 0
2943
3126
  //Or it's an update but update price is 0
2944
3127
  //Or it's an update for subscription renewal
2945
- /*!docRules ||*/ /*
2946
- (updateMessage && removeFreemiumBeforeUpdate && docRules.create_price > 0) ||
2947
- (!updateMessage && !docRules.allow_freemium) ||
2948
- (!updateMessage && docRules.create_price == 0) ||
2949
- (updateMessage && docRules.update_price == 0) ||
2950
- (updateMessage && renewSubscription) ||
3128
+ /*!docRules ||*/ /*
3129
+ (updateMessage && removeFreemiumBeforeUpdate && docRules.create_price > 0) ||
3130
+ (!updateMessage && !docRules.allow_freemium) ||
3131
+ (!updateMessage && docRules.create_price == 0) ||
3132
+ (updateMessage && docRules.update_price == 0) ||
3133
+ (updateMessage && renewSubscription) ||
2951
3134
  (updateMessage && renewSubscription)*/
2952
3135
  //(!updateMessage && docRules.create_price == 0) || (updateMessage && !docRules.yearly_price && !docRules.quarterly_price)?
2953
3136
  autoProcessOn || !docRules ? /*#__PURE__*/React__default["default"].createElement(PleaseWaitForX, null) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, updateMessage && !docRules.yearly_price && !docRules.quarterly_price ? /*#__PURE__*/React__default["default"].createElement(react.Text, {
@@ -2997,11 +3180,11 @@ var DownloadType = function DownloadType(_a) {
2997
3180
  }))));
2998
3181
  };
2999
3182
 
3000
- /**
3001
- * Removes a specific query string parameter from a URL.
3002
- * @param {string} url - The original URL.
3003
- * @param {string} queryString - The query string parameter to remove.
3004
- * @returns {string} - The updated URL without the specified query string parameter.
3183
+ /**
3184
+ * Removes a specific query string parameter from a URL.
3185
+ * @param {string} url - The original URL.
3186
+ * @param {string} queryString - The query string parameter to remove.
3187
+ * @returns {string} - The updated URL without the specified query string parameter.
3005
3188
  */
3006
3189
  function removeQueryString(url, queryString) {
3007
3190
  try {
@@ -3016,12 +3199,12 @@ function removeQueryString(url, queryString) {
3016
3199
  return url; // Return the original URL if there's an error
3017
3200
  }
3018
3201
  }
3019
- /**
3020
- * Converts an array of objects to a map using a specified attribute as the key.
3021
- *
3022
- * @param {Array<Object>} arr - The array of objects to be converted.
3023
- * @param {string} attr - The attribute to use as the key for the mapping.
3024
- * @returns {Object} - An object mapping each unique attribute value to its corresponding item.
3202
+ /**
3203
+ * Converts an array of objects to a map using a specified attribute as the key.
3204
+ *
3205
+ * @param {Array<Object>} arr - The array of objects to be converted.
3206
+ * @param {string} attr - The attribute to use as the key for the mapping.
3207
+ * @returns {Object} - An object mapping each unique attribute value to its corresponding item.
3025
3208
  */
3026
3209
  function arrayToMap(attr, arr, keyParser) {
3027
3210
  return arr.reduce(function (map, item) {
@@ -3047,9 +3230,9 @@ var rmUpdates = function rmUpdates(url) {
3047
3230
 
3048
3231
  var MAX_RETRIES = 5;
3049
3232
  var CACHE_KEY = "tools-cache-metadata";
3233
+ var CACHE_BUST_KEY = "_fb_cache_bust";
3050
3234
  // let toolsCache: ToolsData | null = null;
3051
3235
  // let toolsFetchPromise: Promise<ToolsData | null> | null = null;
3052
- var defaultFactoryData = '{"etag":"W/\\"97cce03e8c6f6c8092dfac11069679e7\\"","lastModified":"Fri, 23 May 2025 17:24:27 GMT","cachedData":{"totalUpdates":1,"lastUpdatedOn":"Fri, 23 May 2025 17:24:18 GMT","tools":[{"id":"U8SL1BvlIb1nxj4JNCNX","siteUrl":"/bank","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"isActive":true,"isHidden":false,"update_price":0.1,"allow_freemium":true,"create_price_is_monthly":true,"rank":1,"icon":"Building","siteLogoUrl":"/templates/tool-U8SL1BvlIb1nxj4JNCNX.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Online Banking Website","chat_supported":true,"create_price":20000,"quarterly_price":50000,"yearly_price":150000,"create_price_discount":0,"description":"Create an online banking website for your content. No more building a custom online banking website from scratch every time you need to film a banking scene.","x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","updatedAt,current_time,0,0,true,true,true","profilePhoto,string,0,300,true,true,false","email,string,0,64,true,true,false","phone,string,0,32,true,true,false","accountType,string,0,64,true,true,false","gender,string,0,64,true,true,false","maritalStatus,string,0,64,true,true,false","dob,string,0,16,true,true,false","password,string,6,16,true,true,false","pin,number,1000,9999,true,true,false","address,string,0,128,true,true,false","occupation,string,0,64,true,true,false","accountNumber_username,number,9000000000,9999999999,false,true,false","fullname,string,0,64,true,true,false","currencySymbol,string,0,64,true,true,false","disableAccount,boolean,0,8,true,true,false","accountBalance,number,0,999999999999999,true,false,false","autoRenewSubscription,boolean,0,8,true,true,false","credits,array:string:1:200,0,10,true,false,false","debits,array:string:1:200,0,10,true,false,false","totalCredits,number,0,999999999999999,true,false,false","totalDebits,number,0,999999999999999,true,false,false","disableAccountError,string,1,500,true,false,false","noTxGeneration,boolean,0,8,false,false,false","isHidden,boolean,1,8,true,false,false","isActive,boolean,1,8,true,false,false","txProcessingDuration,string,1,64,true,true,false","isInActive,boolean,0,8,true,false,false"],"tool_version_code":7},{"id":"0QZLQQKVTRV3Q6SFAIEA","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","createdAt":{"_seconds":1733770038,"_nanoseconds":796000000},"is_static":false,"isActive":true,"is_freemium":true,"icon":"ShippingFast","isHidden":false,"editables":"Shipping_Status@small.select, error_message.textarea, expected_arrival_date.date","templates_url":"/templates/templates-awsuv5ba.json?updates=23","youtube":null,"mobileVideoUrl":null,"desktopVideoUrl":null,"allow_freemium":true,"chat_supported":true,"create_price":10000,"message":"ID_TITLE == Tracking ID\\nLINK == zendcargo.com\\nCONTENT == Track your shipment using the tracking ID above at the tracking website: {LINK}.","description":"Create a shipping invoice with a tracking website for your content. No more building a custom shipping site from scratch every time you need to film a shipping scene.","update_price":200,"updatedAt":{"_seconds":1746816982,"_nanoseconds":404000000},"rank":2,"name":"Shipping","parent":"","x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","expectedArrivalDate,time,0,0,true,true,false","invoiceNumber,string,1,16,false,true,false","packageContent,string,1,64,false,true,false","packageDestinationAddress,string,1,64,false,true,false","packageDestinationEmail,string,1,256,false,true,false","packageDestinationPhone,string,1,16,false,true,false","packageRecipientName,string,1,128,false,true,false","packageWeight,string,1,32,false,true,false","senderEmail,string,1,256,false,true,false","senderName,string,1,128,false,true,false","shipmentDate,time,0,0,false,true,false","shipmentFee,string,0,32,false,true,false","shippingStatus,string,1,32,true,true,false","updatedAt,current_time,0,0,true,true,true","costCurrency,string,0,64,false,false,false","errorMessage,string,1,500,true,false,false"],"tool_version_code":7,"freemiumDownloadMessage":"The shipping invoice will have watermark. The tracking website will also have a \\"fake tracking\\" message.","premiumDownloadMessage":"The shipping invoice will be clean with no watermark. The tracking website will also be clean with no \\"fake tracking\\" message.","templates":[{"id":"hwd7x6ou","name":"Shipping Invoice with Tracking Website","logo":"https://r2.softbaker.com/templates/templates-awsuv5ba-hwd7x6ou-logo.jpeg","data_url":"https://r2.frontbacked.com/templates/templates-awsuv5ba-hwd7x6ou-data.json?updates=1","is_default":true,"split_on_download":false,"thumbnail":"https://r2.frontbacked.com/templates/tools-awsuv5ba-hwd7x6ou-thumbnail.jpg?updates=1&tct=1748021058263"}]},{"id":"5vCsgJJVsFYhV4dZYQdI","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"name":"Invoice","isActive":true,"isHidden":false,"allow_freemium":true,"siteUrl":"/invoice","siteLogoUrl":"/templates/tool-5vCsgJJVsFYhV4dZYQdI.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"description":"Create a payment invoice easily.","rank":3,"update_price":200,"create_price":5000,"x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","updatedAt,current_time,0,0,true,true,true","companyName,string,2,64,false,true,false","companyAddress,string,2,64,false,true,false","customerName,string,2,64,false,true,false","customerAddress,string,2,64,false,true,false","invoiceNumber,string,2,64,false,true,false","date,time,0,0,false,true,false","currency,string,2,64,false,true,false","items,object_array:{description@string_1_90|quantity@number_1_1000000000000000|price@number_1_1000000000000000},1,6,false,true,false","paymentDetails,string,2,256,false,false,false","vat,number,0,99,false,true,false","logo,string,0,64,false,false,false","waterMarkWithLogo,boolean,0,64,false,true,false","grayScaleWaterMark,boolean,0,64,false,true,false"],"tool_version_code":2},{"id":"tDYsSHDnF58hFCf3nUTk","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"icon":"Coins","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Face Swap Video Call","siteUrl":"/face-swap-video-call","isActive":false,"siteLogoUrl":"/templates/tool-tDYsSHDnF58hFCf3nUTk.jpg?v=2","rank":4,"isHidden":false},{"id":"XFXW1s8LlhiJnZKPbdWX","siteUrl":"/invest","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"isActive":false,"icon":"MoneyBillAlt","siteLogoUrl":"/templates/tool-XFXW1s8LlhiJnZKPbdWX.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Investment Website","rank":5,"isHidden":false}]}}';
3053
3236
  var setR2Host = function setR2Host(url, r2Domain) {
3054
3237
  if (!url) return url;
3055
3238
  if (url.startsWith('/')) {
@@ -3066,11 +3249,42 @@ var setR2Host = function setR2Host(url, r2Domain) {
3066
3249
  }
3067
3250
  };
3068
3251
 
3252
+ var addCacheBust = function addCacheBust(url) {
3253
+ try {
3254
+ var parsedUrl = new URL(url);
3255
+ parsedUrl.searchParams.set(CACHE_BUST_KEY, Date.now().toString());
3256
+ return parsedUrl.toString();
3257
+ } catch (err) {
3258
+ return url;
3259
+ }
3260
+ };
3261
+ var readCachedMetadata = function readCachedMetadata() {
3262
+ if (!isBrowser()) return null;
3263
+ try {
3264
+ var cachedMetadata = localStorage.getItem(CACHE_KEY);
3265
+ return cachedMetadata ? JSON.parse(cachedMetadata) : null;
3266
+ } catch (err) {
3267
+ localStorage.removeItem(CACHE_KEY);
3268
+ return null;
3269
+ }
3270
+ };
3271
+ var readCachedToolsData = function readCachedToolsData() {
3272
+ if (!isBrowser()) return null;
3273
+ if (window.toolsCache) return window.toolsCache;
3274
+ var cachedMetadata = readCachedMetadata();
3275
+ var cachedData = cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.cachedData;
3276
+ if (cachedData) {
3277
+ window.toolsCache = cachedData;
3278
+ return cachedData;
3279
+ }
3280
+ return null;
3281
+ };
3069
3282
  var useTools = function useTools(config) {
3070
- var _a = React.useState(isBrowser() ? window.toolsCache : null),
3283
+ var cachedToolsData = readCachedToolsData();
3284
+ var _a = React.useState(cachedToolsData),
3071
3285
  data = _a[0],
3072
3286
  setData = _a[1];
3073
- var _b = React.useState(!isBrowser() || !window.toolsCache),
3287
+ var _b = React.useState(!cachedToolsData),
3074
3288
  loading = _b[0],
3075
3289
  setLoading = _b[1];
3076
3290
  var _c = React.useState(null),
@@ -3084,63 +3298,48 @@ var useTools = function useTools(config) {
3084
3298
  setToolsByTemplatesUrl = _e[1];
3085
3299
  React.useEffect(function () {
3086
3300
  if (!(config === null || config === void 0 ? void 0 : config.r2Domain)) return;
3087
- if (window.toolsCache) {
3088
- setData(window.toolsCache);
3301
+ var cachedToolsData = readCachedToolsData();
3302
+ if (cachedToolsData) {
3303
+ setData(cachedToolsData);
3089
3304
  setLoading(false);
3090
- consoleLog("useTools.returns as toolsCache already exist: ", window.toolsCache);
3091
- return;
3305
+ consoleLog("useTools.returns cached tools data: ", cachedToolsData);
3092
3306
  }
3093
3307
  if (!window.toolsFetchPromise) {
3094
3308
  window.toolsFetchPromise = function () {
3095
3309
  return __awaiter(void 0, void 0, void 0, function () {
3096
- var attempts, headers, cachedMetadata, _a, etag, lastModified, cachedData, response, err_1;
3097
- var _b;
3310
+ var attempts, cachedData, response, err_1;
3311
+ var _a, _b;
3098
3312
  return __generator(this, function (_c) {
3099
3313
  switch (_c.label) {
3100
3314
  case 0:
3101
3315
  attempts = 0;
3102
- headers = {};
3103
- cachedMetadata = localStorage.getItem(CACHE_KEY) || defaultFactoryData;
3104
- if (cachedMetadata) {
3105
- _a = JSON.parse(cachedMetadata), etag = _a.etag, lastModified = _a.lastModified, cachedData = _a.cachedData;
3106
- if (cachedData) {
3107
- window.toolsCache = cachedData;
3108
- setData(cachedData);
3109
- setLoading(false);
3110
- //return cachedData;
3111
- }
3112
-
3113
- if (etag) headers["If-None-Match"] = etag;
3114
- if (lastModified) headers["If-Modified-Since"] = lastModified;
3316
+ cachedData = readCachedToolsData();
3317
+ if (cachedData) {
3318
+ setData(cachedData);
3319
+ setLoading(false);
3115
3320
  }
3116
- consoleLog("useTools.headers: ", headers);
3321
+ consoleLog("useTools.refreshing");
3117
3322
  _c.label = 1;
3118
3323
  case 1:
3119
3324
  if (!(attempts < MAX_RETRIES)) return [3 /*break*/, 6];
3120
3325
  _c.label = 2;
3121
3326
  case 2:
3122
3327
  _c.trys.push([2, 4,, 5]);
3123
- return [4 /*yield*/, axios__default["default"].get("https://".concat(config.r2Domain, "/templates/tools.json"), {
3124
- headers: headers,
3125
- validateStatus: function validateStatus(status) {
3126
- return status < 500;
3127
- } // Accept 304 Not Modified
3128
- })];
3129
-
3328
+ return [4 /*yield*/, axios__default["default"].get(addCacheBust("https://".concat(config.r2Domain, "/templates/tools.json")))];
3130
3329
  case 3:
3131
3330
  response = _c.sent();
3132
- if (response.status === 304) {
3133
- setLoading(false);
3134
- consoleLog("useTools.notModied: ", response.status);
3135
- return [2 /*return*/, window.toolsCache];
3331
+ if (_typeof(response.data) !== "object" || !Array.isArray((_a = response.data) === null || _a === void 0 ? void 0 : _a.tools)) {
3332
+ throw new Error("Invalid tools response");
3136
3333
  }
3137
3334
  window.toolsCache = response.data;
3138
3335
  setData(response.data);
3139
3336
  setError(null);
3337
+ setLoading(false);
3140
3338
  // Save cache metadata
3141
3339
  localStorage.setItem(CACHE_KEY, JSON.stringify({
3142
3340
  etag: response.headers["etag"],
3143
3341
  lastModified: response.headers["last-modified"],
3342
+ cachedAt: Date.now(),
3144
3343
  cachedData: response.data
3145
3344
  }));
3146
3345
  consoleLog("useTools.refreshed: ", response.data, " at ".concat(response.headers["last-modified"], ", with etag, ").concat(response.headers["etag"]));
@@ -3148,23 +3347,30 @@ var useTools = function useTools(config) {
3148
3347
  case 4:
3149
3348
  err_1 = _c.sent();
3150
3349
  if (((_b = err_1.response) === null || _b === void 0 ? void 0 : _b.status) === 404) {
3151
- setError("Resource not found (404)");
3350
+ if (!window.toolsCache) setError("Resource not found (404)");
3152
3351
  return [3 /*break*/, 6];
3153
3352
  }
3154
3353
  attempts++;
3155
3354
  if (attempts === MAX_RETRIES) {
3156
- setError("Failed to fetch data after multiple attempts");
3355
+ if (!window.toolsCache) setError("Failed to fetch data after multiple attempts");
3157
3356
  }
3158
3357
  return [3 /*break*/, 5];
3159
3358
  case 5:
3160
3359
  return [3 /*break*/, 1];
3161
3360
  case 6:
3361
+ if (window.toolsCache) {
3362
+ setError(null);
3363
+ setLoading(false);
3364
+ return [2 /*return*/, window.toolsCache];
3365
+ }
3162
3366
  setLoading(false);
3163
3367
  return [2 /*return*/, null];
3164
3368
  }
3165
3369
  });
3166
3370
  });
3167
- }();
3371
+ }()["finally"](function () {
3372
+ window.toolsFetchPromise = null;
3373
+ });
3168
3374
  }
3169
3375
  window.toolsFetchPromise.then(function (result) {
3170
3376
  if (result) setData(result);