image-exporter 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -50,7 +50,7 @@ import { capture } from "image-exporter";
50
50
  /** Default label for images. Does not include file extension or scale. */
51
51
  defaultImageLabel: string;
52
52
  /** Label for zip file. Does not include file extension or scale. */
53
- zipLabel: Label;
53
+ zipLabel: string;
54
54
  /** Base URL for CORS proxy used when fetching external images. */
55
55
  corsProxyBaseUrl: string;
56
56
  /** Enable window logging for use by external scripts */
@@ -3338,7 +3338,11 @@ const log = {
3338
3338
  info: (...messages) => logAction(messages, "info"),
3339
3339
  error: (...messages) => logAction(messages, "error"),
3340
3340
  verbose: (...messages) => logAction(messages, "verbose"),
3341
- progress: (progress, total) => logProgress(progress, total)
3341
+ progress: (progress, total) => logProgress(progress, total),
3342
+ group: {
3343
+ open: (...messages) => logAction(messages, "group"),
3344
+ close: (...messages) => logAction(messages, "groupEnd")
3345
+ }
3342
3346
  };
3343
3347
  async function logAction(messages, type = "info") {
3344
3348
  const combinedMessage = messages.map((msg) => typeof msg === "object" ? JSON.stringify(msg) : msg).join(" ");
@@ -3358,6 +3362,12 @@ async function logAction(messages, type = "info") {
3358
3362
  console.log(...messages);
3359
3363
  }
3360
3364
  break;
3365
+ case "group":
3366
+ console.group(...messages);
3367
+ break;
3368
+ case "groupEnd":
3369
+ console.groupEnd();
3370
+ break;
3361
3371
  }
3362
3372
  if (windowLogging) window.imageExporterLogs.push({ message: combinedMessage, type });
3363
3373
  }
