grab-url 1.0.7 → 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.
package/dist/log.es.js ADDED
@@ -0,0 +1,299 @@
1
+ function log(message = "", options = {}) {
2
+ let {
3
+ color,
4
+ style = "color:rgb(54, 165, 220); font-size: 10pt;",
5
+ hideInProduction = void 0,
6
+ startSpinner = false,
7
+ stopSpinner = false
8
+ } = options;
9
+ const colors = getColors();
10
+ if (typeof hideInProduction === "undefined")
11
+ hideInProduction = typeof window !== "undefined" && window?.location.hostname.includes("localhost");
12
+ if (typeof message === "object")
13
+ message = printJSONStructure(message) + "\n\n" + JSON.stringify(message, null, 2);
14
+ if (Array.isArray(color) && color.length == 1) color = color[0];
15
+ if (color && typeof process !== void 0) {
16
+ if (message.includes("%c") && Array.isArray(color))
17
+ message = message.replace(/%c/g, (match, index) => colors[color[index]] || "");
18
+ else if (color && typeof color === "string")
19
+ message = (colors[color] || "") + message + colors.reset;
20
+ }
21
+ var i = 0;
22
+ if (startSpinner)
23
+ (global || globalThis).interval = setInterval(() => {
24
+ process.stdout.write(
25
+ (Array.isArray(color) ? colors[color[0]] : colors[color] || "") + "\r" + "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏".split("")[i = ++i % 10] + " " + message + colors.reset
26
+ );
27
+ }, 50);
28
+ else if (stopSpinner) {
29
+ clearInterval((global || globalThis).interval);
30
+ process.stdout.write(
31
+ "\r" + (message || " ") + " ".repeat(message.length + 20) + "\n"
32
+ );
33
+ } else if (typeof style === "string") {
34
+ if (style.split(" ").length == 1 || color) {
35
+ style = `color: ${color || style}; font-size: 11pt;`;
36
+ } else {
37
+ if (style.match(/^#[0-9a-fA-F]{6}$/)) {
38
+ style = `color: ${style}; font-size: 11pt;`;
39
+ }
40
+ }
41
+ if (hideInProduction)
42
+ console.debug((style ? "%c" : "") + (message || ""), style);
43
+ else console.log((style ? "%c" : "") + (message || ""), style);
44
+ } else if (typeof style === "object") console.log(message, ...style);
45
+ return true;
46
+ }
47
+ var ColorName = /* @__PURE__ */ ((ColorName2) => {
48
+ ColorName2["RESET"] = "reset";
49
+ ColorName2["BLACK"] = "black";
50
+ ColorName2["RED"] = "red";
51
+ ColorName2["GREEN"] = "green";
52
+ ColorName2["YELLOW"] = "yellow";
53
+ ColorName2["BLUE"] = "blue";
54
+ ColorName2["MAGENTA"] = "magenta";
55
+ ColorName2["CYAN"] = "cyan";
56
+ ColorName2["WHITE"] = "white";
57
+ ColorName2["GRAY"] = "gray";
58
+ ColorName2["BRIGHT_RED"] = "brightRed";
59
+ ColorName2["BRIGHT_GREEN"] = "brightGreen";
60
+ ColorName2["BRIGHT_YELLOW"] = "brightYellow";
61
+ ColorName2["BRIGHT_BLUE"] = "brightBlue";
62
+ ColorName2["BRIGHT_MAGENTA"] = "brightMagenta";
63
+ ColorName2["BRIGHT_CYAN"] = "brightCyan";
64
+ ColorName2["BRIGHT_WHITE"] = "brightWhite";
65
+ ColorName2["BG_RED"] = "bgRed";
66
+ ColorName2["BG_GREEN"] = "bgGreen";
67
+ ColorName2["BG_YELLOW"] = "bgYellow";
68
+ ColorName2["BG_BLUE"] = "bgBlue";
69
+ ColorName2["BG_MAGENTA"] = "bgMagenta";
70
+ ColorName2["BG_CYAN"] = "bgCyan";
71
+ ColorName2["BG_WHITE"] = "bgWhite";
72
+ ColorName2["BG_GRAY"] = "bgGray";
73
+ ColorName2["BG_BLACK"] = "bgBlack";
74
+ ColorName2["BG_BRIGHT_RED"] = "bgBrightRed";
75
+ ColorName2["BG_BRIGHT_GREEN"] = "bgBrightGreen";
76
+ ColorName2["BG_BRIGHT_YELLOW"] = "bgBrightYellow";
77
+ ColorName2["BG_BRIGHT_BLUE"] = "bgBrightBlue";
78
+ ColorName2["BG_BRIGHT_MAGENTA"] = "bgBrightMagenta";
79
+ ColorName2["BG_BRIGHT_CYAN"] = "bgBrightCyan";
80
+ ColorName2["BG_BRIGHT_WHITE"] = "bgBrightWhite";
81
+ return ColorName2;
82
+ })(ColorName || {});
83
+ const colorMap = {
84
+ [
85
+ "reset"
86
+ /* RESET */
87
+ ]: [0, "000000"],
88
+ [
89
+ "black"
90
+ /* BLACK */
91
+ ]: [30, "000000"],
92
+ [
93
+ "red"
94
+ /* RED */
95
+ ]: [31, "ff0000"],
96
+ [
97
+ "green"
98
+ /* GREEN */
99
+ ]: [32, "00ff00"],
100
+ [
101
+ "yellow"
102
+ /* YELLOW */
103
+ ]: [33, "ffff00"],
104
+ [
105
+ "blue"
106
+ /* BLUE */
107
+ ]: [34, "0000ff"],
108
+ [
109
+ "magenta"
110
+ /* MAGENTA */
111
+ ]: [35, "ff00ff"],
112
+ [
113
+ "cyan"
114
+ /* CYAN */
115
+ ]: [36, "00ffff"],
116
+ [
117
+ "white"
118
+ /* WHITE */
119
+ ]: [37, "ffffff"],
120
+ [
121
+ "gray"
122
+ /* GRAY */
123
+ ]: [90, "808080"],
124
+ [
125
+ "brightRed"
126
+ /* BRIGHT_RED */
127
+ ]: [91, "ff5555"],
128
+ [
129
+ "brightGreen"
130
+ /* BRIGHT_GREEN */
131
+ ]: [92, "55ff55"],
132
+ [
133
+ "brightYellow"
134
+ /* BRIGHT_YELLOW */
135
+ ]: [93, "ffff55"],
136
+ [
137
+ "brightBlue"
138
+ /* BRIGHT_BLUE */
139
+ ]: [94, "5555ff"],
140
+ [
141
+ "brightMagenta"
142
+ /* BRIGHT_MAGENTA */
143
+ ]: [95, "ff55ff"],
144
+ [
145
+ "brightCyan"
146
+ /* BRIGHT_CYAN */
147
+ ]: [96, "55ffff"],
148
+ [
149
+ "brightWhite"
150
+ /* BRIGHT_WHITE */
151
+ ]: [97, "ffffff"],
152
+ [
153
+ "bgBlack"
154
+ /* BG_BLACK */
155
+ ]: [40, "000000"],
156
+ [
157
+ "bgRed"
158
+ /* BG_RED */
159
+ ]: [41, "ff0000"],
160
+ [
161
+ "bgGreen"
162
+ /* BG_GREEN */
163
+ ]: [42, "00ff00"],
164
+ [
165
+ "bgYellow"
166
+ /* BG_YELLOW */
167
+ ]: [43, "ffff00"],
168
+ [
169
+ "bgBlue"
170
+ /* BG_BLUE */
171
+ ]: [44, "0000ff"],
172
+ [
173
+ "bgMagenta"
174
+ /* BG_MAGENTA */
175
+ ]: [45, "ff00ff"],
176
+ [
177
+ "bgCyan"
178
+ /* BG_CYAN */
179
+ ]: [46, "00ffff"],
180
+ [
181
+ "bgWhite"
182
+ /* BG_WHITE */
183
+ ]: [47, "ffffff"],
184
+ [
185
+ "bgGray"
186
+ /* BG_GRAY */
187
+ ]: [100, "808080"],
188
+ [
189
+ "bgBrightRed"
190
+ /* BG_BRIGHT_RED */
191
+ ]: [101, "ff8888"],
192
+ [
193
+ "bgBrightGreen"
194
+ /* BG_BRIGHT_GREEN */
195
+ ]: [102, "88ff88"],
196
+ [
197
+ "bgBrightYellow"
198
+ /* BG_BRIGHT_YELLOW */
199
+ ]: [103, "ffff88"],
200
+ [
201
+ "bgBrightBlue"
202
+ /* BG_BRIGHT_BLUE */
203
+ ]: [104, "8888ff"],
204
+ [
205
+ "bgBrightMagenta"
206
+ /* BG_BRIGHT_MAGENTA */
207
+ ]: [105, "ff88ff"],
208
+ [
209
+ "bgBrightCyan"
210
+ /* BG_BRIGHT_CYAN */
211
+ ]: [106, "88ffff"],
212
+ [
213
+ "bgBrightWhite"
214
+ /* BG_BRIGHT_WHITE */
215
+ ]: [107, "ffffff"]
216
+ };
217
+ function getColors(format = "ansi") {
218
+ const colors = {};
219
+ for (const [name, [ansiCode, hexCode]] of Object.entries(colorMap)) {
220
+ colors[name] = format === "html" ? "#" + hexCode : "\x1B[" + ansiCode + "m";
221
+ }
222
+ return colors;
223
+ }
224
+ function getColorForType(value) {
225
+ const colors = getColors();
226
+ if (typeof value === "string") return colors.yellow;
227
+ if (typeof value === "number") return colors.cyan;
228
+ if (typeof value === "boolean") return colors.magenta;
229
+ if (typeof value === "function") return colors.red;
230
+ if (value === null) return colors.gray;
231
+ if (Array.isArray(value)) return colors.blue;
232
+ if (typeof value === "object") return colors.green;
233
+ return colors.white;
234
+ }
235
+ function getTypeString(value) {
236
+ if (typeof value === "string") return '""';
237
+ if (typeof value === "number") return "number";
238
+ if (typeof value === "boolean") return "bool";
239
+ if (typeof value === "function") return "function";
240
+ if (value === null) return "null";
241
+ if (Array.isArray(value)) {
242
+ if (value.length) return "[" + getTypeString(value[0]) + "]";
243
+ else return "[]";
244
+ }
245
+ if (typeof value === "object") return "{...}";
246
+ return typeof value;
247
+ }
248
+ function printJSONStructure(obj, indent = 0, colorFormat = "ansi") {
249
+ const colors = getColors(colorFormat);
250
+ const pad = " ".repeat(indent);
251
+ var result = "";
252
+ if (typeof obj !== "object" || obj === null) {
253
+ const color = getColorForType(obj);
254
+ return color + getTypeString(obj) + colors.reset;
255
+ }
256
+ if (Array.isArray(obj)) {
257
+ result = colors.blue + "[" + colors.reset;
258
+ if (obj.length) result += "\n";
259
+ if (obj.every((item) => typeof item === typeof obj[0])) {
260
+ result += pad + " " + printJSONStructure(obj[0], indent + 1);
261
+ result += ",";
262
+ result += "\n";
263
+ } else {
264
+ obj.forEach((item, idx) => {
265
+ result += pad + " " + printJSONStructure(item, indent + 1);
266
+ if (idx < obj.length - 1) result += ",";
267
+ result += "\n";
268
+ });
269
+ result += pad + colors.blue + "]" + colors.reset;
270
+ return result;
271
+ }
272
+ }
273
+ result = colors.green + "{" + colors.reset;
274
+ const keys = Object.keys(obj);
275
+ if (keys.length) result += "\n";
276
+ keys.forEach((key, index) => {
277
+ const value = obj[key];
278
+ const color = getColorForType(value);
279
+ result += pad + " ";
280
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
281
+ result += color + key + colors.reset + ": " + printJSONStructure(value, indent + 1);
282
+ } else if (Array.isArray(value)) {
283
+ result += color + key + colors.reset + ": " + printJSONStructure(value, indent + 1);
284
+ } else {
285
+ result += color + key + ": " + getTypeString(value) + colors.reset;
286
+ }
287
+ if (index < keys.length - 1) result += ",";
288
+ result += "\n";
289
+ });
290
+ result += pad + colors.green + "}" + colors.reset;
291
+ return result;
292
+ }
293
+ export {
294
+ ColorName,
295
+ getColors,
296
+ log,
297
+ printJSONStructure
298
+ };
299
+ //# sourceMappingURL=log.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.es.js","sources":["../src/log-json.ts"],"sourcesContent":["/**\n * ### Colorized Log With JSON Structure\n * ![Debug log](https://i.imgur.com/R8Qp6Vg.png)\n * Logs messages to the console with custom styling,\n * prints JSON with description of structure layout,\n * and showing debug output in development only.\n * @param {string|object} message - The message to log. If an object is provided, it will be stringified.\n * @param {string|string[]} [options.style] default='color: blue; font-size: 11pt;' - CSS style string\n * @param {boolean} [options.hideInProduction] - default = auto-detects based on hostname.\n * If true, uses `console.debug` (hidden in production). If false, uses `console.log`.\n *\n */\nexport function log(message: string|object = \"\", options: LogOptions = {}) {\n let {\n color,\n style = \"color:rgb(54, 165, 220); font-size: 10pt;\",\n hideInProduction = undefined,\n startSpinner = false,\n stopSpinner = false,\n } = options;\n const colors = getColors();\n\n // Auto-detect if we should hide logs in production based on hostname\n if (typeof hideInProduction === \"undefined\")\n hideInProduction =\n typeof window !== \"undefined\" &&\n window?.location.hostname.includes(\"localhost\");\n\n // For objects, print both the structure visualization and full JSON\n if (typeof message === \"object\")\n message =\n printJSONStructure(message) + \"\\n\\n\" + JSON.stringify(message, null, 2);\n\n // change color: [red] to color: red if only one\n if (Array.isArray(color) && color.length == 1) color = color[0];\n\n //colorize in terminal (%c is only in browser but we polyfill it)\n if (color && typeof process !== undefined)\n if (message.includes(\"%c\") && Array.isArray(color)) // replace each c with color[i]\n message = message.replace(/%c/g, (match, index) => colors[color[index]] || \"\");\n else if (color && typeof color === \"string\")\n message = (colors[color] || \"\") + message + colors.reset;\n\n\n\n // Displays an animated spinner in the terminal with the provided text.\n var i = 0;\n\n if (startSpinner)\n (global || globalThis).interval = setInterval(() => {\n process.stdout.write(\n (Array.isArray(color) ? colors[color[0]] : colors[color] || \"\") +\n \"\\r\" +\n \"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏\".split(\"\")[(i = ++i % 10)] +\n \" \" +\n message +\n colors.reset\n );\n }, 50);\n else if (stopSpinner) {\n clearInterval((global || globalThis).interval);\n process.stdout.write(\n \"\\r\" + (message || \" \") + \" \".repeat(message.length + 20) + \"\\n\"\n );\n } else if (typeof style === \"string\") {\n // check if style is a one word color code or named color\n //test if style is valid as a CSS color name\n if (style.split(\" \").length == 1 || color) {\n style = `color: ${color || style}; font-size: 11pt;`;\n } else {\n // check if style is valid as a CSS color code\n if (style.match(/^#[0-9a-fA-F]{6}$/)) {\n style = `color: ${style}; font-size: 11pt;`;\n }\n }\n // Use console.debug for production-hidden logs, console.log otherwise\n if (hideInProduction)\n console.debug((style ? \"%c\" : \"\") + (message || \"\"), style);\n else console.log((style ? \"%c\" : \"\") + (message || \"\"), style);\n } else if (typeof style === \"object\") console.log(message, ...(style as any));\n return true;\n}\n\nexport interface LogOptions {\n /** CSS style string or array of CSS strings for browser console styling */\n style?: string | string[];\n /** Optional color name or code for terminal environments */\n color?: ColorName | ColorName[] | string | string[] ;\n /** If true, hides log in production (auto-detects by hostname if undefined) */\n hideInProduction?: boolean;\n /** Start a spinner (for CLI tools, optional) */\n startSpinner?: boolean;\n /** Stop a spinner (for CLI tools, optional) */\n stopSpinner?: boolean;\n}\n\n/**\n * Available color names\n */\nexport enum ColorName {\n RESET = 'reset',\n BLACK = 'black',\n RED = 'red',\n GREEN = 'green',\n YELLOW = 'yellow',\n BLUE = 'blue',\n MAGENTA = 'magenta',\n CYAN = 'cyan',\n WHITE = 'white',\n GRAY = 'gray',\n BRIGHT_RED = 'brightRed',\n BRIGHT_GREEN = 'brightGreen',\n BRIGHT_YELLOW = 'brightYellow',\n BRIGHT_BLUE = 'brightBlue',\n BRIGHT_MAGENTA = 'brightMagenta',\n BRIGHT_CYAN = 'brightCyan',\n BRIGHT_WHITE = 'brightWhite',\n BG_RED = 'bgRed',\n BG_GREEN = 'bgGreen',\n BG_YELLOW = 'bgYellow',\n BG_BLUE = 'bgBlue',\n BG_MAGENTA = 'bgMagenta',\n BG_CYAN = 'bgCyan',\n BG_WHITE = 'bgWhite',\n BG_GRAY = 'bgGray',\n BG_BLACK = 'bgBlack',\n BG_BRIGHT_RED = 'bgBrightRed',\n BG_BRIGHT_GREEN = 'bgBrightGreen',\n BG_BRIGHT_YELLOW = 'bgBrightYellow',\n BG_BRIGHT_BLUE = 'bgBrightBlue',\n BG_BRIGHT_MAGENTA = 'bgBrightMagenta',\n BG_BRIGHT_CYAN = 'bgBrightCyan',\n BG_BRIGHT_WHITE = 'bgBrightWhite',\n}\n\n/**\n * Color mapping with ANSI codes and HTML hex values\n * @type {Record<ColorName, [number, string]>}\n * @description Maps color names to [ansiCode, hexValue] pairs\n * - ansiCode: ANSI escape sequence number for terminal colors\n * - hexValue: Hex color value (without #) for HTML/CSS\n */\nconst colorMap: Record<ColorName, [number, string]> = {\n [ColorName.RESET]: [0, '000000'],\n [ColorName.BLACK]: [30, '000000'],\n [ColorName.RED]: [31, 'ff0000'],\n [ColorName.GREEN]: [32, '00ff00'],\n [ColorName.YELLOW]: [33, 'ffff00'],\n [ColorName.BLUE]: [34, '0000ff'],\n [ColorName.MAGENTA]: [35, 'ff00ff'],\n [ColorName.CYAN]: [36, '00ffff'],\n [ColorName.WHITE]: [37, 'ffffff'],\n [ColorName.GRAY]: [90, '808080'],\n [ColorName.BRIGHT_RED]: [91, 'ff5555'],\n [ColorName.BRIGHT_GREEN]: [92, '55ff55'],\n [ColorName.BRIGHT_YELLOW]: [93, 'ffff55'],\n [ColorName.BRIGHT_BLUE]: [94, '5555ff'],\n [ColorName.BRIGHT_MAGENTA]: [95, 'ff55ff'],\n [ColorName.BRIGHT_CYAN]: [96, '55ffff'],\n [ColorName.BRIGHT_WHITE]: [97, 'ffffff'],\n [ColorName.BG_BLACK]: [40, '000000'],\n [ColorName.BG_RED]: [41, 'ff0000'],\n [ColorName.BG_GREEN]: [42, '00ff00'],\n [ColorName.BG_YELLOW]: [43, 'ffff00'],\n [ColorName.BG_BLUE]: [44, '0000ff'],\n [ColorName.BG_MAGENTA]: [45, 'ff00ff'],\n [ColorName.BG_CYAN]: [46, '00ffff'],\n [ColorName.BG_WHITE]: [47, 'ffffff'],\n [ColorName.BG_GRAY]: [100, '808080'],\n [ColorName.BG_BRIGHT_RED]: [101, 'ff8888'],\n [ColorName.BG_BRIGHT_GREEN]: [102, '88ff88'],\n [ColorName.BG_BRIGHT_YELLOW]: [103, 'ffff88'],\n [ColorName.BG_BRIGHT_BLUE]: [104, '8888ff'],\n [ColorName.BG_BRIGHT_MAGENTA]: [105, 'ff88ff'],\n [ColorName.BG_BRIGHT_CYAN]: [106, '88ffff'],\n [ColorName.BG_BRIGHT_WHITE]: [107, 'ffffff'],\n};\n\n/**\n * Returns color codes based on the specified format\n * @param format - Output format for colors\n * - 'ansi': Returns ANSI escape codes (e.g., '\\x1b[31m')\n * - 'html': Returns HTML hex colors (e.g., '#ff0000')\n * @returns Object with color names as keys and color codes as values\n */\nexport function getColors(format: 'html' | 'ansi' = 'ansi'): Record<ColorName, string> {\n const colors: Record<ColorName, string> = {} as Record<ColorName, string>;\n for (const [name, [ansiCode, hexCode]] of Object.entries(colorMap)) {\n colors[name] = format === 'html' ? '#' + hexCode : '\\x1b[' + ansiCode + 'm';\n }\n return colors;\n}\n\n/**\n * Determines the appropriate color code for a given value type\n * Used for consistent color coding in the structure visualization\n */\nfunction getColorForType(value) {\n const colors = getColors();\n if (typeof value === \"string\") return colors.yellow;\n if (typeof value === \"number\") return colors.cyan;\n if (typeof value === \"boolean\") return colors.magenta;\n if (typeof value === \"function\") return colors.red;\n if (value === null) return colors.gray;\n if (Array.isArray(value)) return colors.blue;\n if (typeof value === \"object\") return colors.green;\n return colors.white;\n}\n\n/**\n * Returns a string representation of the value's type\n * Used to show simplified type information in the structure visualization\n */\nfunction getTypeString(value) {\n if (typeof value === \"string\") return '\"\"';\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"bool\";\n if (typeof value === \"function\") return \"function\";\n if (value === null) return \"null\";\n if (Array.isArray(value)) {\n if (value.length) return \"[\" + getTypeString(value[0]) + \"]\";\n else return \"[]\";\n }\n if (typeof value === \"object\") return \"{...}\";\n return typeof value;\n}\n\n/**\n * Creates a colored visualization of a JSON object's structure\n * Shows the shape and types of the data rather than actual values\n * Recursively processes nested objects and arrays\n * @param {object} obj - The JSON object to visualize\n * @param {number} indent - The number of spaces to indent the object\n * @param {ColorFormat} colorFormat - The color format to use\n * @returns {string} The colored visualization of the JSON object\n */\nexport function printJSONStructure(obj, indent = 0, colorFormat: 'html' | 'ansi' = 'ansi') {\n const colors = getColors(colorFormat);\n const pad = \" \".repeat(indent);\n var result = \"\";\n // Handle primitive values and null\n if (typeof obj !== \"object\" || obj === null) {\n const color = getColorForType(obj);\n return color + getTypeString(obj) + colors.reset;\n }\n // Handle arrays with special bracket formatting\n if (Array.isArray(obj)) {\n result = colors.blue + \"[\" + colors.reset;\n if (obj.length) result += \"\\n\";\n // if array has items all of the same type or object types, print only once\n if (obj.every((item) => typeof item === typeof obj[0])) {\n result += pad + \" \" + printJSONStructure(obj[0], indent + 1);\n result += \",\";\n result += \"\\n\";\n } else {\n obj.forEach((item, idx) => {\n result += pad + \" \" + printJSONStructure(item, indent + 1);\n if (idx < obj.length - 1) result += \",\";\n result += \"\\n\";\n });\n result += pad + colors.blue + \"]\" + colors.reset;\n return result;\n }\n }\n\n // Handle objects with special brace and property formatting\n result = colors.green + \"{\" + colors.reset;\n const keys = Object.keys(obj);\n if (keys.length) result += \"\\n\";\n keys.forEach((key, index) => {\n const value = obj[key];\n const color = getColorForType(value);\n result += pad + \" \";\n\n // Handle nested objects recursively\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n result +=\n color +\n key +\n colors.reset +\n \": \" +\n printJSONStructure(value, indent + 1);\n }\n // Handle nested arrays recursively\n else if (Array.isArray(value)) {\n result +=\n color +\n key +\n colors.reset +\n \": \" +\n printJSONStructure(value, indent + 1);\n }\n // Handle primitive values\n else {\n result += color + key + \": \" + getTypeString(value) + colors.reset;\n }\n if (index < keys.length - 1) result += \",\";\n result += \"\\n\";\n });\n result += pad + colors.green + \"}\" + colors.reset;\n\n // Only log at top level of recursion\n if (indent === 0) {\n // console.log(result);\n }\n return result;\n}\n\n"],"names":["ColorName"],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "grab-url",
3
3
  "description": "📥 Generate Request to API from Browser",
