grab-url 1.0.6 → 1.0.8

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 (47) hide show
  1. package/dist/download.cjs.js +3 -0
  2. package/dist/download.cjs.js.map +1 -0
  3. package/dist/download.d.ts +1 -0
  4. package/dist/download.es.js +3715 -0
  5. package/dist/download.es.js.map +1 -0
  6. package/dist/grab-api.cjs.js +1 -1
  7. package/dist/grab-api.cjs.js.map +1 -1
  8. package/dist/grab-api.d.ts +64 -55
  9. package/dist/grab-api.es.js +87 -223
  10. package/dist/grab-api.es.js.map +1 -1
  11. package/dist/grab-api.umd.js +2 -0
  12. package/dist/grab-api.umd.js.map +1 -0
  13. package/dist/icons.cjs.js +1 -1
  14. package/dist/icons.cjs.js.map +1 -1
  15. package/dist/icons.d.ts +0 -0
  16. package/dist/icons.es.js +3 -3
  17. package/dist/icons.es.js.map +1 -1
  18. package/dist/log.cjs.js +2 -0
  19. package/dist/log.cjs.js.map +1 -0
  20. package/dist/log.d.ts +123 -0
  21. package/dist/log.es.js +299 -0
  22. package/dist/log.es.js.map +1 -0
  23. package/package.json +17 -13
  24. package/readme.md +7 -7
  25. package/src/grab-api.ts +114 -72
  26. package/src/grab-url.js +15 -81
  27. package/src/icons/cli/spinners.js +818 -0
  28. package/src/icons/svg/index.ts +0 -0
  29. package/src/icons/svg/loading-bouncy-ball.svg +0 -0
  30. package/src/icons/svg/loading-double-ring.svg +0 -0
  31. package/src/icons/svg/loading-eclipse.svg +0 -0
  32. package/src/icons/svg/loading-ellipsis.svg +0 -0
  33. package/src/icons/svg/loading-floating-search.svg +0 -0
  34. package/src/icons/svg/loading-gears.svg +0 -0
  35. package/src/icons/svg/loading-infinity.svg +0 -0
  36. package/src/icons/svg/loading-orbital.svg +0 -0
  37. package/src/icons/svg/loading-pacman.svg +0 -0
  38. package/src/icons/svg/loading-pulse-bars.svg +0 -0
  39. package/src/icons/svg/loading-red-blue-ball.svg +0 -0
  40. package/src/icons/svg/loading-reload-arrow.svg +0 -0
  41. package/src/icons/svg/loading-ring.svg +0 -0
  42. package/src/icons/svg/loading-ripple.svg +0 -0
  43. package/src/icons/svg/loading-spinner-oval.svg +0 -0
  44. package/src/icons/svg/loading-spinner.svg +0 -0
  45. package/src/icons/svg/loading-square-blocks.svg +0 -0
  46. package/src/{log.ts → log-json.ts} +128 -129
  47. package/src/icons/cli/spinners.json +0 -1074
