@polotno/pdf-export 0.1.38 → 0.1.40
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 +61 -8
- package/lib/index.d.ts +66 -8
- package/lib/index.js +25 -145
- package/package.json +17 -18
- package/lib/compare-render.d.ts +0 -1
- package/lib/compare-render.js +0 -185
- package/lib/figure.d.ts +0 -10
- package/lib/figure.js +0 -54
- package/lib/filters.d.ts +0 -2
- package/lib/filters.js +0 -163
- package/lib/ghostscript.d.ts +0 -21
- package/lib/ghostscript.js +0 -132
- package/lib/group.d.ts +0 -5
- package/lib/group.js +0 -5
- package/lib/image.d.ts +0 -38
- package/lib/image.js +0 -279
- package/lib/line.d.ts +0 -10
- package/lib/line.js +0 -66
- package/lib/pdf-import/coordinate-transform.d.ts +0 -51
- package/lib/pdf-import/coordinate-transform.js +0 -99
- package/lib/pdf-import/element-builder.d.ts +0 -21
- package/lib/pdf-import/element-builder.js +0 -163
- package/lib/pdf-import/font-mapper.d.ts +0 -17
- package/lib/pdf-import/font-mapper.js +0 -142
- package/lib/pdf-import/index.d.ts +0 -35
- package/lib/pdf-import/index.js +0 -105
- package/lib/pdf-import/parser.d.ts +0 -29
- package/lib/pdf-import/parser.js +0 -285
- package/lib/pdf-import/text-analysis.d.ts +0 -17
- package/lib/pdf-import/text-analysis.js +0 -186
- package/lib/pdf-import/types.d.ts +0 -101
- package/lib/pdf-import/types.js +0 -1
- package/lib/scripts/compare-json.d.ts +0 -1
- package/lib/scripts/compare-json.js +0 -141
- package/lib/spot-colors.d.ts +0 -38
- package/lib/spot-colors.js +0 -141
- package/lib/svg-render.d.ts +0 -9
- package/lib/svg-render.js +0 -63
- package/lib/svg.d.ts +0 -12
- package/lib/svg.js +0 -224
- package/lib/text/fonts.d.ts +0 -16
- package/lib/text/fonts.js +0 -113
- package/lib/text/index.d.ts +0 -8
- package/lib/text/index.js +0 -42
- package/lib/text/layout.d.ts +0 -22
- package/lib/text/layout.js +0 -522
- package/lib/text/parser.d.ts +0 -46
- package/lib/text/parser.js +0 -415
- package/lib/text/render.d.ts +0 -8
- package/lib/text/render.js +0 -237
- package/lib/text/types.d.ts +0 -91
- package/lib/text/types.js +0 -1
- package/lib/text.d.ts +0 -39
- package/lib/text.js +0 -576
- package/lib/utils.d.ts +0 -16
- package/lib/utils.js +0 -124
package/lib/utils.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import parseColor from 'parse-color';
|
|
2
|
-
import fetch from 'node-fetch';
|
|
3
|
-
import Canvas from 'canvas';
|
|
4
|
-
import sharp from 'sharp';
|
|
5
|
-
export const DPI = 75;
|
|
6
|
-
export const PIXEL_RATIO = 2;
|
|
7
|
-
// Fetch with timeout and retry logic
|
|
8
|
-
export async function fetchWithTimeout(url, timeout = 30000, retries = 3) {
|
|
9
|
-
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
10
|
-
try {
|
|
11
|
-
const controller = new AbortController();
|
|
12
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
13
|
-
const response = await fetch(url, {
|
|
14
|
-
signal: controller.signal,
|
|
15
|
-
});
|
|
16
|
-
clearTimeout(timeoutId);
|
|
17
|
-
if (!response.ok) {
|
|
18
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
19
|
-
}
|
|
20
|
-
return response;
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
const isLastAttempt = attempt === retries;
|
|
24
|
-
const isAbortError = error.name === 'AbortError';
|
|
25
|
-
const isTimeoutError = error.code === 'ETIMEDOUT' || error.type === 'request-timeout';
|
|
26
|
-
if (isLastAttempt) {
|
|
27
|
-
throw new Error(`Failed to fetch ${url} after ${retries} attempts: ${error.message}`);
|
|
28
|
-
}
|
|
29
|
-
// Only retry on network/timeout errors, not on 4xx client errors
|
|
30
|
-
if (isAbortError || isTimeoutError || error.code?.startsWith('E')) {
|
|
31
|
-
console.warn(`Fetch attempt ${attempt}/${retries} failed for ${url}, retrying...`);
|
|
32
|
-
// Exponential backoff: 1s, 2s, 4s, etc.
|
|
33
|
-
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt - 1) * 1000));
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
// Don't retry on other errors (e.g., 404, 403)
|
|
37
|
-
throw error;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`Failed to fetch ${url}`);
|
|
41
|
-
}
|
|
42
|
-
export function pxToPt(px) {
|
|
43
|
-
return (px * DPI) / 100;
|
|
44
|
-
}
|
|
45
|
-
export async function loadImage(src, cache = null) {
|
|
46
|
-
// Check cache first
|
|
47
|
-
if (cache && cache.images.has(src)) {
|
|
48
|
-
return cache.images.get(src);
|
|
49
|
-
}
|
|
50
|
-
let buffer;
|
|
51
|
-
let mime = 'unknown';
|
|
52
|
-
if (src.startsWith('data:')) {
|
|
53
|
-
const matches = src.match(/^data:(.+);base64,(.*)$/);
|
|
54
|
-
if (matches) {
|
|
55
|
-
mime = matches[1];
|
|
56
|
-
buffer = Buffer.from(matches[2], 'base64');
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
throw new Error('Invalid data URL');
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
try {
|
|
64
|
-
const response = await fetchWithTimeout(src);
|
|
65
|
-
buffer = Buffer.from(await response.arrayBuffer());
|
|
66
|
-
const { fileTypeFromBuffer } = await import('file-type');
|
|
67
|
-
const typeData = await fileTypeFromBuffer(buffer);
|
|
68
|
-
if (typeData) {
|
|
69
|
-
mime = typeData.mime;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
console.log(error);
|
|
74
|
-
throw new Error(`Failed to process image from ${src}: ${error.message}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
let imageBuffer = buffer;
|
|
78
|
-
if (mime !== 'image/png' && mime !== 'image/jpeg') {
|
|
79
|
-
imageBuffer = await sharp(buffer).toFormat('png').toBuffer();
|
|
80
|
-
mime = 'image/png';
|
|
81
|
-
}
|
|
82
|
-
const image = await Canvas.loadImage(imageBuffer);
|
|
83
|
-
// Store in cache
|
|
84
|
-
if (cache) {
|
|
85
|
-
cache.images.set(src, image);
|
|
86
|
-
}
|
|
87
|
-
return image;
|
|
88
|
-
}
|
|
89
|
-
export async function srcToBase64(src, cache = null) {
|
|
90
|
-
// For base64 caching, we use a different cache key to avoid collision with buffer cache
|
|
91
|
-
const base64CacheKey = `base64:${src}`;
|
|
92
|
-
// Check cache first
|
|
93
|
-
if (cache && cache.buffers.has(base64CacheKey)) {
|
|
94
|
-
return cache.buffers.get(base64CacheKey);
|
|
95
|
-
}
|
|
96
|
-
let base64;
|
|
97
|
-
if (src.indexOf('base64') >= 0) {
|
|
98
|
-
base64 = src.split('base64,')[1];
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
const res = await fetchWithTimeout(src);
|
|
102
|
-
const data = Buffer.from(await res.arrayBuffer());
|
|
103
|
-
base64 = data.toString('base64');
|
|
104
|
-
}
|
|
105
|
-
// Store in cache
|
|
106
|
-
if (cache) {
|
|
107
|
-
cache.buffers.set(base64CacheKey, base64);
|
|
108
|
-
}
|
|
109
|
-
return base64;
|
|
110
|
-
}
|
|
111
|
-
export async function srcToBuffer(src, cache = null) {
|
|
112
|
-
// Check if we have a cached Buffer for this source
|
|
113
|
-
if (cache && cache.buffers.has(src)) {
|
|
114
|
-
return cache.buffers.get(src);
|
|
115
|
-
}
|
|
116
|
-
const base64 = await srcToBase64(src, cache);
|
|
117
|
-
const buffer = Buffer.from(base64, 'base64');
|
|
118
|
-
// Cache the actual Buffer object so PDFKit can reuse it
|
|
119
|
-
if (cache) {
|
|
120
|
-
cache.buffers.set(src, buffer);
|
|
121
|
-
}
|
|
122
|
-
return buffer;
|
|
123
|
-
}
|
|
124
|
-
export { parseColor };
|