4
4
  "type": "module",
5
- "version": "1.0.7",
5
+ "version": "1.0.8",
6
6
  "author": "vtempest",
7
7
  "license": "rights.institute/prosper",
8
8
  "repository": {
@@ -30,6 +30,11 @@
30
30
  "types": "./dist/*.d.ts",
31
31
  "import": "./dist/*.js",
32
32
  "require": "./dist/*.js"
33
+ },
34
+ "./log": {
35
+ "types": "./dist/log.d.ts",
36
+ "import": "./dist/log.es.js",
37
+ "require": "./dist/log.cjs.js"
33
38
  }
34
39
  },
35
40
  "files": [
@@ -40,23 +45,23 @@
40
45
  "src/icons/cli/spinners.json"
41
46
  ],
42
47
  "scripts": {
43
- "down": "bun test command.test.js",
48
+ "down": "bun src/grab-url.js https://releases.ubuntu.com/24.04.2/ubuntu-24.04.2-live-server-amd64.iso",
44
49
  "make": "npm run make:icons; npm run make:docs; npm run make:main",
45
50
  "make:docs": "cd docs && npm run build",
46
51
  "make:icons": "npx export-svg-typescript@latest -i ./src/icons/svg -o ./src/icons/svg/index.ts",
47
52
  "make:main": "vite build",
48
- "ship": "npx standard-version --release-as patch; npm publish",
53
+ "ship": "bun x standard-version --release-as patch; npm publish",
49
54
  "check": "vitest --ui",
50
55
  "docs": "cd docs && npm run start"
51
56
  },
