image-exporter 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -81
- package/dist/capture/capture-element.d.ts +8 -0
- package/dist/capture/capture-element.d.ts.map +1 -0
- package/dist/capture/determine-total-elements.d.ts +9 -0
- package/dist/capture/determine-total-elements.d.ts.map +1 -0
- package/dist/capture/download-images.d.ts +10 -0
- package/dist/capture/download-images.d.ts.map +1 -0
- package/dist/capture/get-image-options.d.ts +15 -0
- package/dist/capture/get-image-options.d.ts.map +1 -0
- package/dist/capture/handle-filenames.d.ts +11 -0
- package/dist/capture/handle-filenames.d.ts.map +1 -0
- package/dist/capture/index.d.ts +10 -0
- package/dist/capture/index.d.ts.map +1 -0
- package/dist/capture/remove-hidden-elements.d.ts +2 -0
- package/dist/capture/remove-hidden-elements.d.ts.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/cors-proxy/cleanup.d.ts +7 -0
- package/dist/cors-proxy/cleanup.d.ts.map +1 -0
- package/dist/cors-proxy/index.d.ts +7 -0
- package/dist/cors-proxy/index.d.ts.map +1 -0
- package/dist/cors-proxy/is-valid-url.d.ts +7 -0
- package/dist/cors-proxy/is-valid-url.d.ts.map +1 -0
- package/dist/cors-proxy/proxy-css.d.ts +9 -0
- package/dist/cors-proxy/proxy-css.d.ts.map +1 -0
- package/dist/cors-proxy/proxy-images.d.ts +9 -0
- package/dist/cors-proxy/proxy-images.d.ts.map +1 -0
- package/dist/cors-proxy/run.d.ts +9 -0
- package/dist/cors-proxy/run.d.ts.map +1 -0
- package/dist/index.browser.js +40 -0
- package/dist/index.browser.js.map +84 -0
- package/dist/index.cjs +14878 -0
- package/dist/index.cjs.map +84 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14869 -0
- package/dist/index.js.map +83 -0
- package/dist/logger.d.ts +26 -0
- package/dist/logger.d.ts.map +1 -0
- package/package.json +19 -14
- package/.gitattributes +0 -2
- package/.prettierrc +0 -5
- package/bun.lockb +0 -0
- package/dist/image-exporter.es.js +0 -4508
- package/dist/image-exporter.umd.js +0 -4514
- package/src/capture/capture-element.ts +0 -79
- package/src/capture/determine-total-elements.ts +0 -40
- package/src/capture/download-images.ts +0 -69
- package/src/capture/get-image-options.ts +0 -207
- package/src/capture/handle-filenames.ts +0 -54
- package/src/capture/index.ts +0 -102
- package/src/capture/remove-hidden-elements.ts +0 -19
- package/src/config.ts +0 -19
- package/src/cors-proxy/cleanup.ts +0 -43
- package/src/cors-proxy/index.ts +0 -7
- package/src/cors-proxy/is-valid-url.ts +0 -22
- package/src/cors-proxy/proxy-css.ts +0 -48
- package/src/cors-proxy/proxy-images.ts +0 -34
- package/src/cors-proxy/run.ts +0 -26
- package/src/index.ts +0 -14
- package/src/logger.ts +0 -71
- package/src/types.d.ts +0 -51
- package/vite.config.js +0 -35
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { log } from "../logger";
|
|
2
|
-
import { Config } from "../types";
|
|
3
|
-
import { isValidUrl } from "./is-valid-url";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* proxyCSS
|
|
7
|
-
*
|
|
8
|
-
* Proxies all linked CSS files and the absolute URLs inside them, including fonts and images.
|
|
9
|
-
* Upon completion of capture, the links will be restored and the style elements removed.
|
|
10
|
-
*/
|
|
11
|
-
export async function proxyCSS(config: Config) {
|
|
12
|
-
const stylesheetElements = document.querySelectorAll('link[rel="stylesheet"]');
|
|
13
|
-
log.verbose("stylesheet elements to proxy", stylesheetElements.length);
|
|
14
|
-
|
|
15
|
-
for (let stylesheetElement of stylesheetElements) {
|
|
16
|
-
const stylesheetURL = stylesheetElement.getAttribute("href");
|
|
17
|
-
|
|
18
|
-
// Exclude data URLs, invalid URLs, and already proxied URLs
|
|
19
|
-
if (!stylesheetURL) continue;
|
|
20
|
-
if (stylesheetURL.startsWith("data:")) continue;
|
|
21
|
-
if (stylesheetURL.startsWith(config.corsProxyBaseUrl)) continue;
|
|
22
|
-
if (!isValidUrl(stylesheetURL)) continue;
|
|
23
|
-
|
|
24
|
-
stylesheetElement.setAttribute("crossorigin", "anonymous");
|
|
25
|
-
const proxiedURL = config.corsProxyBaseUrl + encodeURIComponent(stylesheetURL);
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
// Fetch the CSS content
|
|
29
|
-
const response = await fetch(proxiedURL);
|
|
30
|
-
let cssContent = await response.text();
|
|
31
|
-
|
|
32
|
-
// Insert the parsed CSS content into a <style> element
|
|
33
|
-
const styleElement = document.createElement("style");
|
|
34
|
-
styleElement.textContent = cssContent;
|
|
35
|
-
styleElement.setAttribute(
|
|
36
|
-
"original-link-element",
|
|
37
|
-
encodeURIComponent(stylesheetElement.outerHTML)
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
// Insert the <style> element directly after the original <link> element to easy restoration
|
|
41
|
-
stylesheetElement.insertAdjacentElement("afterend", styleElement);
|
|
42
|
-
stylesheetElement.remove();
|
|
43
|
-
log.verbose("Proxied: ", stylesheetURL);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.error("Error fetching CSS:", error);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Config } from "../types";
|
|
2
|
-
import { isValidUrl } from "./is-valid-url";
|
|
3
|
-
import { log } from "../logger";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* proxyImages
|
|
7
|
-
*
|
|
8
|
-
* Proxies all images inside capture elements.
|
|
9
|
-
* The original src is stored for later restoration.
|
|
10
|
-
*/
|
|
11
|
-
export async function proxyImages(
|
|
12
|
-
config: Config,
|
|
13
|
-
elements: HTMLElement[] | NodeListOf<HTMLElement>
|
|
14
|
-
) {
|
|
15
|
-
try {
|
|
16
|
-
const elementArray = Array.from(elements);
|
|
17
|
-
if (!elementArray.length) return;
|
|
18
|
-
log.verbose("images to proxy", elementArray.length);
|
|
19
|
-
|
|
20
|
-
for (const element of elementArray) {
|
|
21
|
-
const images = Array.from(element.querySelectorAll("img")) as HTMLImageElement[];
|
|
22
|
-
for (const img of images) {
|
|
23
|
-
if (isValidUrl(img.src) && !img.src.startsWith(config.corsProxyBaseUrl)) {
|
|
24
|
-
img.setAttribute("original-src", img.src);
|
|
25
|
-
img.src = config.corsProxyBaseUrl + encodeURIComponent(img.src);
|
|
26
|
-
log.verbose("Proxied: ", img.src);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
} catch (e) {
|
|
31
|
-
console.error("ImageExporter: Error in proxyImages", e);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
}
|
package/src/cors-proxy/run.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { proxyCSS } from "./proxy-css";
|
|
2
|
-
import { proxyImages } from "./proxy-images";
|
|
3
|
-
import { Config } from "../types";
|
|
4
|
-
import { isValidUrl } from "./is-valid-url";
|
|
5
|
-
import { log } from "../logger";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* runCorsProxy
|
|
9
|
-
*
|
|
10
|
-
* Proxies all images inside capture elements, as well as all linked CSS files and the absolute URLs inside them.
|
|
11
|
-
* Upon completion of capture, these will be reverted to their original state.
|
|
12
|
-
*/
|
|
13
|
-
export async function runCorsProxy(
|
|
14
|
-
config: Config,
|
|
15
|
-
elements: HTMLElement[] | NodeListOf<HTMLElement>
|
|
16
|
-
): Promise<void> {
|
|
17
|
-
try {
|
|
18
|
-
log.verbose("running CORS proxy");
|
|
19
|
-
if (!config.corsProxyBaseUrl || !isValidUrl(config.corsProxyBaseUrl)) return;
|
|
20
|
-
|
|
21
|
-
await proxyCSS(config);
|
|
22
|
-
await proxyImages(config, elements);
|
|
23
|
-
} catch (e) {
|
|
24
|
-
console.error("ImageExporter: Error in runCorsProxy", e);
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/* -------------------------------------------------------------------------- */
|
|
2
|
-
/* Image Exporter */
|
|
3
|
-
/* */
|
|
4
|
-
/* by briantuckerdesign */
|
|
5
|
-
/* -------------------------------------------------------------------------- */
|
|
6
|
-
import { capture } from "./capture";
|
|
7
|
-
|
|
8
|
-
/** Exports for use in browser */
|
|
9
|
-
if (typeof window !== "undefined") {
|
|
10
|
-
(window as any).imageExporter = capture;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** Exports for use as an imported package */
|
|
14
|
-
export { capture };
|
package/src/logger.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { windowLogging, loggingLevel } from "./capture";
|
|
2
|
-
|
|
3
|
-
export const log = {
|
|
4
|
-
info: (...messages: any[]) => logAction(messages, "info"),
|
|
5
|
-
error: (...messages: any[]) => logAction(messages, "error"),
|
|
6
|
-
verbose: (...messages: any[]) => logAction(messages, "verbose"),
|
|
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
|
-
},
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
async function logAction(messages: any[], type: LogType = "info") {
|
|
15
|
-
const combinedMessage = messages
|
|
16
|
-
.map((msg) => (typeof msg === "object" ? JSON.stringify(msg) : msg))
|
|
17
|
-
.join(" ");
|
|
18
|
-
|
|
19
|
-
switch (type) {
|
|
20
|
-
case "info":
|
|
21
|
-
if (loggingLevel === "info" || loggingLevel === "verbose") {
|
|
22
|
-
console.log(...messages);
|
|
23
|
-
}
|
|
24
|
-
break;
|
|
25
|
-
case "error":
|
|
26
|
-
if (loggingLevel === "error" || loggingLevel === "verbose") {
|
|
27
|
-
console.error(...messages);
|
|
28
|
-
}
|
|
29
|
-
break;
|
|
30
|
-
case "verbose":
|
|
31
|
-
if (loggingLevel === "verbose") {
|
|
32
|
-
console.log(...messages);
|
|
33
|
-
}
|
|
34
|
-
break;
|
|
35
|
-
case "group":
|
|
36
|
-
console.group(...messages);
|
|
37
|
-
break;
|
|
38
|
-
case "groupEnd":
|
|
39
|
-
console.groupEnd();
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (windowLogging) window.imageExporterLogs.push({ message: combinedMessage, type });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function logProgress(progress: number, total: number) {
|
|
47
|
-
if (windowLogging) {
|
|
48
|
-
window.imageExporterProgress.push([progress, total]);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
type LogType = "info" | "error" | "verbose" | "progress" | "group" | "groupEnd";
|
|
53
|
-
|
|
54
|
-
type Log = {
|
|
55
|
-
message: string;
|
|
56
|
-
type: LogType;
|
|
57
|
-
progress?: number;
|
|
58
|
-
total?: number;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
type Progress = [number, number];
|
|
62
|
-
|
|
63
|
-
declare global {
|
|
64
|
-
interface Window {
|
|
65
|
-
imageExporterLogs: Log[];
|
|
66
|
-
imageExporterProgress: Progress[];
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
window.imageExporterLogs = [];
|
|
71
|
-
window.imageExporterProgress = [];
|
package/src/types.d.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export interface ImageOptions {
|
|
2
|
-
/** Label for image. Does not include file extension or scale. */
|
|
3
|
-
label: Label;
|
|
4
|
-
/** File format, jpg, png, or svg. */
|
|
5
|
-
format: Format;
|
|
6
|
-
/** Scale of image. Can be a number or a comma-separated list of numbers. */
|
|
7
|
-
scale: Scale;
|
|
8
|
-
/** Quality of image. 0.0 to 1.0, only applies to jpg.*/
|
|
9
|
-
quality: Quality;
|
|
10
|
-
/** Include scale in label. True or false. Automatically true if scale is an array. */
|
|
11
|
-
includeScaleInLabel: IncludeScaleInLabel;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface Config extends ImageOptions {
|
|
15
|
-
/** Download images as files upon capture. */
|
|
16
|
-
downloadImages: boolean;
|
|
17
|
-
/** Default label for images. Does not include file extension or scale. */
|
|
18
|
-
defaultImageLabel: string;
|
|
19
|
-
/** Label for zip file. Does not include file extension or scale. */
|
|
20
|
-
zipLabel: Label;
|
|
21
|
-
/** Base URL for CORS proxy used when fetching external images.
|
|
22
|
-
*
|
|
23
|
-
* URLs will be encoded and appended without a `?`. Include your own trailing slash.
|
|
24
|
-
*
|
|
25
|
-
* I recommend [cors-proxy-worker](https://github.com/briantuckerdesign/cors-proxy-worker) for production and [local-cors-proxy-encoded](https://github.com/briantuckerdesign/local-cors-proxy-encoded) for development.
|
|
26
|
-
*
|
|
27
|
-
* Example: `https://cors-proxy.com/` -> `https://cors-proxy.com/https%3A%2F%2FmyEncodedUrl.com`
|
|
28
|
-
*/
|
|
29
|
-
corsProxyBaseUrl: string;
|
|
30
|
-
/** Enable window logging for use by external scripts. */
|
|
31
|
-
enableWindowLogging: boolean;
|
|
32
|
-
/** Enable verbose logging for debugging. */
|
|
33
|
-
loggingLevel: LoggingLevel;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface ParsedImageOptions extends ImageOptions {
|
|
37
|
-
/** After parsing, this will always be a number rather than possibly an array. */
|
|
38
|
-
scale: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface Image {
|
|
42
|
-
dataURL: string;
|
|
43
|
-
fileName: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type Label = string;
|
|
47
|
-
export type Format = "jpg" | "png" | "svg" | "webp";
|
|
48
|
-
export type Scale = number | number[];
|
|
49
|
-
export type Quality = number;
|
|
50
|
-
export type IncludeScaleInLabel = boolean;
|
|
51
|
-
export type LoggingLevel = "none" | "info" | "error" | "verbose";
|
package/vite.config.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
environment: "jsdom",
|
|
6
|
-
},
|
|
7
|
-
build: {
|
|
8
|
-
outDir: "dist",
|
|
9
|
-
emptyOutDir: true,
|
|
10
|
-
minify: false,
|
|
11
|
-
lib: {
|
|
12
|
-
entry: "src/index.ts",
|
|
13
|
-
name: "image-exporter",
|
|
14
|
-
fileName: (format) => `image-exporter.${format}.js`,
|
|
15
|
-
},
|
|
16
|
-
rollupOptions: {
|
|
17
|
-
input: "src/index.ts",
|
|
18
|
-
plugins: [
|
|
19
|
-
{
|
|
20
|
-
name: "wrap-in-iife",
|
|
21
|
-
generateBundle(outputOptions, bundle) {
|
|
22
|
-
if (outputOptions.format === "umd") {
|
|
23
|
-
Object.keys(bundle).forEach((fileName) => {
|
|
24
|
-
const file = bundle[fileName];
|
|
25
|
-
if (fileName.slice(-3) === ".js" && "code" in file) {
|
|
26
|
-
file.code = `(() => {\n${file.code}})()`;
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
});
|