@hellkite/pipkin 0.7.0 → 0.8.2
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/build/src/lib/bundler.js.map +1 -1
- package/build/src/lib/index.d.ts +0 -1
- package/build/src/lib/index.js +0 -1
- package/build/src/lib/index.js.map +1 -1
- package/build/src/lib/replacement.d.ts +5 -3
- package/build/src/lib/replacement.js +6 -3
- package/build/src/lib/replacement.js.map +1 -1
- package/build/src/lib/template.d.ts +25 -20
- package/build/src/lib/template.js +176 -45
- package/build/src/lib/template.js.map +1 -1
- package/build/src/lib/types/containers.js +2 -7
- package/build/src/lib/types/containers.js.map +1 -1
- package/build/src/lib/types/hypernode.d.ts +1 -1
- package/build/src/lib/types/image.d.ts +6 -5
- package/build/src/lib/types/image.js +2 -7
- package/build/src/lib/types/image.js.map +1 -1
- package/build/src/lib/types/index.d.ts +2 -0
- package/build/src/lib/types/index.js +2 -0
- package/build/src/lib/types/index.js.map +1 -1
- package/build/src/lib/types/layer.d.ts +10 -1
- package/build/src/lib/types/layer.js +7 -0
- package/build/src/lib/types/layer.js.map +1 -1
- package/build/src/lib/types/pdf.d.ts +1 -0
- package/build/src/lib/types/pdf.js +3 -0
- package/build/src/lib/types/pdf.js.map +1 -0
- package/build/src/lib/types/replacement.d.ts +2 -2
- package/build/src/lib/types/template.d.ts +13 -0
- package/build/src/lib/types/template.js +10 -0
- package/build/src/lib/types/template.js.map +1 -0
- package/build/src/lib/types/text.d.ts +2 -2
- package/build/src/lib/types/text.js +3 -10
- package/build/src/lib/types/text.js.map +1 -1
- package/build/src/lib/utils/container.js.map +1 -1
- package/build/src/lib/utils/htmlToImage.js +0 -1
- package/build/src/lib/utils/htmlToImage.js.map +1 -1
- package/build/src/lib/utils/imagesToPdf.d.ts +2 -0
- package/build/src/lib/utils/imagesToPdf.js +31 -0
- package/build/src/lib/utils/imagesToPdf.js.map +1 -0
- package/build/src/lib/utils/index.d.ts +1 -2
- package/build/src/lib/utils/index.js +1 -2
- package/build/src/lib/utils/index.js.map +1 -1
- package/build/src/lib/utils/placeBoundingBox.js +11 -3
- package/build/src/lib/utils/placeBoundingBox.js.map +1 -1
- package/build/src/lib/utils/reduceBoundingBox.d.ts +2 -0
- package/build/src/lib/utils/reduceBoundingBox.js +16 -0
- package/build/src/lib/utils/reduceBoundingBox.js.map +1 -0
- package/build/src/test.js +115 -27
- package/build/src/test.js.map +1 -1
- package/package.json +2 -1
- package/roadmap.md +1 -0
- package/src/lib/bundler.ts +1 -1
- package/src/lib/index.ts +0 -1
- package/src/lib/template.ts +327 -84
- package/src/lib/types/containers.ts +3 -5
- package/src/lib/types/hypernode.ts +1 -2
- package/src/lib/types/image.ts +15 -10
- package/src/lib/types/index.ts +2 -0
- package/src/lib/types/layer.ts +24 -1
- package/src/lib/types/pdf.ts +1 -0
- package/src/lib/types/render.ts +2 -4
- package/src/lib/types/replacement.ts +2 -2
- package/src/lib/types/template.ts +22 -0
- package/src/lib/types/text.ts +6 -7
- package/src/lib/utils/container.ts +0 -1
- package/src/lib/utils/htmlToImage.ts +0 -1
- package/src/lib/utils/imagesToPdf.ts +24 -0
- package/src/lib/utils/index.ts +1 -2
- package/src/lib/utils/placeBoundingBox.ts +33 -13
- package/src/lib/utils/reduceBoundingBox.ts +21 -0
- package/src/lib/replacement.ts +0 -21
- package/src/lib/utils/placeImage.ts +0 -69
- package/src/lib/utils/placeText.ts +0 -110
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type PDFData = Uint8Array<ArrayBufferLike>;
|
package/src/lib/types/render.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
export type RenderOptions<EntryType extends Record<string, string>> = {
|
|
4
2
|
duplication?: DuplicationOptions<EntryType>;
|
|
5
|
-
}
|
|
3
|
+
};
|
|
6
4
|
|
|
7
5
|
export type DuplicationOptions<EntryType extends Record<string, string>> = {
|
|
8
6
|
/**
|
|
@@ -20,4 +18,4 @@ export type DuplicationOptions<EntryType extends Record<string, string>> = {
|
|
|
20
18
|
* default: 1
|
|
21
19
|
*/
|
|
22
20
|
default?: number;
|
|
23
|
-
}
|
|
21
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StaticImageRef } from './image';
|
|
2
2
|
|
|
3
|
-
export type ReplacementMap = Record<string,
|
|
3
|
+
export type ReplacementMap = Record<string, StaticImageRef>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { rgbaToInt } from 'jimp';
|
|
2
|
+
|
|
3
|
+
type RequiredTemplateOptions = {
|
|
4
|
+
height: number;
|
|
5
|
+
width: number;
|
|
6
|
+
color: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type OptionalTemplateOptions = Partial<{
|
|
10
|
+
defaultFontFamily: string;
|
|
11
|
+
defaultAssetsPath: string;
|
|
12
|
+
// TODO: defaultOutputDirectoryPath
|
|
13
|
+
debug: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export type TemplateOptions = RequiredTemplateOptions & OptionalTemplateOptions;
|
|
17
|
+
|
|
18
|
+
export const DEFAULT_TEMPLATE_OPTIONS: RequiredTemplateOptions = {
|
|
19
|
+
height: 1050,
|
|
20
|
+
width: 750,
|
|
21
|
+
color: rgbaToInt(255, 255, 255, 255),
|
|
22
|
+
};
|
package/src/lib/types/text.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RequiredDeep } from 'type-fest';
|
|
2
|
-
import { LayerOptions } from './layer';
|
|
3
|
-
import {
|
|
2
|
+
import { DEFAULT_LAYER_OPTIONS, LayerOptions } from './layer';
|
|
3
|
+
import { Replacement } from '../template';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Static text -> `text`
|
|
@@ -42,8 +42,9 @@ export type TextLayerOptions<EntryType extends Record<string, string>> =
|
|
|
42
42
|
color?: string;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
replacementFn?: (replace: Replacement) => Replacement;
|
|
46
|
+
|
|
45
47
|
// TODO: processor fn
|
|
46
|
-
replacement?: ReplacementMap;
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
export const DEFAULT_FONT: Required<FontOptions> = {
|
|
@@ -59,12 +60,10 @@ export type TextLayerSpecificOptions<EntryType extends Record<string, string>> =
|
|
|
59
60
|
export const DEFAULT_TEXT_LAYER_OPTIONS: RequiredDeep<
|
|
60
61
|
TextLayerOptions<Record<string, string>>
|
|
61
62
|
> = {
|
|
62
|
-
|
|
63
|
-
alignItems: 'center',
|
|
63
|
+
...DEFAULT_LAYER_OPTIONS,
|
|
64
64
|
font: DEFAULT_FONT,
|
|
65
65
|
color: 'black',
|
|
66
|
-
|
|
67
|
-
skip: false,
|
|
66
|
+
replacementFn: replacement => replacement,
|
|
68
67
|
border: {
|
|
69
68
|
width: 0,
|
|
70
69
|
color: 'black',
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PDFDocument } from 'pdf-lib';
|
|
2
|
+
import { ImageType, PDFData } from '../types';
|
|
3
|
+
|
|
4
|
+
export const imagesToPdf = async (
|
|
5
|
+
images: Array<ImageType>,
|
|
6
|
+
): Promise<PDFData> => {
|
|
7
|
+
const pdf = await PDFDocument.create();
|
|
8
|
+
|
|
9
|
+
for (const image of images) {
|
|
10
|
+
const imageBase64 = await image.getBase64('image/png');
|
|
11
|
+
const embeddedImage = await pdf.embedPng(imageBase64);
|
|
12
|
+
const { width, height } = embeddedImage.scale(1);
|
|
13
|
+
const page = pdf.addPage([width, height]);
|
|
14
|
+
|
|
15
|
+
page.drawImage(embeddedImage, {
|
|
16
|
+
x: 0,
|
|
17
|
+
y: 0,
|
|
18
|
+
width,
|
|
19
|
+
height,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return pdf.save();
|
|
24
|
+
};
|
package/src/lib/utils/index.ts
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
import { h } from 'virtual-dom';
|
|
2
2
|
import { boundingBoxToPx } from './toPx';
|
|
3
3
|
import { BoundingBox, HyperNode } from '../types';
|
|
4
|
+
import { reduceBoundingBox } from './reduceBoundingBox';
|
|
4
5
|
|
|
5
|
-
export const placeBoundingBox = async (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
export const placeBoundingBox = async (
|
|
7
|
+
box: BoundingBox,
|
|
8
|
+
): Promise<HyperNode> => {
|
|
9
|
+
const borderWidthPx = 2;
|
|
10
|
+
const reducedBoundingBox = reduceBoundingBox(box, borderWidthPx);
|
|
11
|
+
return h('div', {}, [
|
|
12
|
+
h(
|
|
13
|
+
'div',
|
|
14
|
+
{
|
|
15
|
+
style: {
|
|
16
|
+
position: 'absolute',
|
|
17
|
+
border: `${borderWidthPx}px solid red`,
|
|
18
|
+
background: 'transparent',
|
|
19
|
+
boxSizing: 'border-box',
|
|
20
|
+
...boundingBoxToPx(box),
|
|
21
|
+
},
|
|
15
22
|
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
[],
|
|
24
|
+
),
|
|
25
|
+
h(
|
|
26
|
+
'div',
|
|
27
|
+
{
|
|
28
|
+
style: {
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
border: `${borderWidthPx}px dashed blue`,
|
|
31
|
+
background: 'transparent',
|
|
32
|
+
boxSizing: 'border-box',
|
|
33
|
+
...boundingBoxToPx(reducedBoundingBox),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
[],
|
|
37
|
+
),
|
|
38
|
+
]);
|
|
19
39
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BoundingBox } from '../types';
|
|
2
|
+
|
|
3
|
+
type KeysOfUnion<T> = T extends unknown ? keyof T : never;
|
|
4
|
+
|
|
5
|
+
export const reduceBoundingBox = (
|
|
6
|
+
boundingBox: BoundingBox,
|
|
7
|
+
reduceWithPx: number,
|
|
8
|
+
): BoundingBox => {
|
|
9
|
+
return (Object.entries(boundingBox) as [KeysOfUnion<BoundingBox>, number][])
|
|
10
|
+
.map(([key, value]) => [
|
|
11
|
+
key,
|
|
12
|
+
value +
|
|
13
|
+
(key === 'width' || key === 'height'
|
|
14
|
+
? -reduceWithPx * 2
|
|
15
|
+
: reduceWithPx),
|
|
16
|
+
])
|
|
17
|
+
.reduce(
|
|
18
|
+
(box, [key, value]) => ({ ...box, [key]: value }),
|
|
19
|
+
{} as BoundingBox,
|
|
20
|
+
);
|
|
21
|
+
};
|
package/src/lib/replacement.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ReplacementMap, ImageType } from "./types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a replacement map between sets of words and symbols
|
|
5
|
-
*/
|
|
6
|
-
export class Replacement {
|
|
7
|
-
|
|
8
|
-
private readonly replacementMap: ReplacementMap = {};
|
|
9
|
-
|
|
10
|
-
replace(words: Array<string>, symbol: ImageType): this {
|
|
11
|
-
words.forEach(word => {
|
|
12
|
-
this.replacementMap[word] = symbol.clone();
|
|
13
|
-
});
|
|
14
|
-
return this;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
build(): ReplacementMap {
|
|
18
|
-
return this.replacementMap;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { h } from 'virtual-dom';
|
|
2
|
-
import { boundingBoxToPx } from './toPx';
|
|
3
|
-
import {
|
|
4
|
-
ImageLayerOptions,
|
|
5
|
-
ImageType,
|
|
6
|
-
BoundingBox,
|
|
7
|
-
SCALE_MODE_TO_OBJECT_FIT,
|
|
8
|
-
HyperNode,
|
|
9
|
-
ImageLayerSpecificOptions,
|
|
10
|
-
} from '../types';
|
|
11
|
-
import { RequiredDeep } from 'type-fest';
|
|
12
|
-
|
|
13
|
-
type PlaceImageProps<EntryType extends Record<string, string>> = {
|
|
14
|
-
image: ImageType;
|
|
15
|
-
box: BoundingBox;
|
|
16
|
-
options: RequiredDeep<ImageLayerOptions<EntryType>>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const placeImage = async <EntryType extends Record<string, string>>({
|
|
20
|
-
image,
|
|
21
|
-
box,
|
|
22
|
-
options,
|
|
23
|
-
}: PlaceImageProps<EntryType>): Promise<HyperNode> => {
|
|
24
|
-
return h(
|
|
25
|
-
'div',
|
|
26
|
-
{
|
|
27
|
-
style: {
|
|
28
|
-
display: 'flex',
|
|
29
|
-
position: 'absolute',
|
|
30
|
-
scale: 1,
|
|
31
|
-
|
|
32
|
-
justifyContent: options.justifyContent,
|
|
33
|
-
alignItems: options.alignItems,
|
|
34
|
-
|
|
35
|
-
...boundingBoxToPx(box),
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
[await prepareImage({ image, options })],
|
|
39
|
-
);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
type PrepareImageProps<EntryType extends Record<string, string>> = {
|
|
43
|
-
image: ImageType;
|
|
44
|
-
options: RequiredDeep<ImageLayerSpecificOptions<EntryType>>;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const prepareImage = async <EntryType extends Record<string, string>>({
|
|
48
|
-
image,
|
|
49
|
-
options,
|
|
50
|
-
}: PrepareImageProps<EntryType>): Promise<HyperNode> => {
|
|
51
|
-
const imageBase64 = await image.getBase64('image/png');
|
|
52
|
-
const objectFit = SCALE_MODE_TO_OBJECT_FIT[options.scale];
|
|
53
|
-
|
|
54
|
-
return h(
|
|
55
|
-
'img',
|
|
56
|
-
{
|
|
57
|
-
style: {
|
|
58
|
-
objectFit,
|
|
59
|
-
flex: '1 1 auto',
|
|
60
|
-
minWidth: 0,
|
|
61
|
-
minHeight: 0,
|
|
62
|
-
maxWidth: '100%',
|
|
63
|
-
maxHeight: '100%',
|
|
64
|
-
},
|
|
65
|
-
src: imageBase64,
|
|
66
|
-
},
|
|
67
|
-
[],
|
|
68
|
-
);
|
|
69
|
-
};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { h } from 'virtual-dom';
|
|
2
|
-
import {
|
|
3
|
-
BoundingBox,
|
|
4
|
-
TextLayerOptions,
|
|
5
|
-
HyperNode,
|
|
6
|
-
TextLayerSpecificOptions,
|
|
7
|
-
} from '../types';
|
|
8
|
-
import { boundingBoxToPx, toPx } from './toPx';
|
|
9
|
-
import { RequiredDeep } from 'type-fest';
|
|
10
|
-
|
|
11
|
-
type PlaceTextProps<EntryType extends Record<string, string>> = {
|
|
12
|
-
text: string;
|
|
13
|
-
box: BoundingBox;
|
|
14
|
-
options: RequiredDeep<TextLayerOptions<EntryType>>;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const placeText = async <EntryType extends Record<string, string>>({
|
|
18
|
-
text,
|
|
19
|
-
box,
|
|
20
|
-
options,
|
|
21
|
-
}: PlaceTextProps<EntryType>): Promise<HyperNode> => {
|
|
22
|
-
return h(
|
|
23
|
-
'div',
|
|
24
|
-
{
|
|
25
|
-
style: {
|
|
26
|
-
display: 'flex',
|
|
27
|
-
overflow: 'visible',
|
|
28
|
-
position: 'absolute',
|
|
29
|
-
|
|
30
|
-
justifyContent: options.justifyContent,
|
|
31
|
-
alignItems: options.alignItems,
|
|
32
|
-
|
|
33
|
-
...boundingBoxToPx(box),
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
[
|
|
37
|
-
await prepareText({
|
|
38
|
-
text,
|
|
39
|
-
options,
|
|
40
|
-
}),
|
|
41
|
-
],
|
|
42
|
-
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
type PrepareTextProps<EntryType extends Record<string, string>> = {
|
|
46
|
-
text: string;
|
|
47
|
-
options: RequiredDeep<TextLayerSpecificOptions<EntryType>>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const prepareText = async <EntryType extends Record<string, string>>({
|
|
51
|
-
text,
|
|
52
|
-
options,
|
|
53
|
-
}: PrepareTextProps<EntryType>): Promise<HyperNode> => {
|
|
54
|
-
let textChildren: Array<string | HyperNode> = [text];
|
|
55
|
-
for (const [word, image] of Object.entries(options.replacement)) {
|
|
56
|
-
const regex = new RegExp(word, 'gi');
|
|
57
|
-
const imageBase64 = await image.getBase64('image/png');
|
|
58
|
-
|
|
59
|
-
let tmpChildren: Array<string | HyperNode> = [];
|
|
60
|
-
for (const textSegment of textChildren) {
|
|
61
|
-
if (typeof textSegment !== 'string') {
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const parts = (textSegment as string).split(regex);
|
|
66
|
-
for (let index = 0; index < parts.length; index++) {
|
|
67
|
-
if (index > 0) {
|
|
68
|
-
tmpChildren.push(
|
|
69
|
-
h(
|
|
70
|
-
'img',
|
|
71
|
-
{
|
|
72
|
-
style: {
|
|
73
|
-
display: 'inline',
|
|
74
|
-
verticalAlign: 'middle',
|
|
75
|
-
height: toPx(options.font.size),
|
|
76
|
-
width: 'auto',
|
|
77
|
-
},
|
|
78
|
-
src: imageBase64,
|
|
79
|
-
},
|
|
80
|
-
[],
|
|
81
|
-
),
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
tmpChildren.push(parts[index]);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
textChildren = tmpChildren;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return h(
|
|
92
|
-
'div',
|
|
93
|
-
{
|
|
94
|
-
style: {
|
|
95
|
-
overflow: 'visible',
|
|
96
|
-
overflowWrap: 'word-wrap',
|
|
97
|
-
whiteSpace: 'normal',
|
|
98
|
-
|
|
99
|
-
color: options.color,
|
|
100
|
-
fontFamily: options.font.family,
|
|
101
|
-
fontSize: options.font.size,
|
|
102
|
-
fontStyle: options.font.italic ? 'italic' : undefined,
|
|
103
|
-
fontWeight: options.font.bold ? 'bold' : undefined,
|
|
104
|
-
|
|
105
|
-
'-webkit-text-stroke': `${options.border.width}px ${options.border.color}`,
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
textChildren,
|
|
109
|
-
);
|
|
110
|
-
};
|