52
57
  "devDependencies": {
53
- "@vitest/ui": "^3.1.4",
54
- "export-svg-typescript": "^0.1.6",
55
- "terser": "^5.40.0",
56
- "typescript": "^5.8.3",
57
- "vite": "^6.3.5",
58
+ "@vitest/ui": "^3.2.4",
59
+ "export-svg-typescript": "^0.1.15",
60
+ "terser": "^5.44.0",
61
+ "typescript": "^5.9.2",
62
+ "vite": "^7.1.6",
58
63
  "vite-plugin-dts": "^4.5.4",
59
- "vitest": "^3.1.4"
64
+ "vitest": "^3.2.4"
60
65
  },
61
66
  "keywords": [
62
67
  "api",
@@ -71,11 +76,10 @@
71
76
  "http"
72
77
  ],
73
78
  "dependencies": {
74
- "@types/node": "^24.2.1",
75
- "chalk": "^5.4.1",
79
+ "chalk": "^5.6.2",
76
80
  "cli-progress": "^3.12.0",
77
- "cli-spinners": "^3.2.0",
81
+ "cli-spinners": "^3.2.1",
78
82
  "cli-table3": "^0.6.5",
79
- "ora": "^8.2.0"
83
+ "ora": "^9.0.0"
80
84
  }
