@pdfme/schemas 6.0.3-dev.0 → 6.0.4-dev.1
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/barcodes/constants.d.ts +4 -0
- package/dist/barcodes/helper.d.ts +21 -0
- package/dist/barcodes/index.d.ts +4 -0
- package/dist/barcodes/pdfRender.d.ts +3 -0
- package/dist/barcodes/propPanel.d.ts +3 -0
- package/{src/barcodes/types.ts → dist/barcodes/types.d.ts} +5 -7
- package/dist/barcodes/uiRender.d.ts +3 -0
- package/dist/builtins-CgaZ0UX3.js +613 -0
- package/dist/builtins-CgaZ0UX3.js.map +1 -0
- package/dist/builtins.d.ts +4 -0
- package/dist/builtins.js +2 -0
- package/dist/checkbox/index.d.ts +6 -0
- package/dist/constants.d.ts +2 -0
- package/dist/date/date.d.ts +2 -0
- package/dist/date/dateTime.d.ts +2 -0
- package/dist/date/helper.d.ts +20 -0
- package/dist/date/time.d.ts +2 -0
- package/dist/date/types.d.ts +17 -0
- package/dist/dynamicTemplate-D_DHR3-X.js +1128 -0
- package/dist/dynamicTemplate-D_DHR3-X.js.map +1 -0
- package/dist/graphics/image.d.ts +5 -0
- package/dist/graphics/imagehelper.d.ts +4 -0
- package/dist/graphics/signature.d.ts +4 -0
- package/dist/graphics/svg.d.ts +4 -0
- package/{src/index.ts → dist/index.d.ts} +1 -22
- package/dist/index.js +5383 -0
- package/dist/index.js.map +1 -0
- package/dist/multiVariableText/helper.d.ts +3 -0
- package/dist/multiVariableText/index.d.ts +4 -0
- package/dist/multiVariableText/pdfRender.d.ts +3 -0
- package/dist/multiVariableText/propPanel.d.ts +3 -0
- package/{src/multiVariableText/types.ts → dist/multiVariableText/types.d.ts} +2 -3
- package/dist/multiVariableText/uiRender.d.ts +3 -0
- package/dist/multiVariableText/variables.d.ts +10 -0
- package/dist/radioGroup/index.d.ts +7 -0
- package/dist/sanitize.d.ts +1 -0
- package/dist/select/index.d.ts +7 -0
- package/dist/shapes/line.d.ts +6 -0
- package/dist/shapes/rectAndEllipse.d.ts +11 -0
- package/dist/tables/cell.d.ts +4 -0
- package/dist/tables/classes.d.ts +69 -0
- package/dist/tables/dynamicTemplate.d.ts +7 -0
- package/dist/tables/helper.d.ts +265 -0
- package/dist/tables/index.d.ts +4 -0
- package/dist/tables/pdfRender.d.ts +3 -0
- package/dist/tables/propPanel.d.ts +3 -0
- package/dist/tables/tableHelper.d.ts +10 -0
- package/dist/tables/types.d.ts +88 -0
- package/dist/tables/uiRender.d.ts +3 -0
- package/dist/tables.js +2 -0
- package/dist/text/constants.d.ts +23 -0
- package/dist/text/extraFormatter.d.ts +25 -0
- package/dist/text/helper.d.ts +40 -0
- package/dist/text/icons/index.d.ts +9 -0
- package/dist/text/index.d.ts +4 -0
- package/dist/text/pdfRender.d.ts +3 -0
- package/dist/text/propPanel.d.ts +3 -0
- package/dist/text/types.d.ts +28 -0
- package/dist/text/uiRender.d.ts +11 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.js +215 -0
- package/dist/utils.js.map +1 -0
- package/package.json +5 -1
- package/src/barcodes/constants.ts +0 -20
- package/src/barcodes/helper.ts +0 -187
- package/src/barcodes/index.ts +0 -23
- package/src/barcodes/pdfRender.ts +0 -37
- package/src/barcodes/propPanel.ts +0 -249
- package/src/barcodes/uiRender.ts +0 -94
- package/src/builtins.ts +0 -8
- package/src/checkbox/index.ts +0 -70
- package/src/constants.ts +0 -2
- package/src/date/date.ts +0 -9
- package/src/date/dateTime.ts +0 -9
- package/src/date/helper.ts +0 -544
- package/src/date/time.ts +0 -9
- package/src/date/types.ts +0 -19
- package/src/graphics/image.ts +0 -201
- package/src/graphics/imagehelper.ts +0 -156
- package/src/graphics/signature.ts +0 -136
- package/src/graphics/svg.ts +0 -121
- package/src/multiVariableText/helper.ts +0 -65
- package/src/multiVariableText/index.ts +0 -16
- package/src/multiVariableText/pdfRender.ts +0 -21
- package/src/multiVariableText/propPanel.ts +0 -169
- package/src/multiVariableText/uiRender.ts +0 -157
- package/src/multiVariableText/variables.ts +0 -63
- package/src/radioGroup/index.ts +0 -115
- package/src/sanitize.ts +0 -50
- package/src/select/index.ts +0 -205
- package/src/shapes/line.ts +0 -94
- package/src/shapes/rectAndEllipse.ts +0 -152
- package/src/tables/cell.ts +0 -152
- package/src/tables/classes.ts +0 -402
- package/src/tables/dynamicTemplate.ts +0 -88
- package/src/tables/helper.ts +0 -216
- package/src/tables/index.ts +0 -15
- package/src/tables/pdfRender.ts +0 -144
- package/src/tables/propPanel.ts +0 -111
- package/src/tables/tableHelper.ts +0 -289
- package/src/tables/types.ts +0 -87
- package/src/tables/uiRender.ts +0 -436
- package/src/text/constants.ts +0 -104
- package/src/text/extraFormatter.ts +0 -83
- package/src/text/helper.ts +0 -573
- package/src/text/icons/index.ts +0 -30
- package/src/text/index.ts +0 -16
- package/src/text/pdfRender.ts +0 -240
- package/src/text/propPanel.ts +0 -184
- package/src/text/types.ts +0 -30
- package/src/text/uiRender.ts +0 -292
- package/src/utils.ts +0 -354
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -16
- package/vite.config.mts +0 -51
- /package/{src/tables.ts → dist/tables.d.ts} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Schema } from '@pdfme/common';
|
|
2
|
+
import type { Font as FontKitFont } from 'fontkit';
|
|
3
|
+
export type ALIGNMENT = 'left' | 'center' | 'right' | 'justify';
|
|
4
|
+
export type VERTICAL_ALIGNMENT = 'top' | 'middle' | 'bottom';
|
|
5
|
+
export type DYNAMIC_FONT_SIZE_FIT = 'horizontal' | 'vertical';
|
|
6
|
+
export type FontWidthCalcValues = {
|
|
7
|
+
font: FontKitFont;
|
|
8
|
+
fontSize: number;
|
|
9
|
+
characterSpacing: number;
|
|
10
|
+
boxWidthInPt: number;
|
|
11
|
+
};
|
|
12
|
+
export type TextSchema = Schema & {
|
|
13
|
+
fontName?: string;
|
|
14
|
+
alignment: ALIGNMENT;
|
|
15
|
+
verticalAlignment: VERTICAL_ALIGNMENT;
|
|
16
|
+
fontSize: number;
|
|
17
|
+
lineHeight: number;
|
|
18
|
+
strikethrough?: boolean;
|
|
19
|
+
underline?: boolean;
|
|
20
|
+
characterSpacing: number;
|
|
21
|
+
dynamicFontSize?: {
|
|
22
|
+
min: number;
|
|
23
|
+
max: number;
|
|
24
|
+
fit: DYNAMIC_FONT_SIZE_FIT;
|
|
25
|
+
};
|
|
26
|
+
fontColor: string;
|
|
27
|
+
backgroundColor: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Font as FontKitFont } from 'fontkit';
|
|
2
|
+
import { UIRenderProps } from '@pdfme/common';
|
|
3
|
+
import type { TextSchema } from './types.js';
|
|
4
|
+
export declare const uiRender: (arg: UIRenderProps<TextSchema>) => Promise<void>;
|
|
5
|
+
export declare const buildStyledTextContainer: (arg: UIRenderProps<TextSchema>, fontKitFont: FontKitFont, value: string) => HTMLDivElement;
|
|
6
|
+
/**
|
|
7
|
+
* Firefox doesn't support 'plaintext-only' contentEditable mode, which we want to avoid mark-up.
|
|
8
|
+
* This function adds a workaround for Firefox to make the contentEditable element behave like 'plaintext-only'.
|
|
9
|
+
*/
|
|
10
|
+
export declare const makeElementPlainTextContentEditable: (element: HTMLElement) => void;
|
|
11
|
+
export declare const mapVerticalAlignToFlex: (verticalAlignmentValue: string | undefined) => "center" | "flex-end" | "flex-start";
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Color } from '@pdfme/pdf-lib';
|
|
2
|
+
import { Schema, Mode, ColorType } from '@pdfme/common';
|
|
3
|
+
import { IconNode } from 'lucide';
|
|
4
|
+
export declare const convertForPdfLayoutProps: ({ schema, pageHeight, applyRotateTranslate, }: {
|
|
5
|
+
schema: Schema;
|
|
6
|
+
pageHeight: number;
|
|
7
|
+
applyRotateTranslate?: boolean;
|
|
8
|
+
}) => {
|
|
9
|
+
position: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
height: number;
|
|
14
|
+
width: number;
|
|
15
|
+
rotate: import("@pdfme/pdf-lib").Degrees;
|
|
16
|
+
opacity: number | undefined;
|
|
17
|
+
};
|
|
18
|
+
export declare const rotatePoint: (point: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
}, pivot: {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
}, angleDegrees: number) => {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const getDynamicHeightsForTable: (value: string, args: {
|
|
29
|
+
schema: Schema;
|
|
30
|
+
basePdf: import("@pdfme/common").BasePdf;
|
|
31
|
+
options: import("@pdfme/common").CommonOptions;
|
|
32
|
+
_cache: Map<string | number, unknown>;
|
|
33
|
+
}) => Promise<number[]>;
|
|
34
|
+
export declare const addAlphaToHex: (hex: string, alphaPercentage: number) => string;
|
|
35
|
+
export declare const isEditable: (mode: Mode, schema: Schema) => boolean;
|
|
36
|
+
export declare const hex2RgbColor: (hexString: string | undefined) => import("@pdfme/pdf-lib").RGB | undefined;
|
|
37
|
+
export declare const hex2PrintingColor: (color?: string | Color, colorType?: ColorType) => Color | undefined;
|
|
38
|
+
export declare const readFile: (input: File | FileList | null) => Promise<string | ArrayBuffer>;
|
|
39
|
+
export declare const createErrorElm: () => HTMLDivElement;
|
|
40
|
+
export declare const createSvgStr: (icon: IconNode, attrs?: Record<string, string>) => string;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { t as getDynamicHeightsForTable$1 } from "./dynamicTemplate-D_DHR3-X.js";
|
|
2
|
+
import { isHexValid, mm2pt } from "@pdfme/common";
|
|
3
|
+
import { cmyk, degrees, degreesToRadians, rgb } from "@pdfme/pdf-lib";
|
|
4
|
+
//#region src/utils.ts
|
|
5
|
+
var convertForPdfLayoutProps = ({ schema, pageHeight, applyRotateTranslate = true }) => {
|
|
6
|
+
const { width: mmWidth, height: mmHeight, position, rotate, opacity } = schema;
|
|
7
|
+
const { x: mmX, y: mmY } = position;
|
|
8
|
+
const rotateDegrees = rotate ? -rotate : 0;
|
|
9
|
+
const width = mm2pt(mmWidth);
|
|
10
|
+
const height = mm2pt(mmHeight);
|
|
11
|
+
let x = mm2pt(mmX);
|
|
12
|
+
let y = pageHeight - mm2pt(mmY) - height;
|
|
13
|
+
if (rotateDegrees && applyRotateTranslate) {
|
|
14
|
+
const pivotPoint = {
|
|
15
|
+
x: x + width / 2,
|
|
16
|
+
y: pageHeight - mm2pt(mmY) - height / 2
|
|
17
|
+
};
|
|
18
|
+
const rotatedPoint = rotatePoint({
|
|
19
|
+
x,
|
|
20
|
+
y
|
|
21
|
+
}, pivotPoint, rotateDegrees);
|
|
22
|
+
x = rotatedPoint.x;
|
|
23
|
+
y = rotatedPoint.y;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
position: {
|
|
27
|
+
x,
|
|
28
|
+
y
|
|
29
|
+
},
|
|
30
|
+
height,
|
|
31
|
+
width,
|
|
32
|
+
rotate: degrees(rotateDegrees),
|
|
33
|
+
opacity
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
var rotatePoint = (point, pivot, angleDegrees) => {
|
|
37
|
+
const angleRadians = degreesToRadians(angleDegrees);
|
|
38
|
+
return {
|
|
39
|
+
x: Math.cos(angleRadians) * (point.x - pivot.x) - Math.sin(angleRadians) * (point.y - pivot.y) + pivot.x,
|
|
40
|
+
y: Math.sin(angleRadians) * (point.x - pivot.x) + Math.cos(angleRadians) * (point.y - pivot.y) + pivot.y
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
var getDynamicHeightsForTable = getDynamicHeightsForTable$1;
|
|
44
|
+
var addAlphaToHex = (hex, alphaPercentage) => {
|
|
45
|
+
if (!/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i.test(hex)) throw new Error("Invalid HEX color code");
|
|
46
|
+
let alphaHex = Math.round(alphaPercentage / 100 * 255).toString(16);
|
|
47
|
+
if (alphaHex.length === 1) alphaHex = "0" + alphaHex;
|
|
48
|
+
return hex + alphaHex;
|
|
49
|
+
};
|
|
50
|
+
var isEditable = (mode, schema) => mode === "designer" || mode === "form" && schema.readOnly !== true;
|
|
51
|
+
var hex2rgb = (hex) => {
|
|
52
|
+
if (hex.slice(0, 1) === "#") hex = hex.slice(1);
|
|
53
|
+
if (hex.length === 3) hex = hex.slice(0, 1) + hex.slice(0, 1) + hex.slice(1, 2) + hex.slice(1, 2) + hex.slice(2, 3) + hex.slice(2, 3);
|
|
54
|
+
return [
|
|
55
|
+
hex.slice(0, 2),
|
|
56
|
+
hex.slice(2, 4),
|
|
57
|
+
hex.slice(4, 6)
|
|
58
|
+
].map((str) => parseInt(str, 16));
|
|
59
|
+
};
|
|
60
|
+
var hex2RgbColor = (hexString) => {
|
|
61
|
+
if (hexString) {
|
|
62
|
+
if (!isHexValid(hexString)) throw new Error(`Invalid hex color value ${hexString}`);
|
|
63
|
+
const [r, g, b] = hex2rgb(hexString);
|
|
64
|
+
return rgb(r / 255, g / 255, b / 255);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var hex2CmykColor = (hexString) => {
|
|
68
|
+
if (hexString) {
|
|
69
|
+
if (!isHexValid(hexString)) throw new Error(`Invalid hex color value ${hexString}`);
|
|
70
|
+
hexString = hexString.replace("#", "");
|
|
71
|
+
const hexColor = hexString.substring(0, 6);
|
|
72
|
+
const opacityColor = hexString.substring(6, 8);
|
|
73
|
+
const opacity = opacityColor ? parseInt(opacityColor, 16) / 255 : 1;
|
|
74
|
+
let r = parseInt(hexColor.substring(0, 2), 16) / 255;
|
|
75
|
+
let g = parseInt(hexColor.substring(2, 4), 16) / 255;
|
|
76
|
+
let b = parseInt(hexColor.substring(4, 6), 16) / 255;
|
|
77
|
+
r = r * opacity + (1 - opacity);
|
|
78
|
+
g = g * opacity + (1 - opacity);
|
|
79
|
+
b = b * opacity + (1 - opacity);
|
|
80
|
+
const k = 1 - Math.max(r, g, b);
|
|
81
|
+
return cmyk(r === 0 ? 0 : (1 - r - k) / (1 - k), g === 0 ? 0 : (1 - g - k) / (1 - k), b === 0 ? 0 : (1 - b - k) / (1 - k), k);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var hex2PrintingColor = (color, colorType) => {
|
|
85
|
+
if (typeof color === "object") return color;
|
|
86
|
+
return colorType?.toLowerCase() == "cmyk" ? hex2CmykColor(color) : hex2RgbColor(color);
|
|
87
|
+
};
|
|
88
|
+
var readFile = (input) => new Promise((resolve, reject) => {
|
|
89
|
+
const fileReader = new FileReader();
|
|
90
|
+
fileReader.onload = (e) => {
|
|
91
|
+
if (e.target?.result) resolve(e.target.result);
|
|
92
|
+
};
|
|
93
|
+
fileReader.onerror = () => {
|
|
94
|
+
reject(/* @__PURE__ */ new Error("[@pdfme/schemas] File reading failed"));
|
|
95
|
+
};
|
|
96
|
+
let file = null;
|
|
97
|
+
if (input instanceof FileList && input.length > 0) file = input[0];
|
|
98
|
+
else if (input instanceof File) file = input;
|
|
99
|
+
if (file) fileReader.readAsDataURL(file);
|
|
100
|
+
else reject(/* @__PURE__ */ new Error("[@pdfme/schemas] No files provided"));
|
|
101
|
+
});
|
|
102
|
+
var createErrorElm = () => {
|
|
103
|
+
const container = document.createElement("div");
|
|
104
|
+
Object.assign(container.style, {
|
|
105
|
+
display: "flex",
|
|
106
|
+
alignItems: "center",
|
|
107
|
+
justifyContent: "center",
|
|
108
|
+
width: "100%",
|
|
109
|
+
height: "100%"
|
|
110
|
+
});
|
|
111
|
+
const span = document.createElement("span");
|
|
112
|
+
Object.assign(span.style, {
|
|
113
|
+
color: "white",
|
|
114
|
+
background: "red",
|
|
115
|
+
padding: "0.25rem",
|
|
116
|
+
fontSize: "12pt",
|
|
117
|
+
fontWeight: "bold",
|
|
118
|
+
borderRadius: "2px",
|
|
119
|
+
fontFamily: "'Open Sans', sans-serif"
|
|
120
|
+
});
|
|
121
|
+
span.textContent = "ERROR";
|
|
122
|
+
container.appendChild(span);
|
|
123
|
+
return container;
|
|
124
|
+
};
|
|
125
|
+
var createSvgStr = (icon, attrs) => {
|
|
126
|
+
const safeTagNames = new Set([
|
|
127
|
+
"svg",
|
|
128
|
+
"circle",
|
|
129
|
+
"ellipse",
|
|
130
|
+
"g",
|
|
131
|
+
"line",
|
|
132
|
+
"path",
|
|
133
|
+
"polygon",
|
|
134
|
+
"polyline",
|
|
135
|
+
"rect"
|
|
136
|
+
]);
|
|
137
|
+
const safeAttributeNames = new Set([
|
|
138
|
+
"aria-hidden",
|
|
139
|
+
"aria-label",
|
|
140
|
+
"class",
|
|
141
|
+
"clip-rule",
|
|
142
|
+
"cx",
|
|
143
|
+
"cy",
|
|
144
|
+
"d",
|
|
145
|
+
"fill",
|
|
146
|
+
"fill-opacity",
|
|
147
|
+
"fill-rule",
|
|
148
|
+
"focusable",
|
|
149
|
+
"height",
|
|
150
|
+
"id",
|
|
151
|
+
"opacity",
|
|
152
|
+
"points",
|
|
153
|
+
"preserveAspectRatio",
|
|
154
|
+
"r",
|
|
155
|
+
"role",
|
|
156
|
+
"rx",
|
|
157
|
+
"ry",
|
|
158
|
+
"stroke",
|
|
159
|
+
"stroke-dasharray",
|
|
160
|
+
"stroke-dashoffset",
|
|
161
|
+
"stroke-linecap",
|
|
162
|
+
"stroke-linejoin",
|
|
163
|
+
"stroke-miterlimit",
|
|
164
|
+
"stroke-opacity",
|
|
165
|
+
"stroke-width",
|
|
166
|
+
"transform",
|
|
167
|
+
"vector-effect",
|
|
168
|
+
"viewBox",
|
|
169
|
+
"width",
|
|
170
|
+
"x",
|
|
171
|
+
"x1",
|
|
172
|
+
"x2",
|
|
173
|
+
"xmlns",
|
|
174
|
+
"xmlns:xlink",
|
|
175
|
+
"y",
|
|
176
|
+
"y1",
|
|
177
|
+
"y2"
|
|
178
|
+
]);
|
|
179
|
+
const escapeHtmlAttribute = (value) => value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
180
|
+
const escapeHtmlText = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
181
|
+
const toSafeAttributeString = (attributes) => Object.entries(attributes).filter(([key, value]) => safeAttributeNames.has(key) && value !== void 0 && value !== null && !key.toLowerCase().startsWith("on")).map(([key, value]) => `${key}="${escapeHtmlAttribute(String(value))}"`).join(" ");
|
|
182
|
+
const toSafeTagName = (tag) => {
|
|
183
|
+
const tagName = String(tag);
|
|
184
|
+
if (!safeTagNames.has(tagName)) throw new Error(`Invalid SVG tag name: ${tagName}`);
|
|
185
|
+
return tagName;
|
|
186
|
+
};
|
|
187
|
+
if (!Array.isArray(icon)) return escapeHtmlText(String(icon));
|
|
188
|
+
const svgAttrString = toSafeAttributeString({
|
|
189
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
190
|
+
width: "24",
|
|
191
|
+
height: "24",
|
|
192
|
+
viewBox: "0 0 24 24",
|
|
193
|
+
fill: "none",
|
|
194
|
+
stroke: "currentColor",
|
|
195
|
+
"stroke-width": "2",
|
|
196
|
+
"stroke-linecap": "round",
|
|
197
|
+
"stroke-linejoin": "round",
|
|
198
|
+
...attrs
|
|
199
|
+
});
|
|
200
|
+
const processElement = (element) => {
|
|
201
|
+
if (!Array.isArray(element)) return escapeHtmlText(String(element));
|
|
202
|
+
const [tag, attributes = {}, children = []] = element;
|
|
203
|
+
const tagName = toSafeTagName(tag);
|
|
204
|
+
const attrString = toSafeAttributeString(attributes);
|
|
205
|
+
let childrenString = "";
|
|
206
|
+
if (Array.isArray(children) && children.length > 0) childrenString = children.map((child) => processElement(child)).join("");
|
|
207
|
+
if (childrenString) return `<${String(tagName)}${attrString ? " " + String(attrString) : ""}>${childrenString}</${String(tagName)}>`;
|
|
208
|
+
else return `<${String(tagName)}${attrString ? " " + String(attrString) : ""}/>`;
|
|
209
|
+
};
|
|
210
|
+
return `<svg ${svgAttrString}>${Array.isArray(icon) ? icon.map((element) => processElement(element)).join("") : processElement(icon)}</svg>`;
|
|
211
|
+
};
|
|
212
|
+
//#endregion
|
|
213
|
+
export { addAlphaToHex, convertForPdfLayoutProps, createErrorElm, createSvgStr, getDynamicHeightsForTable, hex2PrintingColor, hex2RgbColor, isEditable, readFile, rotatePoint };
|
|
214
|
+
|
|
215
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type * as CSS from 'csstype';\nimport { cmyk, degrees, degreesToRadians, rgb, Color } from '@pdfme/pdf-lib';\nimport { Schema, mm2pt, Mode, isHexValid, ColorType } from '@pdfme/common';\nimport { IconNode } from 'lucide';\nimport { getDynamicHeightsForTable as _getDynamicHeightsForTable } from './tables/dynamicTemplate.js';\nexport const convertForPdfLayoutProps = ({\n schema,\n pageHeight,\n applyRotateTranslate = true,\n}: {\n schema: Schema;\n pageHeight: number;\n applyRotateTranslate?: boolean;\n}) => {\n const { width: mmWidth, height: mmHeight, position, rotate, opacity } = schema;\n const { x: mmX, y: mmY } = position;\n\n const rotateDegrees = rotate ? -rotate : 0;\n const width = mm2pt(mmWidth);\n const height = mm2pt(mmHeight);\n let x = mm2pt(mmX);\n // PDF coordinate system is from bottom left, UI is top left, so we need to flip the y axis\n let y = pageHeight - mm2pt(mmY) - height;\n\n if (rotateDegrees && applyRotateTranslate) {\n // If rotating we must pivot around the same point as the UI performs its rotation.\n // The UI performs rotation around the objects center point (the pivot point below),\n // pdflib rotates around the bottom left corner of the object.\n // We must therefore adjust the X and Y by rotating the bottom left corner by this pivot point.\n const pivotPoint = { x: x + width / 2, y: pageHeight - mm2pt(mmY) - height / 2 };\n const rotatedPoint = rotatePoint({ x, y }, pivotPoint, rotateDegrees);\n x = rotatedPoint.x;\n y = rotatedPoint.y;\n }\n\n return {\n position: { x, y },\n height: height,\n width: width,\n rotate: degrees(rotateDegrees),\n opacity,\n };\n};\n\nexport const rotatePoint = (\n point: { x: number; y: number },\n pivot: { x: number; y: number },\n angleDegrees: number,\n): { x: number; y: number } => {\n const angleRadians = degreesToRadians(angleDegrees);\n\n const x =\n Math.cos(angleRadians) * (point.x - pivot.x) -\n Math.sin(angleRadians) * (point.y - pivot.y) +\n pivot.x;\n const y =\n Math.sin(angleRadians) * (point.x - pivot.x) +\n Math.cos(angleRadians) * (point.y - pivot.y) +\n pivot.y;\n\n return { x, y };\n};\n\nexport const getDynamicHeightsForTable = _getDynamicHeightsForTable;\n\n// ----------------------------------------\n\nexport const addAlphaToHex = (hex: string, alphaPercentage: number) => {\n if (!/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i.test(hex)) {\n throw new Error('Invalid HEX color code');\n }\n const alphaValue = Math.round((alphaPercentage / 100) * 255);\n let alphaHex = alphaValue.toString(16);\n if (alphaHex.length === 1) alphaHex = '0' + alphaHex;\n return hex + alphaHex;\n};\n\nexport const isEditable = (mode: Mode, schema: Schema) =>\n mode === 'designer' || (mode === 'form' && schema.readOnly !== true);\n\nconst hex2rgb = (hex: string) => {\n if (hex.slice(0, 1) === '#') hex = hex.slice(1);\n if (hex.length === 3)\n hex =\n hex.slice(0, 1) +\n hex.slice(0, 1) +\n hex.slice(1, 2) +\n hex.slice(1, 2) +\n hex.slice(2, 3) +\n hex.slice(2, 3);\n\n return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map((str) => parseInt(str, 16));\n};\n\nexport const hex2RgbColor = (hexString: string | undefined) => {\n if (hexString) {\n const isValid = isHexValid(hexString);\n\n if (!isValid) {\n throw new Error(`Invalid hex color value ${hexString}`);\n }\n\n const [r, g, b] = hex2rgb(hexString);\n\n return rgb(r / 255, g / 255, b / 255);\n }\n\n return undefined;\n};\n\nconst hex2CmykColor = (hexString: string | undefined) => {\n if (hexString) {\n const isValid = isHexValid(hexString);\n\n if (!isValid) {\n throw new Error(`Invalid hex color value ${hexString}`);\n }\n\n // Remove the # if it's present\n hexString = hexString.replace('#', '');\n\n // Extract the hexadecimal color code and the opacity\n const hexColor = hexString.substring(0, 6);\n const opacityColor = hexString.substring(6, 8);\n const opacity = opacityColor ? parseInt(opacityColor, 16) / 255 : 1;\n\n // Convert the hex values to decimal\n let r = parseInt(hexColor.substring(0, 2), 16) / 255;\n let g = parseInt(hexColor.substring(2, 4), 16) / 255;\n let b = parseInt(hexColor.substring(4, 6), 16) / 255;\n\n // Apply the opacity\n r = r * opacity + (1 - opacity);\n g = g * opacity + (1 - opacity);\n b = b * opacity + (1 - opacity);\n\n // Calculate the CMYK values\n const k = 1 - Math.max(r, g, b);\n const c = r === 0 ? 0 : (1 - r - k) / (1 - k);\n const m = g === 0 ? 0 : (1 - g - k) / (1 - k);\n const y = b === 0 ? 0 : (1 - b - k) / (1 - k);\n\n return cmyk(c, m, y, k);\n }\n\n return undefined;\n};\n\nexport const hex2PrintingColor = (color?: string | Color, colorType?: ColorType) => {\n // if color is already CMYK, RGB or Grayscale, does not required to convert\n if (typeof color === 'object') return color;\n return colorType?.toLowerCase() == 'cmyk' ? hex2CmykColor(color) : hex2RgbColor(color);\n};\n\nexport const readFile = (input: File | FileList | null): Promise<string | ArrayBuffer> =>\n new Promise((resolve, reject) => {\n const fileReader = new FileReader();\n\n fileReader.onload = (e) => {\n if (e.target?.result) {\n resolve(e.target.result);\n }\n };\n\n fileReader.onerror = () => {\n reject(new Error('[@pdfme/schemas] File reading failed'));\n };\n\n let file: File | null = null;\n if (input instanceof FileList && input.length > 0) {\n file = input[0];\n } else if (input instanceof File) {\n file = input;\n }\n\n if (file) {\n fileReader.readAsDataURL(file);\n } else {\n reject(new Error('[@pdfme/schemas] No files provided'));\n }\n });\n\nexport const createErrorElm = () => {\n const container = document.createElement('div');\n const containerStyle: CSS.Properties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n height: '100%',\n };\n Object.assign(container.style, containerStyle);\n\n const span = document.createElement('span');\n const spanStyle: CSS.Properties = {\n color: 'white',\n background: 'red',\n padding: '0.25rem',\n fontSize: '12pt',\n fontWeight: 'bold',\n borderRadius: '2px',\n fontFamily: \"'Open Sans', sans-serif\",\n };\n Object.assign(span.style, spanStyle);\n\n span.textContent = 'ERROR';\n container.appendChild(span);\n\n return container;\n};\n\nexport const createSvgStr = (icon: IconNode, attrs?: Record<string, string>): string => {\n // In lucide 0.475.0, the icon is an array of elements, not a single SVG element\n // We need to create an SVG wrapper and add the elements as children\n\n const safeTagNames = new Set([\n 'svg',\n 'circle',\n 'ellipse',\n 'g',\n 'line',\n 'path',\n 'polygon',\n 'polyline',\n 'rect',\n ]);\n const safeAttributeNames = new Set([\n 'aria-hidden',\n 'aria-label',\n 'class',\n 'clip-rule',\n 'cx',\n 'cy',\n 'd',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'focusable',\n 'height',\n 'id',\n 'opacity',\n 'points',\n 'preserveAspectRatio',\n 'r',\n 'role',\n 'rx',\n 'ry',\n 'stroke',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke-width',\n 'transform',\n 'vector-effect',\n 'viewBox',\n 'width',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'xmlns:xlink',\n 'y',\n 'y1',\n 'y2',\n ]);\n const escapeHtmlAttribute = (value: string): string =>\n value\n .replaceAll('&', '&')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''')\n .replaceAll('<', '<')\n .replaceAll('>', '>');\n const escapeHtmlText = (value: string): string =>\n value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');\n const toSafeAttributeString = (attributes: Record<string, string>): string =>\n Object.entries(attributes)\n .filter(\n ([key, value]) =>\n safeAttributeNames.has(key) &&\n value !== undefined &&\n value !== null &&\n !key.toLowerCase().startsWith('on'),\n )\n .map(([key, value]) => `${key}=\"${escapeHtmlAttribute(String(value))}\"`)\n .join(' ');\n const toSafeTagName = (tag: unknown): string => {\n const tagName = String(tag);\n if (!safeTagNames.has(tagName)) {\n throw new Error(`Invalid SVG tag name: ${tagName}`);\n }\n return tagName;\n };\n\n // Handle non-array input\n if (!Array.isArray(icon)) {\n return escapeHtmlText(String(icon));\n }\n\n // Create default SVG attributes\n const svgAttrs = {\n xmlns: 'http://www.w3.org/2000/svg',\n width: '24',\n height: '24',\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': '2',\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n ...attrs,\n };\n const svgAttrString = toSafeAttributeString(svgAttrs);\n\n // Helper function to process a single element\n const processElement = (element: unknown): string => {\n if (!Array.isArray(element)) {\n return escapeHtmlText(String(element));\n }\n\n const [tag, attributes = {}, children = []] = element as [\n unknown,\n Record<string, string>,\n unknown[],\n ];\n const tagName = toSafeTagName(tag);\n const attrString = toSafeAttributeString(attributes);\n\n // Process children recursively\n let childrenString = '';\n\n if (Array.isArray(children) && children.length > 0) {\n childrenString = children.map((child) => processElement(child)).join('');\n }\n\n // Return properly formatted element string\n if (childrenString) {\n return `<${String(tagName)}${attrString ? ' ' + String(attrString) : ''}>${childrenString}</${String(tagName)}>`;\n } else {\n // Self-closing tag for empty children\n return `<${String(tagName)}${attrString ? ' ' + String(attrString) : ''}/>`;\n }\n };\n\n // Process all elements and join them\n const elementsString = Array.isArray(icon)\n ? icon.map((element) => processElement(element)).join('')\n : processElement(icon);\n\n // Return the complete SVG string\n return `<svg ${svgAttrString}>${elementsString}</svg>`;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pdfme/schemas",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4-dev.1",
|
|
4
4
|
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pdf",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
},
|
|
23
23
|
"type": "module",
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
25
29
|
"main": "./dist/index.js",
|
|
26
30
|
"module": "./dist/index.js",
|
|
27
31
|
"types": "./dist/index.d.ts",
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const BARCODE_TYPES = [
|
|
2
|
-
'qrcode',
|
|
3
|
-
'japanpost',
|
|
4
|
-
'ean13',
|
|
5
|
-
'ean8',
|
|
6
|
-
'code39',
|
|
7
|
-
'code128',
|
|
8
|
-
'nw7',
|
|
9
|
-
'itf14',
|
|
10
|
-
'upca',
|
|
11
|
-
'upce',
|
|
12
|
-
'gs1datamatrix',
|
|
13
|
-
'pdf417',
|
|
14
|
-
] as const;
|
|
15
|
-
|
|
16
|
-
export const DEFAULT_BARCODE_BG_COLOR = '#ffffff';
|
|
17
|
-
|
|
18
|
-
export const DEFAULT_BARCODE_COLOR = '#000000';
|
|
19
|
-
|
|
20
|
-
export const DEFAULT_BARCODE_INCLUDETEXT = true;
|
package/src/barcodes/helper.ts
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { b64toUint8Array } from '@pdfme/common';
|
|
2
|
-
import bwipjs, { RenderOptions } from 'bwip-js';
|
|
3
|
-
import { Buffer } from 'buffer';
|
|
4
|
-
import { BARCODE_TYPES, DEFAULT_BARCODE_INCLUDETEXT } from './constants.js';
|
|
5
|
-
import { BarcodeTypes } from './types.js';
|
|
6
|
-
|
|
7
|
-
// GTIN-13, GTIN-8, GTIN-12, GTIN-14
|
|
8
|
-
const validateCheckDigit = (input: string, checkDigitPos: number) => {
|
|
9
|
-
let passCheckDigit = true;
|
|
10
|
-
|
|
11
|
-
if (input.length === checkDigitPos) {
|
|
12
|
-
const ds = input.slice(0, -1).replace(/[^0-9]/g, '');
|
|
13
|
-
let sum = 0;
|
|
14
|
-
let odd = 1;
|
|
15
|
-
for (let i = ds.length - 1; i > -1; i -= 1) {
|
|
16
|
-
sum += Number(ds[i]) * (odd ? 3 : 1);
|
|
17
|
-
odd ^= 1;
|
|
18
|
-
if (sum > 0xffffffffffff) {
|
|
19
|
-
// ~2^48 at max
|
|
20
|
-
sum %= 10;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
passCheckDigit = String(10 - (sum % 10)).slice(-1) === input.slice(-1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return passCheckDigit;
|
|
27
|
-
};
|
|
28
|
-
export const validateBarcodeInput = (type: BarcodeTypes, input: string) => {
|
|
29
|
-
if (!input) return false;
|
|
30
|
-
|
|
31
|
-
if (!BARCODE_TYPES.includes(type)) return false;
|
|
32
|
-
|
|
33
|
-
if (type === 'qrcode') {
|
|
34
|
-
// Up to 500 characters
|
|
35
|
-
return input.length < 500;
|
|
36
|
-
}
|
|
37
|
-
if (type === 'japanpost') {
|
|
38
|
-
// For Japan Post: Postal codes must be digits (0-9) only.
|
|
39
|
-
// Address display numbers can use alphanumeric characters (0-9, A-Z) and hyphen (-).
|
|
40
|
-
const regexp = /^(\d{7})(\d|[A-Z]|-)+$/;
|
|
41
|
-
return regexp.test(input);
|
|
42
|
-
}
|
|
43
|
-
if (type === 'ean13') {
|
|
44
|
-
// For EAN-13: Valid characters are digits (0-9) only.
|
|
45
|
-
// Either 12 digits (without check digit) or 13 digits (with check digit).
|
|
46
|
-
const regexp = /^\d{12}$|^\d{13}$/;
|
|
47
|
-
return regexp.test(input) && validateCheckDigit(input, 13);
|
|
48
|
-
}
|
|
49
|
-
if (type === 'ean8') {
|
|
50
|
-
// For EAN-8: Valid characters are digits (0-9) only.
|
|
51
|
-
// Either 7 digits (without check digit) or 8 digits (with check digit).
|
|
52
|
-
const regexp = /^\d{7}$|^\d{8}$/;
|
|
53
|
-
return regexp.test(input) && validateCheckDigit(input, 8);
|
|
54
|
-
}
|
|
55
|
-
if (type === 'code39') {
|
|
56
|
-
// For Code39: Valid characters are digits (0-9), uppercase alphabets (A-Z),
|
|
57
|
-
// symbols (-, ., $, /, +, %), and space.
|
|
58
|
-
const regexp = /^(\d|[A-Z]|[-.$/+%]|\s)+$/;
|
|
59
|
-
return regexp.test(input);
|
|
60
|
-
}
|
|
61
|
-
if (type === 'code128') {
|
|
62
|
-
// For Code128: Valid characters are all except Kanji, Hiragana, and Katakana.
|
|
63
|
-
// https://qiita.com/graminume/items/2ac8dd9c32277fa9da64
|
|
64
|
-
return !input.match(
|
|
65
|
-
/([\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]|[A-Za-z0-9!"#$%&'()*+,-./:;<=>?@[\]^_`{|}〜 ])+/,
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
if (type === 'nw7') {
|
|
69
|
-
// For NW-7: Valid characters are digits (0-9) and symbols (-, ., $, :, /, +).
|
|
70
|
-
// The first and last characters must be one of the alphabets A-D (start/stop codes).
|
|
71
|
-
const regexp = /^[A-Da-d]([0-9.$:/+-])+[A-Da-d]$/;
|
|
72
|
-
return regexp.test(input);
|
|
73
|
-
}
|
|
74
|
-
if (type === 'itf14') {
|
|
75
|
-
// For ITF-14: Valid characters are digits (0-9) only.
|
|
76
|
-
// Either 13 digits (without check digit) or 14 digits (with check digit).
|
|
77
|
-
const regexp = /^\d{13}$|^\d{14}$/;
|
|
78
|
-
return regexp.test(input) && validateCheckDigit(input, 14);
|
|
79
|
-
}
|
|
80
|
-
if (type === 'upca') {
|
|
81
|
-
// For UPCA: Valid characters are digits (0-9) only.
|
|
82
|
-
// Either 11 digits (without check digit) or 12 digits (with check digit).
|
|
83
|
-
const regexp = /^\d{11}$|^\d{12}$/;
|
|
84
|
-
return regexp.test(input) && validateCheckDigit(input, 12);
|
|
85
|
-
}
|
|
86
|
-
if (type === 'upce') {
|
|
87
|
-
// For UPCE: Valid characters are digits (0-9) only.
|
|
88
|
-
// The first digit (number system character) must be 0.
|
|
89
|
-
// Either 7 digits (without check digit) or 8 digits (with check digit).
|
|
90
|
-
const regexp = /^0(\d{6}$|\d{7}$)/;
|
|
91
|
-
return regexp.test(input) && validateCheckDigit(input, 8);
|
|
92
|
-
}
|
|
93
|
-
if (type === 'gs1datamatrix') {
|
|
94
|
-
let ret = false;
|
|
95
|
-
// Find the GTIN application identifier: regex for "(01)" and the digits following it until another "(".
|
|
96
|
-
const regexp = /\((01)\)(\d*)(\(|$)/;
|
|
97
|
-
let res = input.match(regexp);
|
|
98
|
-
if (
|
|
99
|
-
res != null &&
|
|
100
|
-
input.length <= 52 && // 52 is the max length of a GS1 DataMatrix barcode before bwip-js throws an error
|
|
101
|
-
res[1] === '01' &&
|
|
102
|
-
(res[2].length === 14 || res[2].length === 8 || res[2].length === 12 || res[2].length === 13)
|
|
103
|
-
) {
|
|
104
|
-
let gtin = res[2];
|
|
105
|
-
ret = validateCheckDigit(gtin, gtin.length);
|
|
106
|
-
}
|
|
107
|
-
return ret;
|
|
108
|
-
}
|
|
109
|
-
if (type === 'pdf417') {
|
|
110
|
-
// PDF417 can encode a wide range of characters,
|
|
111
|
-
// but considering performance and library limitations, the maximum number of characters is limited (up to 1000 characters here).
|
|
112
|
-
return input.length > 0 && input.length <= 1000;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return false;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* The bwip.js lib has a different name for nw7 type barcodes
|
|
120
|
-
*/
|
|
121
|
-
export const barCodeType2Bcid = (type: BarcodeTypes) =>
|
|
122
|
-
type === 'nw7' ? 'rationalizedCodabar' : type;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Strip hash from the beginning of HTML hex color codes for the bwip.js lib
|
|
126
|
-
*/
|
|
127
|
-
export const mapHexColorForBwipJsLib = (color: string | undefined, fallback?: string) =>
|
|
128
|
-
color ? color.replace('#', '') : fallback ? fallback.replace('#', '') : '000000';
|
|
129
|
-
|
|
130
|
-
export const createBarCode = async (arg: {
|
|
131
|
-
type: BarcodeTypes;
|
|
132
|
-
input: string;
|
|
133
|
-
width: number;
|
|
134
|
-
height: number;
|
|
135
|
-
backgroundColor?: string;
|
|
136
|
-
barColor?: string;
|
|
137
|
-
textColor?: string;
|
|
138
|
-
includetext?: boolean;
|
|
139
|
-
}): Promise<Buffer> => {
|
|
140
|
-
const {
|
|
141
|
-
type,
|
|
142
|
-
input,
|
|
143
|
-
width,
|
|
144
|
-
height,
|
|
145
|
-
backgroundColor,
|
|
146
|
-
barColor,
|
|
147
|
-
textColor,
|
|
148
|
-
includetext = DEFAULT_BARCODE_INCLUDETEXT,
|
|
149
|
-
} = arg;
|
|
150
|
-
|
|
151
|
-
const bcid = barCodeType2Bcid(type);
|
|
152
|
-
const scale = 5;
|
|
153
|
-
const bwipjsArg: RenderOptions = {
|
|
154
|
-
bcid,
|
|
155
|
-
text: input,
|
|
156
|
-
width,
|
|
157
|
-
height,
|
|
158
|
-
scale,
|
|
159
|
-
includetext,
|
|
160
|
-
textxalign: 'center',
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
if (backgroundColor) bwipjsArg.backgroundcolor = mapHexColorForBwipJsLib(backgroundColor);
|
|
164
|
-
if (barColor) bwipjsArg.barcolor = mapHexColorForBwipJsLib(barColor);
|
|
165
|
-
if (textColor) bwipjsArg.textcolor = mapHexColorForBwipJsLib(textColor);
|
|
166
|
-
|
|
167
|
-
let res: Buffer;
|
|
168
|
-
|
|
169
|
-
if (typeof window !== 'undefined') {
|
|
170
|
-
const canvas = document.createElement('canvas');
|
|
171
|
-
// Use a type assertion to safely call toCanvas
|
|
172
|
-
const bwipjsModule = bwipjs as unknown as {
|
|
173
|
-
toCanvas(canvas: HTMLCanvasElement, options: RenderOptions): void;
|
|
174
|
-
};
|
|
175
|
-
bwipjsModule.toCanvas(canvas, bwipjsArg);
|
|
176
|
-
const dataUrl = canvas.toDataURL('image/png');
|
|
177
|
-
res = Buffer.from(b64toUint8Array(dataUrl).buffer);
|
|
178
|
-
} else {
|
|
179
|
-
// Use a type assertion to safely call toBuffer
|
|
180
|
-
const bwipjsModule = bwipjs as unknown as {
|
|
181
|
-
toBuffer(options: RenderOptions): Promise<Buffer>;
|
|
182
|
-
};
|
|
183
|
-
res = await bwipjsModule.toBuffer(bwipjsArg);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return res;
|
|
187
|
-
};
|
package/src/barcodes/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { pdfRender } from './pdfRender.js';
|
|
2
|
-
import { getPropPanelByBarcodeType } from './propPanel.js';
|
|
3
|
-
import { uiRender } from './uiRender.js';
|
|
4
|
-
import type { BarcodeSchema, BarcodeTypes } from './types.js';
|
|
5
|
-
import { BARCODE_TYPES } from './constants.js';
|
|
6
|
-
import { createSvgStr } from '../utils.js';
|
|
7
|
-
import { Plugin } from '@pdfme/common';
|
|
8
|
-
import { QrCode, Barcode } from 'lucide';
|
|
9
|
-
|
|
10
|
-
const barcodes = BARCODE_TYPES.reduce(
|
|
11
|
-
(acc, type) =>
|
|
12
|
-
Object.assign(acc, {
|
|
13
|
-
[type]: {
|
|
14
|
-
pdf: pdfRender,
|
|
15
|
-
ui: uiRender,
|
|
16
|
-
propPanel: getPropPanelByBarcodeType(type),
|
|
17
|
-
icon: createSvgStr(type == 'qrcode' ? QrCode : Barcode),
|
|
18
|
-
},
|
|
19
|
-
}),
|
|
20
|
-
{} as Record<BarcodeTypes, Plugin<BarcodeSchema>>,
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
export default barcodes;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { PDFRenderProps } from '@pdfme/common';
|
|
2
|
-
import { convertForPdfLayoutProps } from '../utils.js';
|
|
3
|
-
import type { BarcodeSchema } from './types.js';
|
|
4
|
-
import { createBarCode, validateBarcodeInput } from './helper.js';
|
|
5
|
-
import { PDFImage } from '@pdfme/pdf-lib';
|
|
6
|
-
|
|
7
|
-
const getBarcodeCacheKey = (schema: BarcodeSchema, value: string) => {
|
|
8
|
-
return `${schema.type}${schema.backgroundColor}${schema.barColor}${schema.textColor}${value}${schema.includetext}`;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const pdfRender = async (arg: PDFRenderProps<BarcodeSchema>) => {
|
|
12
|
-
const { value, schema, pdfDoc, page, _cache } = arg;
|
|
13
|
-
if (!validateBarcodeInput(schema.type, value)) return;
|
|
14
|
-
|
|
15
|
-
const inputBarcodeCacheKey = getBarcodeCacheKey(schema, value);
|
|
16
|
-
let image = _cache.get(inputBarcodeCacheKey) as PDFImage | undefined;
|
|
17
|
-
if (!image) {
|
|
18
|
-
const imageBuf = await createBarCode({
|
|
19
|
-
...schema,
|
|
20
|
-
type: schema.type,
|
|
21
|
-
input: value,
|
|
22
|
-
});
|
|
23
|
-
image = await pdfDoc.embedPng(imageBuf);
|
|
24
|
-
_cache.set(inputBarcodeCacheKey, image);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const pageHeight = page.getHeight();
|
|
28
|
-
const {
|
|
29
|
-
width,
|
|
30
|
-
height,
|
|
31
|
-
rotate,
|
|
32
|
-
position: { x, y },
|
|
33
|
-
opacity,
|
|
34
|
-
} = convertForPdfLayoutProps({ schema, pageHeight });
|
|
35
|
-
|
|
36
|
-
page.drawImage(image, { x, y, rotate, width, height, opacity });
|
|
37
|
-
};
|