@@ -3396,13 +3406,6 @@ async function proxyCSS(config) {
3396
3406
  try {
3397
3407
  const response = await fetch(proxiedURL);
3398
3408
  let cssContent = await response.text();
3399
- cssContent = cssContent.replace(
3400
- /url\(['"]?(https?:\/\/[^'")\s]+)['"]?\)/g,
3401
- (match, url) => {
3402
- if (url.startsWith(config.corsProxyBaseUrl)) return match;
3403
- return `url("${config.corsProxyBaseUrl}${encodeURIComponent(url)}")`;
3404
- }
3405
- );
3406
3409
  const styleElement = document.createElement("style");
3407
3410
  styleElement.textContent = cssContent;
3408
3411
  styleElement.setAttribute(
@@ -3645,6 +3648,7 @@ async function determineTotalElements(elements) {
3645
3648
  let windowLogging = true;
3646
3649
  let loggingLevel = "none";
3647
3650
  async function capture(elements, userConfig = defaultConfig) {
3651
+ log.group.open("image-exporter");
3648
3652
  try {
3649
3653
  const config = { ...defaultConfig, ...userConfig };
3650
3654
  windowLogging = config.enableWindowLogging;
@@ -3656,19 +3660,19 @@ async function capture(elements, userConfig = defaultConfig) {
3656
3660
  const totalElements = await determineTotalElements(elements);
3657
3661
  if (originalLength !== elements.length)
3658
3662
  log.verbose(
3659
- "skipping capture of hidden elements: ",
3663
+ "Skipping capture of hidden elements: ",
3660
3664
  originalLength - elements.length
3661
3665
  );
3662
- log.verbose("element to capture", elements.length);
3666
+ log.verbose("Element to capture", elements.length);
3663
3667
  if (userConfig.corsProxyBaseUrl) await corsProxy.run(config, elements);
3664
3668
  let images = [];
3665
3669
  let filenames = [];
3666
3670
  let imageNumber = 1;
3667
3671
  for (const element of elements) {
3668
3672
  const imageOptions = await getImageOptions(element, config);
3669
- log.verbose("image options", imageOptions);
3673
+ log.verbose("Image options", imageOptions);
3670
3674
  if (imageOptions.scale instanceof Array) {
3671
- log.verbose("multi-scale capture");
3675
+ log.verbose("Multi-scale capture");
3672
3676
  imageOptions.includeScaleInLabel = true;
3673
3677
  for (const scale of imageOptions.scale) {
3674
3678
  log.progress(imageNumber++, totalElements);
@@ -3681,7 +3685,7 @@ async function capture(elements, userConfig = defaultConfig) {
3681
3685
  }
3682
3686
  } else if (typeof imageOptions.scale === "number") {
3683
3687
  log.progress(imageNumber++, totalElements);
3684
- log.verbose("single-scale capture");
3688
+ log.verbose("Single-scale capture");
3685
3689
  const image = await captureElement(
3686
3690
  element,
3687
3691
  imageOptions,
@@ -3690,12 +3694,14 @@ async function capture(elements, userConfig = defaultConfig) {
3690
3694
  images.push(image);
3691
3695
  }
3692
3696
  }
3693
- if (userConfig.downloadImages) downloadImages(images, config);
3697
+ if (userConfig.downloadImages) await downloadImages(images, config);
3694
3698
  if (userConfig.corsProxyBaseUrl) await corsProxy.cleanUp();
3695
3699
  return images;
3696
3700
  } catch (error) {
3697
3701
  log.error(error);
3698
3702
  return null;
3703
+ } finally {
3704
+ log.group.close();
3699
3705
  }
3700
3706
  }
3701
3707
  if (typeof window !== "undefined") {
@@ -3343,7 +3343,11 @@
3343
3343
  info: (...messages) => logAction(messages, "info"),
3344
3344
  error: (...messages) => logAction(messages, "error"),
3345
3345
  verbose: (...messages) => logAction(messages, "verbose"),
3346
- progress: (progress, total) => logProgress(progress, total)
3346
+ progress: (progress, total) => logProgress(progress, total),
3347
+ group: {
3348
+ open: (...messages) => logAction(messages, "group"),
3349
+ close: (...messages) => logAction(messages, "groupEnd")
3350
+ }
3347
3351
  };
3348
3352
  async function logAction(messages, type = "info") {
3349
3353
  const combinedMessage = messages.map((msg) => typeof msg === "object" ? JSON.stringify(msg) : msg).join(" ");
@@ -3363,6 +3367,12 @@
3363
3367
  console.log(...messages);
3364
3368
  }
3365
3369
  break;
3370
+ case "group":
3371
+ console.group(...messages);
3372
+ break;
3373
+ case "groupEnd":
3374
+ console.groupEnd();
3375
+ break;
3366
3376
  }
3367
3377
  if (windowLogging) window.imageExporterLogs.push({ message: combinedMessage, type });
3368
3378
  }
@@ -3401,13 +3411,6 @@
3401
3411
  try {
3402
3412
  const response = await fetch(proxiedURL);
3403
3413
  let cssContent = await response.text();
3404
- cssContent = cssContent.replace(
3405
- /url\(['"]?(https?:\/\/[^'")\s]+)['"]?\)/g,
3406
- (match, url) => {
3407
- if (url.startsWith(config.corsProxyBaseUrl)) return match;
3408
- return `url("${config.corsProxyBaseUrl}${encodeURIComponent(url)}")`;
3409
- }
3410
- );
3411
3414
  const styleElement = document.createElement("style");
3412
3415
  styleElement.textContent = cssContent;
3413
3416
  styleElement.setAttribute(
@@ -3650,6 +3653,7 @@
3650
3653
  let windowLogging = true;
3651
3654
  let loggingLevel = "none";
3652
3655
  async function capture(elements, userConfig = defaultConfig) {
3656
+ log.group.open("image-exporter");
3653
3657
  try {
3654
3658
  const config = { ...defaultConfig, ...userConfig };
3655
3659
  windowLogging = config.enableWindowLogging;
@@ -3661,19 +3665,19 @@
3661
3665
  const totalElements = await determineTotalElements(elements);
3662
3666
  if (originalLength !== elements.length)
3663
3667
  log.verbose(
3664
- "skipping capture of hidden elements: ",
3668
+ "Skipping capture of hidden elements: ",
3665
3669
  originalLength - elements.length
3666
3670
  );
3667
- log.verbose("element to capture", elements.length);
3671
+ log.verbose("Element to capture", elements.length);
3668
3672
  if (userConfig.corsProxyBaseUrl) await corsProxy.run(config, elements);
3669
3673
  let images = [];
3670
3674
  let filenames = [];
3671
3675
  let imageNumber = 1;
3672
3676
  for (const element of elements) {
3673
3677
  const imageOptions = await getImageOptions(element, config);
3674
- log.verbose("image options", imageOptions);
3678
+ log.verbose("Image options", imageOptions);
3675
3679
  if (imageOptions.scale instanceof Array) {
3676
- log.verbose("multi-scale capture");
3680
+ log.verbose("Multi-scale capture");
3677
3681
  imageOptions.includeScaleInLabel = true;
3678
3682
  for (const scale of imageOptions.scale) {
3679
3683
  log.progress(imageNumber++, totalElements);
@@ -3686,7 +3690,7 @@
3686
3690
  }
3687
3691
  } else if (typeof imageOptions.scale === "number") {
3688
3692
  log.progress(imageNumber++, totalElements);
3689
- log.verbose("single-scale capture");
3693
+ log.verbose("Single-scale capture");
3690
3694
  const image = await captureElement(
3691
3695
  element,
3692
3696
  imageOptions,
@@ -3695,12 +3699,14 @@
3695
3699
  images.push(image);
3696
3700
  }
3697
3701
  }
3698
- if (userConfig.downloadImages) downloadImages(images, config);
3702
+ if (userConfig.downloadImages) await downloadImages(images, config);
3699
3703
  if (userConfig.corsProxyBaseUrl) await corsProxy.cleanUp();
3700
3704
  return images;
3701
3705
  } catch (error) {
3702
3706
  log.error(error);
3703
3707
  return null;
3708
+ } finally {
3709
+ log.group.close();
3704
3710
  }
3705
3711
  }
3706
3712
  if (typeof window !== "undefined") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-exporter",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Easily download one or more DOM elements as images",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -2,8 +2,6 @@ import * as htmlToImage from "html-to-image";
2
2
  import { Image, ParsedImageOptions } from "../types";
3
3
  import { handleFileNames } from "./handle-filenames";
4
4
  import { Options } from "html-to-image/lib/types";
5
- import { get } from "http";
6
-
7
5
  /**
8
6
  * captureElement
9
7
  *
@@ -20,6 +20,7 @@ export async function capture(
20
20
  elements: HTMLElement[] | NodeListOf<HTMLElement> | HTMLElement,
21
21
  userConfig: Partial<Config> = defaultConfig
22
22
  ): Promise<Image[] | null> {
23
+ log.group.open("image-exporter");
23
24
  try {
24
25
  /* --------------------------------- Config --------------------------------- */
25
26
  const config = { ...defaultConfig, ...userConfig };
@@ -36,10 +37,10 @@ export async function capture(
36
37
 
37
38
  if (originalLength !== elements.length)
38
39
  log.verbose(
39
- "skipping capture of hidden elements: ",
40
+ "Skipping capture of hidden elements: ",
40
41
  originalLength - elements.length
41
42
  );
42
- log.verbose("element to capture", elements.length);
43
+ log.verbose("Element to capture", elements.length);
43
44
 
44
45
  /* ------------------------------- CORS proxy ------------------------------- */
45
46
  if (userConfig.corsProxyBaseUrl) await corsProxy.run(config, elements);
@@ -51,11 +52,11 @@ export async function capture(
51
52
 
52
53
  for (const element of elements) {
53
54
  const imageOptions = await getImageOptions(element, config);
54
- log.verbose("image options", imageOptions);
55
+ log.verbose("Image options", imageOptions);
55
56
 
56
57
  if (imageOptions.scale instanceof Array) {
57
58
  /* --------------------------- Multi-scale capture -------------------------- */
58
- log.verbose("multi-scale capture");
59
+ log.verbose("Multi-scale capture");
59
60
 
60
61
  imageOptions.includeScaleInLabel = true;
61
62
 
@@ -72,7 +73,7 @@ export async function capture(
72
73
  } else if (typeof imageOptions.scale === "number") {
73
74
  log.progress(imageNumber++, totalElements);
74
75
  /* -------------------------- Single scale capture -------------------------- */
75
- log.verbose("single-scale capture");
76
+ log.verbose("Single-scale capture");
76
77
 
77
78
  const image = await captureElement(
78
79
  element,
@@ -85,7 +86,7 @@ export async function capture(
85
86
  }
86
87
 
87
88
  /* -------------------------------- Download -------------------------------- */
88
- if (userConfig.downloadImages) downloadImages(images, config);
89
+ if (userConfig.downloadImages) await downloadImages(images, config);
89
90
 
90
91
  /* --------------------------- Clean up CORS proxy -------------------------- */
91
92
  if (userConfig.corsProxyBaseUrl) await corsProxy.cleanUp();
@@ -95,5 +96,7 @@ export async function capture(
95
96
  } catch (error) {
96
97
  log.error(error);
97
98
  return null;
99
+ } finally {
100
+ log.group.close();
98
101
  }
99
102
  }
@@ -29,17 +29,6 @@ export async function proxyCSS(config: Config) {
29
29
  const response = await fetch(proxiedURL);
30
30
  let cssContent = await response.text();
31
31
 
32
- // Proxy absolute URLs (http/https) within the CSS content
33
- cssContent = cssContent.replace(
34
- /url\(['"]?(https?:\/\/[^'")\s]+)['"]?\)/g,
35
- (match, url) => {
36
- // Skip if already proxied
37
- if (url.startsWith(config.corsProxyBaseUrl)) return match;
38
- // Otherwise return proxied URL
39
- return `url("${config.corsProxyBaseUrl}${encodeURIComponent(url)}")`;
40
- }
41
- );
42
-
43
32
  // Insert the parsed CSS content into a <style> element
44
33
  const styleElement = document.createElement("style");
45
34
  styleElement.textContent = cssContent;
package/src/logger.ts CHANGED
@@ -5,6 +5,10 @@ export const log = {
5
5
  error: (...messages: any[]) => logAction(messages, "error"),
6
6
  verbose: (...messages: any[]) => logAction(messages, "verbose"),
7
7
  progress: (progress: number, total: number) => logProgress(progress, total),
8
+ group: {
9
+ open: (...messages: any[]) => logAction(messages, "group"),
10
+ close: (...messages: any[]) => logAction(messages, "groupEnd"),
11
+ },
8
12
  };
9
13
 
10
14
  async function logAction(messages: any[], type: LogType = "info") {
@@ -28,6 +32,12 @@ async function logAction(messages: any[], type: LogType = "info") {
28
32
  console.log(...messages);
29
33
  }
30
34
  break;
35
+ case "group":
36
+ console.group(...messages);
37
+ break;
38
+ case "groupEnd":
39
+ console.groupEnd();
40
+ break;
31
41
  }
32
42
 
33
43
  if (windowLogging) window.imageExporterLogs.push({ message: combinedMessage, type });
@@ -39,7 +49,7 @@ async function logProgress(progress: number, total: number) {
39
49
  }
40
50
  }
41
51
 
42
- type LogType = "info" | "error" | "verbose" | "progress";
52
+ type LogType = "info" | "error" | "verbose" | "progress" | "group" | "groupEnd";
43
53
 
44
54
  type Log = {
45
55
  message: string;