81
85
  }
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  <p align="center">
3
- <img width="400px" src="https://i.imgur.com/qrQWkeb.png" />
3
+ <img width="400px" src="https://i.imgur.com/xWD7gyV.png" />
4
4
  </p>
5
5
 
6
6
  <p align="center">
@@ -16,7 +16,7 @@
16
16
  </p>
17
17
  <h3 align="center">
18
18
  <a href="https://grab.js.org"> 📑 Docs (grab.js.org)</a>
19
- <a href="https://grab.js.org/guide/Examples"> 🎯 Example Strategies </a>
19
+ <a href="https://grab.js.org/docs/Examples"> 🎯 Example Strategies </a>
20
20
  </h3>
21
21
 
22
22
  ```
@@ -25,7 +25,7 @@ npm i grab-url
25
25
 
26
26
  ### GRAB: Generate Request to API from Browser
27
27
 
28
- 1. **GRAB is the FBEST Request Manager: Functionally Brilliant, Elegantly Simple Tool**: One Function, no dependencies, minimalist syntax, [more features than alternatives](https://grab.js.org/guide/Comparisons)
28
+ 1. **GRAB is the FBEST Request Manager: Functionally Brilliant, Elegantly Simple Tool**: One Function, no dependencies, minimalist syntax, [more features than alternatives](https://grab.js.org/docs/Comparisons)
29
29
  2. **Auto-JSON Convert**: Pass parameters and get response or error in JSON, handling other data types as is.
30
30
  3. **isLoading Status**: Sets `.isLoading=true` on the pre-initialized response object so you can show a "Loading..." in any framework
31
31
  4. **Debug Logging**: Adds global `log()` and prints colored JSON structure, response, timing for requests in test.
@@ -41,7 +41,7 @@ npm i grab-url
41
41
  14. **Framework Agnostic**: Alternatives like TanStack work only in component initialization and depend on React & others.
42
42
  15. **Globals**: Adds to window in browser or global in Node.js so you only import once: `grab()`, `log()`, `grab.log`, `grab.mock`, `grab.defaults`
43
43
  16. **TypeScript Tooltips**: Developers can hover over option names and autocomplete TypeScript.
44
- 17. **Request Stategies**: [🎯 Examples](https://grab.js.org/guide/Examples) show common stategies like debounce, repeat, proxy, unit tests, interceptors, file upload, etc
44
+ 17. **Request Stategies**: [🎯 Examples](https://grab.js.org/docs/Examples) show common stategies like debounce, repeat, proxy, unit tests, interceptors, file upload, etc
45
45
  18. **Rate Limiting**: Built-in rate limiting to prevent multi-click cascading responses, require to wait seconds between requests.
46
46
  19. **Repeat**: Repeat request this many times, or repeat every X seconds to poll for updates.
47
47
  20. **Loading Icons**: Import from `grab-url/icons` to get enhanced animated loading icons.
@@ -119,11 +119,11 @@ grab('user').then(log)
119
119
  ![Info Tooltip](https://i.imgur.com/vV5jbZo.png)
120
120
 
121
121
 
122
- ### Comparison of HTTP Request Libraries
122
+ ## Comparison of HTTP Request Libraries
123
123
 
124
124
  | Feature | [GRAB](https://github.com/vtempest/GRAB-URL) | [Axios](https://github.com/axios/axios) | [TanStack Query](https://github.com/TanStack/query) | [SWR](https://github.com/vercel/swr) | [Alova](https://github.com/alovajs/alova) | [SuperAgent](https://github.com/ladjs/superagent) | [Apisauce](https://github.com/infinitered/apisauce) | [Ky](https://github.com/sindresorhus/ky) |
125
125
  | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- |
126
- | Size | ✅ 3KB | ❌ 13KB | ❌ 39KB | 4.2KB | ⚠️ 4KB | ❌ 19KB | ❌ 15KB (with axios) | ⚠️ 4KB |
126
+ | Size | ✅ 4KB | ❌ 13KB | ❌ 39KB | 4.2KB | 4KB | ❌ 19KB | ❌ 15KB (with axios) | 4KB |
127
127
  | Zero Dependencies | ✅ Yes | ❌ No | ❌ No | ❌ No | ✅ Yes | ❌ No | ❌ Needs Axios | ✅ Yes |
128
128
  | isLoading State Handling | ✅ Auto-managed | ❌ Manual | ✅ Yes | ✅ Yes | ✅ Yes | ❌ Manual | ❌ Manual | ❌ Manual |
129
129
  | Auto JSON Handling | ✅ Automatic | ✅ Configurable | ❌ Manual | ❌ Manual | ✅ Automatic | ✅ Automatic | ✅ Automatic | ✅ Automatic |
@@ -144,7 +144,7 @@ grab('user').then(log)
144
144
 
145
145
  **Why fetch things when you can just GRAB?**
146
146
 
147
- **Debugging requests is a bitch. [Make the switch!](https://grab.js.org/guide/Comparisons)**
147
+ **Debugging requests is a bitch. [Make the switch!](https://grab.js.org/docs/Comparisons)**
148
148
 
149
149
 
150
150
  🌟 Star this repo so it will grow and get updates!