@@ -1,180 +1,6 @@
1
- function log(message = "", options = {}) {
2
- let {
3
- color = null,
4
- style = "color: blue; font-size: 11pt;",
5
- hideInProduction = void 0,
6
- startSpinner = false,
7
- stopSpinner = false
8
- } = options;
9
- if (typeof hideInProduction === "undefined")
10
- hideInProduction = typeof window !== "undefined" && (window == null ? void 0 : window.location.hostname.includes("localhost"));
11
- if (typeof message === "object")
12
- message = printJSONStructure(message) + "\n\n" + JSON.stringify(message, null, 2);
13
- if (color && typeof process !== void 0)
14
- message = (colors[color] || "") + message + colors.reset;
15
- var i = 0;
16
- if (startSpinner)
17
- (global || globalThis).interval = setInterval(() => {
18
- process.stdout.write(
19
- (colors[color] || "") + "\r" + "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏".split("")[i = ++i % 10] + " " + message + colors.reset
20
- );
21
- }, 50);
22
- else if (stopSpinner) {
23
- clearInterval((global || globalThis).interval);
24
- process.stdout.write(
25
- "\r" + (message || "✔ Done") + " ".repeat(message.length + 20) + "\n"
26
- );
27
- } else if (typeof style === "string") {
28
- if (style.split(" ").length == 1 || color) {
29
- style = `color: ${color || style}; font-size: 11pt;`;
30
- } else {
31
- if (style.match(/^#[0-9a-fA-F]{6}$/)) {
32
- style = `color: ${style}; font-size: 11pt;`;
33
- }
34
- }
35
- if (hideInProduction)
36
- console.debug((style ? "%c" : "") + (message || ""), style);
37
- else console.log((style ? "%c" : "") + (message || ""), style);
38
- } else if (typeof style === "object") console.log(message, ...style);
39
- return true;
40
- }
41
- const colors = {
42
- reset: "\x1B[0m",
43
- // Reset to default color
44
- black: "\x1B[30m",
45
- red: "\x1B[31m",
46
- // Functions, errors
47
- green: "\x1B[32m",
48
- // Object braces, success
49
- yellow: "\x1B[33m",
50
- // Strings, warnings
51
- blue: "\x1B[34m",
52
- // Array brackets, info
53
- magenta: "\x1B[35m",
54
- // Booleans
55
- cyan: "\x1B[36m",
56
- // Numbers
57
- white: "\x1B[37m",
58
- // Default color, plain text
59
- gray: "\x1B[90m",
60
- // Null, undefined, subtle
61
- // Bright variants
62
- brightRed: "\x1B[91m",
63
- brightGreen: "\x1B[92m",
64
- brightYellow: "\x1B[93m",
65
- brightBlue: "\x1B[94m",
66
- brightMagenta: "\x1B[95m",
67
- brightCyan: "\x1B[96m",
68
- brightWhite: "\x1B[97m",
69
- // Background colors (optional)
70
- bgRed: "\x1B[41m",
71
- bgGreen: "\x1B[42m",
72
- bgYellow: "\x1B[43m",
73
- bgBlue: "\x1B[44m",
74
- bgMagenta: "\x1B[45m",
75
- bgCyan: "\x1B[46m",
76
- bgWhite: "\x1B[47m",
77
- bgGray: "\x1B[100m"
78
- };
79
- function getColorForType(value) {
80
- if (typeof value === "string") return colors.yellow;
81
- if (typeof value === "number") return colors.cyan;
82
- if (typeof value === "boolean") return colors.magenta;
83
- if (typeof value === "function") return colors.red;
84
- if (value === null) return colors.gray;
85
- if (Array.isArray(value)) return colors.blue;
86
- if (typeof value === "object") return colors.green;
87
- return colors.white;
88
- }
89
- function getTypeString(value) {
90
- if (typeof value === "string") return '""';
91
- if (typeof value === "number") return "number";
92
- if (typeof value === "boolean") return "bool";
93
- if (typeof value === "function") return "function";
94
- if (value === null) return "null";
95
- if (Array.isArray(value)) {
96
- if (value.length) return "[" + getTypeString(value[0]) + "]";
97
- else return "[]";
98
- }
99
- if (typeof value === "object") return "{...}";
100
- return typeof value;
101
- }
102
- function printJSONStructure(obj, indent = 0) {
103
- const pad = " ".repeat(indent);
104
- if (typeof obj !== "object" || obj === null) {
105
- const color = getColorForType(obj);
106
- return color + getTypeString(obj) + colors.reset;
107
- }
108
- if (Array.isArray(obj)) {
109
- let result2 = colors.blue + "[" + colors.reset;
110
- if (obj.length) result2 += "\n";
111
- obj.forEach((item, idx) => {
112
- result2 += pad + " " + printJSONStructure(item, indent + 1);
113
- if (idx < obj.length - 1) result2 += ",";
114
- result2 += "\n";
115
- });
116
- result2 += pad + colors.blue + "]" + colors.reset;
117
- return result2;
118
- }
119
- let result = colors.green + "{" + colors.reset;
120
- const keys = Object.keys(obj);
121
- if (keys.length) result += "\n";
122
- keys.forEach((key, index) => {
123
- const value = obj[key];
124
- const color = getColorForType(value);
125
- result += pad + " ";
126
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
127
- result += color + key + colors.reset + ": " + printJSONStructure(value, indent + 1);
128
- } else if (Array.isArray(value)) {
129
- result += color + key + colors.reset + ": " + printJSONStructure(value, indent + 1);
130
- } else {
131
- result += color + key + ": " + getTypeString(value) + colors.reset;
132
- }
133
- if (index < keys.length - 1) result += ",";
134
- result += "\n";
135
- });
136
- result += pad + colors.green + "}" + colors.reset;
137
- return result;
138
- }
139
- function showAlert(msg) {
140
- if (typeof document === "undefined") return;
141
- let o = document.getElementById("alert-overlay"), list;
142
- if (!o) {
143
- o = document.body.appendChild(document.createElement("div"));
144
- o.id = "alert-overlay";
145
- o.setAttribute(
146
- "style",
147
- "position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center"
148
- );
149
- o.innerHTML = `<div id="alert-box" style="background:#fff;padding:1.5em 2em;border-radius:8px;box-shadow:0 2px 16px #0003;min-width:220px;max-height:80vh;position:relative;display:flex;flex-direction:column;">
150
- <button id="close-alert" style="position:absolute;top:12px;right:20px;font-size:1.5em;background:none;border:none;cursor:pointer;color:black;">&times;</button>
151
- <div id="alert-list" style="overflow:auto;flex:1;"></div>
152
- </div>`;
153
- o.addEventListener("click", (e) => e.target == o && o.remove());
154
- document.getElementById("close-alert").onclick = () => o.remove();
155
- }
156
- list = o.querySelector("#alert-list");
157
- list.innerHTML += `<div style="border-bottom:1px solid #333; font-size:1.2em;margin:0.5em 0;">${msg}</div>`;
158
- }
159
- function setupDevTools() {
160
- document.addEventListener("keydown", (e) => {
161
- if (e.key === "i" && e.ctrlKey) {
162
- let html = " ";
163
- for (let request of grab.log) {
164
- html += `<div style="margin-bottom:1em; border-bottom:1px solid #ccc; padding-bottom:1em;">
165
- <b>Path:</b> ${request.path}<br>
166
- <b>Request:</b> ${request.request}<br>
167
- <b>Response:</b> ${JSON.stringify(request.response, null, 2)}<br>
168
- <b>Time:</b> ${new Date(request.lastFetchTime).toLocaleString()}
169
- </div>`;
170
- }
171
- showAlert(html);
172
- }
173
- });
174
- }
175
- async function grab$1(path, options) {
176
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
177
- let {
1
+ import { log, printJSONStructure } from "./log.es.js";
2
+ async function grab(path, options) {
3
+ var {
178
4
  headers,
179
5
  response = {},
180
6
  // Pre-initialized object to set the response in. isLoading and error are also set on this object.
@@ -232,7 +58,7 @@ async function grab$1(path, options) {
232
58
  // All other params become request params/query
233
59
  } = {
234
60
  // Destructure options with defaults, merging with any globally set defaults
235
- ...typeof window !== "undefined" ? (_a = window == null ? void 0 : window.grab) == null ? void 0 : _a.defaults : ((_c = (_b = global || globalThis) == null ? void 0 : _b.grab) == null ? void 0 : _c.defaults) || {},
61
+ ...typeof window !== "undefined" ? window?.grab?.defaults : (global || globalThis)?.grab?.defaults || {},
236
62
  ...options
237
63
  };
238
64
  let s = (t) => path.startsWith(t);
@@ -242,21 +68,21 @@ async function grab$1(path, options) {
242
68
  try {
243
69
  if (debounce > 0)
244
70
  return await debouncer(async () => {
245
- await grab$1(path, { ...options, debounce: 0 });
71
+ await grab(path, { ...options, debounce: 0 });
246
72
  }, debounce * 1e3);
247
73
  if (repeat > 1) {
248
74
  for (let i = 0; i < repeat; i++) {
249
- await grab$1(path, { ...options, repeat: 0 });
75
+ await grab(path, { ...options, repeat: 0 });
250
76
  }
251
77
  return response;
252
78
  }
253
79
  if (repeatEvery) {
254
80
  setInterval(async () => {
255
- await grab$1(path, { ...options, repeat: 0, repeatEvery: null });
81
+ await grab(path, { ...options, repeat: 0, repeatEvery: null });
256
82
  }, repeatEvery * 1e3);
257
83
  return response;
258
84
  }
259
- if (options == null ? void 0 : options.setDefaults) {
85
+ if (options?.setDefaults) {
260
86
  if (typeof window !== "undefined")
261
87
  window.grab.defaults = { ...options, setDefaults: void 0 };
262
88
  else if (typeof (global || globalThis).grab !== "undefined")
@@ -266,8 +92,8 @@ async function grab$1(path, options) {
266
92
  };
267
93
  return;
268
94
  }
269
- if (typeof window !== void 0) {
270
- const regrab = async () => await grab$1(path, { ...options, cache: false });
95
+ if (typeof window !== "undefined") {
96
+ const regrab = async () => await grab(path, { ...options, cache: false });
271
97
  if (regrabOnStale && cache) setTimeout(regrab, 1e3 * cacheForTime);
272
98
  if (regrabOnNetwork) window.addEventListener("online", regrab);
273
99
  if (regrabOnFocus) {
@@ -280,9 +106,10 @@ async function grab$1(path, options) {
280
106
  let resFunction = typeof response === "function" ? response : null;
281
107
  if (!response || resFunction) response = {};
282
108
  var [paginateKey, paginateResult, paginateElement] = infiniteScroll || [];
283
- if ((infiniteScroll == null ? void 0 : infiniteScroll.length) && typeof window !== "undefined") {
109
+ if (infiniteScroll?.length && typeof paginateElement !== "undefined" && typeof window !== "undefined") {
284
110
  let paginateDOM = typeof paginateElement === "string" ? document.querySelector(paginateElement) : paginateElement;
285
- if (window.scrollListener)
111
+ if (!paginateDOM) log("paginateDOM not found", { color: "red" });
112
+ else if (window.scrollListener && typeof paginateDOM !== "undefined" && typeof paginateDOM.removeEventListener === "function")
286
113
  paginateDOM.removeEventListener("scroll", window.scrollListener);
287
114
  window.scrollListener = async (event) => {
288
115
  const t = event.target;
@@ -291,49 +118,50 @@ async function grab$1(path, options) {
291
118
  JSON.stringify([t.scrollTop, t.scrollLeft, paginateElement])
292
119
  );
293
120
  if (t.scrollHeight - t.scrollTop <= t.clientHeight + 200) {
294
- await grab$1(path, {
121
+ await grab(path, {
295
122
  ...options,
296
123
  cache: false,
297
- [paginateKey]: (priorRequest == null ? void 0 : priorRequest.currentPage) + 1
124
+ [paginateKey]: priorRequest?.currentPage + 1
298
125
  });
299
126
  }
300
127
  };
301
- paginateDOM.addEventListener("scroll", window.scrollListener);
128
+ if (paginateDOM)
129
+ paginateDOM.addEventListener("scroll", window.scrollListener);
302
130
  }
303
131
  let paramsAsText = JSON.stringify(
304
132
  paginateKey ? { ...params, [paginateKey]: void 0 } : params
305
133
  );
306
- let priorRequest = (_d = grab$1 == null ? void 0 : grab$1.log) == null ? void 0 : _d.find(
134
+ let priorRequest = grab?.log?.find(
307
135
  (e) => e.request == paramsAsText && e.path == path
308
136
  );
309
137
  if (!paginateKey) {
310
138
  for (let key of Object.keys(response)) response[key] = void 0;
311
- if (cache && (!cacheForTime || (priorRequest == null ? void 0 : priorRequest.lastFetchTime) > Date.now() - 1e3 * cacheForTime)) {
139
+ if (cache && (!cacheForTime || priorRequest?.lastFetchTime > Date.now() - 1e3 * cacheForTime)) {
312
140
  for (let key of Object.keys(priorRequest.res))
313
141
  response[key] = priorRequest.res[key];
314
142
  if (resFunction) response = resFunction(response);
315
143
  }
316
144
  } else {
317
- let pageNumber = (priorRequest == null ? void 0 : priorRequest.currentPage) + 1 || (params == null ? void 0 : params[paginateKey]) || 1;
145
+ let pageNumber = priorRequest?.currentPage + 1 || params?.[paginateKey] || 1;
318
146
  if (!priorRequest) {
319
147
  response[paginateResult] = [];
320
148
  pageNumber = 1;
321
149
  }
322
150
  if (priorRequest) priorRequest.currentPage = pageNumber;
323
- params[paginateKey] = pageNumber;
151
+ params = { ...params, [paginateKey]: pageNumber };
324
152
  }
325
153
  if (resFunction) resFunction({ isLoading: true });
326
154
  else if (typeof response === "object") response.isLoading = true;
327
155
  if (resFunction) response = resFunction(response);
328
- if (rateLimit > 0 && (priorRequest == null ? void 0 : priorRequest.lastFetchTime) && priorRequest.lastFetchTime > Date.now() - 1e3 * rateLimit)
156
+ if (rateLimit > 0 && priorRequest?.lastFetchTime && priorRequest.lastFetchTime > Date.now() - 1e3 * rateLimit)
329
157
  throw new Error(`Fetch rate limit exceeded for ${path}.
330
158
  Wait ${rateLimit}s between requests.`);
331
- if (priorRequest == null ? void 0 : priorRequest.controller) {
159
+ if (priorRequest?.controller) {
332
160
  if (cancelOngoingIfNew) priorRequest.controller.abort();
333
161
  else if (cancelNewIfOngoing) return { isLoading: true };
334
162
  }
335
- if (typeof grab$1.log != "undefined")
336
- (_e = grab$1.log) == null ? void 0 : _e.unshift({
163
+ if (typeof grab.log != "undefined")
164
+ grab.log?.unshift({
337
165
  path,
338
166
  request: paramsAsText,
339
167
  lastFetchTime: Date.now(),
@@ -349,7 +177,7 @@ async function grab$1(path, options) {
349
177
  body: params.body,
350
178
  redirect: "follow",
351
179
  cache: cache ? "force-cache" : "no-store",
352
- signal: cancelOngoingIfNew ? (_g = (_f = grab$1.log[0]) == null ? void 0 : _f.controller) == null ? void 0 : _g.signal : AbortSignal.timeout(timeout * 1e3)
180
+ signal: cancelOngoingIfNew ? grab.log[0]?.controller?.signal : AbortSignal.timeout(timeout * 1e3)
353
181
  };
354
182
  let paramsGETRequest = "";
355
183
  if (["POST", "PUT", "PATCH"].includes(method))
@@ -363,7 +191,7 @@ async function grab$1(path, options) {
363
191
  params,
364
192
  fetchParams
365
193
  );
366
- let res = null, startTime = /* @__PURE__ */ new Date(), mockHandler = (_h = grab$1.mock) == null ? void 0 : _h[path];
194
+ let res = null, startTime = /* @__PURE__ */ new Date(), mockHandler = grab.mock?.[path];
367
195
  let wait = (s2) => new Promise((res2) => setTimeout(res2, s2 * 1e3 || 0));
368
196
  if (mockHandler && (!mockHandler.params || mockHandler.method == method) && (!mockHandler.params || paramsAsText == JSON.stringify(mockHandler.params))) {
369
197
  await wait(mockHandler.delay);
@@ -371,7 +199,7 @@ async function grab$1(path, options) {
371
199
  } else {
372
200
  res = await fetch(baseURL + path + paramsGETRequest, fetchParams).catch(
373
201
  (e) => {
374
- throw new Error(e);
202
+ throw new Error(e.message);
375
203
  }
376
204
  );
377
205
  if (!res.ok)
@@ -391,8 +219,8 @@ async function grab$1(path, options) {
391
219
  fetchParams
392
220
  );
393
221
  if (resFunction) resFunction({ isLoading: void 0 });
394
- else if (typeof response === "object") response == null ? true : delete response.isLoading;
395
- priorRequest == null ? true : delete priorRequest.controller;
222
+ else if (typeof response === "object") delete response?.isLoading;
223
+ delete priorRequest?.controller;
396
224
  const elapsedTime = ((Number(/* @__PURE__ */ new Date()) - Number(startTime)) / 1e3).toFixed(1);
397
225
  if (debug) {
398
226
  logger(
@@ -401,12 +229,12 @@ async function grab$1(path, options) {
401
229
  }
402
230
  if (typeof res === "object") {
403
231
  for (let key of Object.keys(res))
404
- response[key] = paginateResult == key && ((_i = response[key]) == null ? void 0 : _i.length) ? [...response[key], ...res[key]] : res[key];
232
+ response[key] = paginateResult == key && response[key]?.length ? [...response[key], ...res[key]] : res[key];
405
233
  if (typeof response !== "undefined") response.data = res;
406
234
  } else if (resFunction) resFunction({ data: res, ...res });
407
235
  else if (typeof response === "object") response.data = res;
408
- if (typeof grab$1.log != "undefined")
409
- (_j = grab$1.log) == null ? void 0 : _j.unshift({
236
+ if (typeof grab.log != "undefined")
237
+ grab.log?.unshift({
410
238
  path,
411
239
  request: JSON.stringify({ ...params, paginateKey: void 0 }),
412
240
  response,
@@ -416,25 +244,24 @@ async function grab$1(path, options) {
416
244
  return response;
417
245
  } catch (error) {
418
246
  let errorMessage = "Error: " + error.message + "\nPath:" + baseURL + path + "\n";
419
- JSON.stringify(params);
420
247
  if (typeof onError === "function")
421
248
  onError(error.message, baseURL + path, params);
422
249
  if (options.retryAttempts > 0)
423
- return await grab$1(path, {
250
+ return await grab(path, {
424
251
  ...options,
425
252
  retryAttempts: --options.retryAttempts
426
253
  });
427
254
  if (!error.message.includes("signal") && options.debug) {
428
255
  logger(errorMessage, { color: "red" });
429
- if (debug && typeof document !== void 0) showAlert(errorMessage);
256
+ if (debug && typeof document !== "undefined") showAlert(errorMessage);
430
257
  }
431
258
  response.error = error.message;
432
259
  if (typeof response === "function") {
433
260
  response.data = response({ isLoading: void 0, error: error.message });
434
261
  response = response.data;
435
- } else response == null ? true : delete response.isLoading;
436
- if (typeof grab$1.log != "undefined")
437
- (_k = grab$1.log) == null ? void 0 : _k.unshift({
262
+ } else delete response?.isLoading;
263
+ if (typeof grab.log != "undefined")
264
+ grab.log?.unshift({
438
265
  path,
439
266
  request: JSON.stringify(params),
440
267
  error: error.message
@@ -442,7 +269,7 @@ async function grab$1(path, options) {
442
269
  return response;
443
270
  }
444
271
  }
445
- grab$1.instance = (defaults = {}) => (path, options = {}) => grab$1(path, { ...defaults, ...options });
272
+ grab.instance = (defaults = {}) => (path, options = {}) => grab(path, { ...defaults, ...options });
446
273
  const debouncer = async (func, wait) => {
447
274
  let timeout;
448
275
  return async function executedFunction(...args) {
@@ -456,7 +283,7 @@ const debouncer = async (func, wait) => {
456
283
  };
457
284
  if (typeof window !== "undefined") {
458
285
  window.log = log;
459
- window.grab = grab$1;
286
+ window.grab = grab;
460
287
  window.grab.log = [];
461
288
  window.grab.mock = {};
462
289
  window.grab.defaults = {};
@@ -468,23 +295,60 @@ if (typeof window !== "undefined") {
468
295
  document.querySelector(paginateElement).scrollLeft = scrollLeft;
469
296
  });
470
297
  } else if (typeof global !== "undefined") {
471
- grab$1.log = [];
472
- grab$1.mock = {};
473
- grab$1.defaults = {};
298
+ grab.log = [];
299
+ grab.mock = {};
300
+ grab.defaults = {};
474
301
  global.log = log;
475
- global.grab = grab$1.instance();
302
+ global.grab = grab.instance();
476
303
  } else if (typeof globalThis !== "undefined") {
477
- grab$1.log = [];
478
- grab$1.mock = {};
479
- grab$1.defaults = {};
304
+ grab.log = [];
305
+ grab.mock = {};
306
+ grab.defaults = {};
480
307
  globalThis.log = log;
481
- globalThis.grab = grab$1.instance();
308
+ globalThis.grab = grab.instance();
309
+ }
310
+ function showAlert(msg) {
311
+ if (typeof document === "undefined") return;
312
+ let o = document.getElementById("alert-overlay"), list;
313
+ if (!o) {
314
+ o = document.body.appendChild(document.createElement("div"));
315
+ o.id = "alert-overlay";
316
+ o.setAttribute(
317
+ "style",
318
+ "position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center"
319
+ );
320
+ o.innerHTML = `<div id="alert-box" style="background:#fff;padding:1.5em 2em;border-radius:8px;box-shadow:0 2px 16px #0003;min-width:220px;max-height:80vh;position:relative;display:flex;flex-direction:column;">
321
+ <button id="close-alert" style="position:absolute;top:12px;right:20px;font-size:1.5em;background:none;border:none;cursor:pointer;color:black;">&times;</button>
322
+ <div id="alert-list" style="overflow:auto;flex:1;"></div>
323
+ </div>`;
324
+ o.addEventListener("click", (e) => e.target == o && o.remove());
325
+ document.getElementById("close-alert").onclick = () => o.remove();
326
+ }
327
+ list = o.querySelector("#alert-list");
328
+ list.innerHTML += `<div style="border-bottom:1px solid #333; font-size:1.2em;margin:0.5em 0;">${msg}</div>`;
329
+ }
330
+ function setupDevTools() {
331
+ document.addEventListener("keydown", (e) => {
332
+ if (e.key === "i" && e.ctrlKey && e.altKey) {
333
+ let html = " ";
334
+ for (let request of grab.log) {
335
+ html += `<div style="margin-bottom:1em; border-bottom:1px solid #ccc; padding-bottom:1em;">
336
+ <b>Path:</b> ${request.path}<br>
337
+ <b>Request:</b> ${printJSONStructure(request.request, 0, "html")}<br>
338
+ <b>Response:</b> ${printJSONStructure(request.response, 0, "html")}<br>
339
+ <b>Time:</b> ${new Date(request.lastFetchTime).toLocaleString()}
340
+ </div>`;
341
+ }
342
+ showAlert(html);
343
+ }
344
+ });
482
345
  }
483
346
  export {
484
- grab$1 as default,
485
- grab$1 as grab,
347
+ grab as default,
348
+ grab,
486
349
  log,
487
350
  printJSONStructure,
351
+ setupDevTools,
488
352
  showAlert
489
353
  };
490
354
  //# sourceMappingURL=grab-api.es.js.map