frontbacked-svg 5.0.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/LICENSE +191 -0
- package/README.md +41 -0
- package/dist/main.cjs +3785 -0
- package/dist/main.d.cts +316 -0
- package/dist/main.d.ts +316 -0
- package/dist/main.mjs +3681 -0
- package/package.json +103 -0
- package/src/base64Image.ts +101 -0
- package/src/cssParser.ts +59 -0
- package/src/filters.ts +226 -0
- package/src/font-utils.ts +204 -0
- package/src/get-default-fields-value.ts +64 -0
- package/src/getSvg.ts +284 -0
- package/src/imageHelper.ts +293 -0
- package/src/imagePassportUtils.ts +718 -0
- package/src/images-processor.ts +186 -0
- package/src/main.ts +1354 -0
- package/src/polyfills/DOMParser.ts +28 -0
- package/src/polyfills/File.ts +20 -0
- package/src/polyfills/Image.ts +90 -0
- package/src/svgScaler.ts +179 -0
- package/src/textGenCodeParser.ts +319 -0
- package/src/time.ts +147 -0
- package/src/toolsFunc.ts +79 -0
- package/src/types.ts +177 -0
- package/src/utils.ts +758 -0
- package/src/watermaker.ts +190 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { getCanvas } from "./imageHelper.ts";
|
|
2
|
+
import { FileMap, MaskMap } from "./types.ts";
|
|
3
|
+
import { isUploadedFileUrl, setR2Host } from "./utils.ts";
|
|
4
|
+
|
|
5
|
+
const isNode = typeof window === 'undefined';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Fetches the image from a URL and converts it to a base64 string.
|
|
9
|
+
* @param {string} url - The URL of the image to fetch.
|
|
10
|
+
* @returns {Promise<string|null>} - A promise that resolves to the base64 string of the image or null if an error occurs.
|
|
11
|
+
*/
|
|
12
|
+
export const fetchImageForBase64 = async (storageHost: string, url: string, alwaysResolve = false): Promise<string | null> => {
|
|
13
|
+
return new Promise(async (resolve, reject) => {
|
|
14
|
+
if (!isUploadedFileUrl(url)) return resolve(url);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch(setR2Host(url, storageHost));
|
|
18
|
+
const blob = await response.blob();
|
|
19
|
+
|
|
20
|
+
if (typeof window !== "undefined" && typeof FileReader !== "undefined") {
|
|
21
|
+
// Browser Environment: Use FileReader
|
|
22
|
+
const reader = new FileReader();
|
|
23
|
+
reader.onloadend = () => {
|
|
24
|
+
resolve(reader.result as string);
|
|
25
|
+
};
|
|
26
|
+
reader.onerror = reject;
|
|
27
|
+
reader.readAsDataURL(blob);
|
|
28
|
+
} else if (typeof Buffer !== "undefined") {
|
|
29
|
+
// Node.js Environment: Use Buffer
|
|
30
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
31
|
+
const base64String = Buffer.from(arrayBuffer).toString("base64");
|
|
32
|
+
const mimeType = blob.type || "application/octet-stream";
|
|
33
|
+
resolve(`data:${mimeType};base64,${base64String}`);
|
|
34
|
+
} else {
|
|
35
|
+
throw new Error("Base64 conversion not supported in this environment");
|
|
36
|
+
}
|
|
37
|
+
} catch (e: any) {
|
|
38
|
+
console.info("fetchImageForBase64 error:", e.message);
|
|
39
|
+
if (alwaysResolve) return resolve(null);
|
|
40
|
+
reject(e);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Compares two base64 strings to check if they are identical.
|
|
48
|
+
* @param {string} base64A - The first base64 string.
|
|
49
|
+
* @param {string} base64B - The second base64 string.
|
|
50
|
+
* @returns {boolean} - Returns true if the base64 strings are identical, otherwise false.
|
|
51
|
+
*/
|
|
52
|
+
export function compareBase64(base64A: string, base64B: string): boolean {
|
|
53
|
+
//base64A is fetched from URL. Sampl: iVBORw0KGgoAAAANSUhEUgAAAGYAAABg...
|
|
54
|
+
//base64B is the uploaded file base64 string. Sample: data:image/png;base64,iVBORw0KGg...
|
|
55
|
+
console.info("parsedSvg:base64A: ", base64A.substring(0, 32))
|
|
56
|
+
console.info("parsedSvg:base64B: ", base64B.substring(0, 32))
|
|
57
|
+
return base64A === base64B.split(',')[1];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Removes a specific query string parameter from a URL.
|
|
62
|
+
* @param {string} url - The original URL.
|
|
63
|
+
* @param {string} queryString - The query string parameter to remove.
|
|
64
|
+
* @returns {string} - The updated URL without the specified query string parameter.
|
|
65
|
+
*/
|
|
66
|
+
export function removeQueryString(url: string, queryString: string): string {
|
|
67
|
+
try {
|
|
68
|
+
// Create a URL object
|
|
69
|
+
const urlObj = new URL(url);
|
|
70
|
+
|
|
71
|
+
// Remove the specified query string parameter
|
|
72
|
+
urlObj.searchParams.delete(queryString);
|
|
73
|
+
|
|
74
|
+
// Return the updated URL as a string
|
|
75
|
+
return urlObj.toString();
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('Invalid URL:', error, url);
|
|
78
|
+
return url; // Return the original URL if there's an error
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Updates the query string in a URL, adding or incrementing the 'updates' parameter.
|
|
84
|
+
* @param {string} url - The URL to update.
|
|
85
|
+
* @returns {string} - The updated URL.
|
|
86
|
+
*/
|
|
87
|
+
export function removeUpdateQueryString(url: string): string {
|
|
88
|
+
return removeQueryString(url, 'updates')
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Updates the query string in a URL, adding or incrementing the 'updates' parameter.
|
|
93
|
+
* @param {string} url - The URL to update.
|
|
94
|
+
* @returns {string} - The updated URL.
|
|
95
|
+
*/
|
|
96
|
+
export function incrementUpdateQueryString(url: string): string {
|
|
97
|
+
const urlObj = new URL(url);
|
|
98
|
+
const updates = urlObj.searchParams.get('updates');
|
|
99
|
+
const newUpdates = `${updates ? parseInt(updates, 10) + 1 : 1}`;
|
|
100
|
+
urlObj.searchParams.set('updates', newUpdates);
|
|
101
|
+
return urlObj.toString();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Updates the query string in a URL, adding or incrementing the 'updates' parameter.
|
|
106
|
+
* @param {string} url - The URL to update.
|
|
107
|
+
* @returns {string} - The updated URL.
|
|
108
|
+
*/
|
|
109
|
+
export function getUrlUpdatesCount(url: string): number {
|
|
110
|
+
const urlObj = new URL(url);
|
|
111
|
+
const updates = urlObj.searchParams.get('updates');
|
|
112
|
+
return updates ? parseInt(updates, 10) : 1;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Processes the old and new images, comparing the content and updating the new images if they are identical.
|
|
117
|
+
* @param {{[x: string]: string}} oldImages - The map of old images with keys and URLs or base64 strings.
|
|
118
|
+
* @param {{[x: string]: string}} newImages - The map of new images with keys and base64 strings.
|
|
119
|
+
* @returns {Promise<{[x: string]: string}>} - Returns a promise that resolves to the updated map of new images.
|
|
120
|
+
*/
|
|
121
|
+
export function mergeImages(storageHost: string, oldImages: FileMap, newImages: FileMap): Promise<FileMap> {
|
|
122
|
+
return new Promise(async (resolve, reject) => {
|
|
123
|
+
try {
|
|
124
|
+
for (const key in oldImages) {
|
|
125
|
+
if (oldImages.hasOwnProperty(key) && newImages.hasOwnProperty(key)) {
|
|
126
|
+
const oldImage = oldImages[key];
|
|
127
|
+
const newImage = newImages[key];
|
|
128
|
+
|
|
129
|
+
// Check if oldImage is a URL and newImage is base64
|
|
130
|
+
if (oldImage.startsWith('http') && newImage.startsWith('data:image')) {
|
|
131
|
+
const fetchedOldImageBase64 = await fetchImageForBase64(storageHost, oldImage, true);
|
|
132
|
+
|
|
133
|
+
//If the image at the old image's url is the same as the new image,
|
|
134
|
+
//that is no change
|
|
135
|
+
if (fetchedOldImageBase64 && compareBase64(fetchedOldImageBase64, newImage)) {
|
|
136
|
+
//Replace the new image's base64 url with the old image's http url to
|
|
137
|
+
// prevent unneccessary reupload of the image
|
|
138
|
+
newImages[key] = oldImage;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
resolve(newImages);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
reject(error);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Generates a new image of specified width and height by repeating the given image with a specified opacity.
|
|
152
|
+
*
|
|
153
|
+
* @param {string} imageUrl - The URL or base64 string of the original image.
|
|
154
|
+
* @param {number} width - The width of the new image.
|
|
155
|
+
* @param {number} height - The height of the new image.
|
|
156
|
+
* @param {number} opacity - The opacity of the watermark image (0 to 1).
|
|
157
|
+
* @returns {Promise<string>} - A promise that resolves to a base64 string of the new image.
|
|
158
|
+
*/
|
|
159
|
+
export function generateWatermark(imageUrl: string, width: number, height: number, opacity = 1): Promise<string> {
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
const originalImage = new Image();
|
|
162
|
+
|
|
163
|
+
originalImage.onload = () => {
|
|
164
|
+
const canvas = getCanvas(width, height);
|
|
165
|
+
const ctx = canvas.getContext('2d') as any;
|
|
166
|
+
|
|
167
|
+
if (!ctx) return reject("No canvas context");
|
|
168
|
+
|
|
169
|
+
canvas.width = width;
|
|
170
|
+
canvas.height = height;
|
|
171
|
+
|
|
172
|
+
ctx.globalAlpha = opacity;
|
|
173
|
+
|
|
174
|
+
for (let y = 0; y < height; y += originalImage.height) {
|
|
175
|
+
for (let x = 0; x < width; x += originalImage.width) {
|
|
176
|
+
ctx.drawImage(originalImage, x, y, originalImage.width, originalImage.height);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
resolve(canvas.toDataURL());
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
originalImage.onerror = reject;
|
|
184
|
+
originalImage.src = imageUrl;
|
|
185
|
+
});
|
|
186
|
+
}
|