@pdfme/common 1.0.0-beta.10
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/.eslintrc.js +31 -0
- package/declaration.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.LICENSE.txt +6 -0
- package/dist/index.js.map +1 -0
- package/dist/types/constants.d.ts +6 -0
- package/dist/types/helper.d.ts +15 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/schema.d.ts +3613 -0
- package/dist/types/type.d.ts +64 -0
- package/package.json +57 -0
- package/src/assets/Helvetica.ttf +0 -0
- package/src/constants.ts +8 -0
- package/src/helper.ts +214 -0
- package/src/index.ts +95 -0
- package/src/schema.ts +118 -0
- package/src/type.ts +58 -0
- package/tsconfig.json +21 -0
- package/webpack.config.js +54 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
import { Lang, Size, Alignment, BarcodeSchemaType, SchemaType, CommonSchema as _CommonSchema, TextSchema, ImageSchema, BarcodeSchema, Schema, SchemaForUI, Font, BasePdf, Template, CommonProps, GeneratorOptions, GenerateProps, UIOptions, UIProps, PreviewProps, PreviewReactProps, DesignerProps, DesignerReactProps } from './schema';
|
3
|
+
declare type CommonSchema = z.infer<typeof _CommonSchema>;
|
4
|
+
export declare const schemaTypes: readonly ["text", "image", "qrcode", "japanpost", "ean13", "ean8", "code39", "code128", "nw7", "itf14", "upca", "upce"];
|
5
|
+
export declare const isTextSchema: (arg: CommonSchema) => arg is {
|
6
|
+
rotate?: number | undefined;
|
7
|
+
alignment?: "left" | "center" | "right" | undefined;
|
8
|
+
fontSize?: number | undefined;
|
9
|
+
fontName?: string | undefined;
|
10
|
+
fontColor?: string | undefined;
|
11
|
+
backgroundColor?: string | undefined;
|
12
|
+
characterSpacing?: number | undefined;
|
13
|
+
lineHeight?: number | undefined;
|
14
|
+
type: "text";
|
15
|
+
position: {
|
16
|
+
x: number;
|
17
|
+
y: number;
|
18
|
+
};
|
19
|
+
width: number;
|
20
|
+
height: number;
|
21
|
+
};
|
22
|
+
export declare const isImageSchema: (arg: CommonSchema) => arg is {
|
23
|
+
rotate?: number | undefined;
|
24
|
+
type: "image";
|
25
|
+
position: {
|
26
|
+
x: number;
|
27
|
+
y: number;
|
28
|
+
};
|
29
|
+
width: number;
|
30
|
+
height: number;
|
31
|
+
};
|
32
|
+
export declare const isBarcodeSchema: (arg: CommonSchema) => arg is {
|
33
|
+
rotate?: number | undefined;
|
34
|
+
type: "qrcode" | "japanpost" | "ean13" | "ean8" | "code39" | "code128" | "nw7" | "itf14" | "upca" | "upce";
|
35
|
+
position: {
|
36
|
+
x: number;
|
37
|
+
y: number;
|
38
|
+
};
|
39
|
+
width: number;
|
40
|
+
height: number;
|
41
|
+
};
|
42
|
+
export declare type Lang = z.infer<typeof Lang>;
|
43
|
+
export declare type Size = z.infer<typeof Size>;
|
44
|
+
export declare type Alignment = z.infer<typeof Alignment>;
|
45
|
+
export declare type SchemaType = z.infer<typeof SchemaType>;
|
46
|
+
export declare type BarCodeType = z.infer<typeof BarcodeSchemaType>;
|
47
|
+
export declare type TextSchema = z.infer<typeof TextSchema>;
|
48
|
+
export declare type ImageSchema = z.infer<typeof ImageSchema>;
|
49
|
+
export declare type BarcodeSchema = z.infer<typeof BarcodeSchema>;
|
50
|
+
export declare type Schema = z.infer<typeof Schema>;
|
51
|
+
export declare type SchemaForUI = z.infer<typeof SchemaForUI>;
|
52
|
+
export declare type Font = z.infer<typeof Font>;
|
53
|
+
export declare type BasePdf = z.infer<typeof BasePdf>;
|
54
|
+
export declare type Template = z.infer<typeof Template>;
|
55
|
+
export declare type CommonProps = z.infer<typeof CommonProps>;
|
56
|
+
export declare type GeneratorOptions = z.infer<typeof GeneratorOptions>;
|
57
|
+
export declare type GenerateProps = z.infer<typeof GenerateProps>;
|
58
|
+
export declare type UIOptions = z.infer<typeof UIOptions>;
|
59
|
+
export declare type UIProps = z.infer<typeof UIProps>;
|
60
|
+
export declare type PreviewProps = z.infer<typeof PreviewProps>;
|
61
|
+
export declare type PreviewReactProps = z.infer<typeof PreviewReactProps>;
|
62
|
+
export declare type DesignerProps = z.infer<typeof DesignerProps>;
|
63
|
+
export declare type DesignerReactProps = z.infer<typeof DesignerReactProps>;
|
64
|
+
export {};
|
package/package.json
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"name": "@pdfme/common",
|
3
|
+
"version": "1.0.0-beta.10",
|
4
|
+
"author": "hand-dot",
|
5
|
+
"license": "MIT",
|
6
|
+
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
7
|
+
"homepage": "https://pdfme.com",
|
8
|
+
"repository": {
|
9
|
+
"type": "git",
|
10
|
+
"url": "git@github.com:pdfme/pdfme.git"
|
11
|
+
},
|
12
|
+
"bugs": {
|
13
|
+
"url": "https://github.com/pdfme/pdfme/issues"
|
14
|
+
},
|
15
|
+
"main": "dist/index.js",
|
16
|
+
"module": "dist/index.js",
|
17
|
+
"types": "dist/types/index.d.ts",
|
18
|
+
"engines": {
|
19
|
+
"node": ">=14"
|
20
|
+
},
|
21
|
+
"scripts": {
|
22
|
+
"develop": "webpack --watch --mode development",
|
23
|
+
"build": "NODE_ENV=production webpack --mode production",
|
24
|
+
"clean": "rimraf dist",
|
25
|
+
"lint": "tsc --noEmit",
|
26
|
+
"test": "jest",
|
27
|
+
"lint:watch": "tsc -w --noEmit",
|
28
|
+
"test:watch": "jest --coverage --watch",
|
29
|
+
"prune": "ts-prune src"
|
30
|
+
},
|
31
|
+
"dependencies": {
|
32
|
+
"zod": "^3.11.6"
|
33
|
+
},
|
34
|
+
"jest": {
|
35
|
+
"moduleNameMapper": {
|
36
|
+
"\\.(ttf)$": "<rootDir>../../fontTransformer.js"
|
37
|
+
},
|
38
|
+
"moduleFileExtensions": [
|
39
|
+
"js",
|
40
|
+
"ts"
|
41
|
+
],
|
42
|
+
"transform": {
|
43
|
+
"^.+\\.ts$": "ts-jest"
|
44
|
+
},
|
45
|
+
"globals": {
|
46
|
+
"ts-jest": {
|
47
|
+
"tsconfig": "tsconfig.json"
|
48
|
+
}
|
49
|
+
},
|
50
|
+
"testMatch": [
|
51
|
+
"**/*.test.ts"
|
52
|
+
]
|
53
|
+
},
|
54
|
+
"publishConfig": {
|
55
|
+
"access": "public"
|
56
|
+
}
|
57
|
+
}
|
Binary file
|
package/src/constants.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export const DEFAULT_FONT_SIZE = 13;
|
2
|
+
export const DEFAULT_ALIGNMENT = 'left';
|
3
|
+
export const DEFAULT_LINE_HEIGHT = 1;
|
4
|
+
export const DEFAULT_CHARACTER_SPACING = 0;
|
5
|
+
export const DEFAULT_FONT_COLOR = '#000';
|
6
|
+
|
7
|
+
export const BLANK_PDF =
|
8
|
+
'data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKNSAwIG9iago8PAovRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDM4Cj4+CnN0cmVhbQp4nCvkMlAwUDC1NNUzMVGwMDHUszRSKErlCtfiyuMK5AIAXQ8GCgplbmRzdHJlYW0KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL01lZGlhQm94IFswIDAgNTk1LjQ0IDg0MS45Ml0KL1Jlc291cmNlcyA8PAo+PgovQ29udGVudHMgNSAwIFIKL1BhcmVudCAyIDAgUgo+PgplbmRvYmoKMiAwIG9iago8PAovVHlwZSAvUGFnZXMKL0tpZHMgWzQgMCBSXQovQ291bnQgMQo+PgplbmRvYmoKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKPj4KZW5kb2JqCjMgMCBvYmoKPDwKL3RyYXBwZWQgKGZhbHNlKQovQ3JlYXRvciAoU2VyaWYgQWZmaW5pdHkgRGVzaWduZXIgMS4xMC40KQovVGl0bGUgKFVudGl0bGVkLnBkZikKL0NyZWF0aW9uRGF0ZSAoRDoyMDIyMDEwNjE0MDg1OCswOScwMCcpCi9Qcm9kdWNlciAoaUxvdmVQREYpCi9Nb2REYXRlIChEOjIwMjIwMTA2MDUwOTA5WikKPj4KZW5kb2JqCjYgMCBvYmoKPDwKL1NpemUgNwovUm9vdCAxIDAgUgovSW5mbyAzIDAgUgovSUQgWzwyODhCM0VENTAyOEU0MDcyNERBNzNCOUE0Nzk4OUEwQT4gPEY1RkJGNjg4NkVERDZBQUNBNDRCNEZDRjBBRDUxRDlDPl0KL1R5cGUgL1hSZWYKL1cgWzEgMiAyXQovRmlsdGVyIC9GbGF0ZURlY29kZQovSW5kZXggWzAgN10KL0xlbmd0aCAzNgo+PgpzdHJlYW0KeJxjYGD4/5+RUZmBgZHhFZBgDAGxakAEP5BgEmFgAABlRwQJCmVuZHN0cmVhbQplbmRvYmoKc3RhcnR4cmVmCjUzMgolJUVPRgo=';
|
package/src/helper.ts
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
import Helvetica from './assets/Helvetica.ttf';
|
3
|
+
import { Template, Schema, BasePdf, Font, CommonProps, isTextSchema, BarCodeType } from './type';
|
4
|
+
import {
|
5
|
+
Template as TemplateSchema,
|
6
|
+
PreviewProps as PreviewPropsSchema,
|
7
|
+
DesignerProps as DesignerPropsSchema,
|
8
|
+
GenerateProps as GeneratePropsSchema,
|
9
|
+
UIProps as UIPropsSchema,
|
10
|
+
} from './schema';
|
11
|
+
|
12
|
+
const DEFAULT_FONT_NAME = 'Helvetica';
|
13
|
+
|
14
|
+
const blob2Base64Pdf = (blob: Blob) => {
|
15
|
+
return new Promise<string>((resolve, reject) => {
|
16
|
+
const reader = new FileReader();
|
17
|
+
reader.onloadend = () => {
|
18
|
+
if ((reader.result as string).startsWith('data:application/pdf;')) {
|
19
|
+
resolve(reader.result as string);
|
20
|
+
} else {
|
21
|
+
reject(Error('template.basePdf must be pdf data.'));
|
22
|
+
}
|
23
|
+
};
|
24
|
+
reader.readAsDataURL(blob);
|
25
|
+
});
|
26
|
+
};
|
27
|
+
|
28
|
+
export const getB64BasePdf = (basePdf: BasePdf) => {
|
29
|
+
const needFetchFromNetwork =
|
30
|
+
typeof basePdf === 'string' && !basePdf.startsWith('data:application/pdf;');
|
31
|
+
if (needFetchFromNetwork && typeof window !== 'undefined') {
|
32
|
+
return fetch(basePdf)
|
33
|
+
.then((res) => res.blob())
|
34
|
+
.then(blob2Base64Pdf)
|
35
|
+
.catch((e: Error) => {
|
36
|
+
throw e;
|
37
|
+
});
|
38
|
+
}
|
39
|
+
|
40
|
+
return basePdf as string;
|
41
|
+
};
|
42
|
+
|
43
|
+
const getByteString = (base64: string) => {
|
44
|
+
if (typeof window !== 'undefined' && window.atob) {
|
45
|
+
return window.atob(base64);
|
46
|
+
} else {
|
47
|
+
return Buffer.from(base64, 'base64').toString('binary');
|
48
|
+
}
|
49
|
+
};
|
50
|
+
|
51
|
+
export const b64toUint8Array = (base64: string) => {
|
52
|
+
const data = base64.split(';base64,')[1] ? base64.split(';base64,')[1] : base64;
|
53
|
+
|
54
|
+
const byteString = getByteString(data);
|
55
|
+
|
56
|
+
const unit8arr = new Uint8Array(byteString.length);
|
57
|
+
for (let i = 0; i < byteString.length; i += 1) {
|
58
|
+
unit8arr[i] = byteString.charCodeAt(i);
|
59
|
+
}
|
60
|
+
return unit8arr;
|
61
|
+
};
|
62
|
+
|
63
|
+
export const getFallbackFontName = (font: Font) => {
|
64
|
+
const initial = '';
|
65
|
+
const fallbackFontName = Object.entries(font).reduce((acc, cur) => {
|
66
|
+
const [fontName, fontValue] = cur;
|
67
|
+
|
68
|
+
return !acc && fontValue.fallback ? fontName : acc;
|
69
|
+
}, initial);
|
70
|
+
if (fallbackFontName === initial) {
|
71
|
+
throw Error(`fallback flag is not found in font. true fallback flag must be only one.`);
|
72
|
+
}
|
73
|
+
|
74
|
+
return fallbackFontName;
|
75
|
+
};
|
76
|
+
|
77
|
+
export const getDefaultFont = (): Font => ({
|
78
|
+
[DEFAULT_FONT_NAME]: { data: b64toUint8Array(Helvetica), fallback: true },
|
79
|
+
});
|
80
|
+
|
81
|
+
const uniq = <T>(array: Array<T>) => Array.from(new Set(array));
|
82
|
+
|
83
|
+
const getFontNamesInSchemas = (schemas: { [key: string]: Schema }[]) =>
|
84
|
+
uniq(
|
85
|
+
schemas
|
86
|
+
.map((s) => Object.values(s).map((v) => (isTextSchema(v) ? v.fontName : '')))
|
87
|
+
.reduce((acc, cur) => acc.concat(cur), [] as (string | undefined)[])
|
88
|
+
.filter(Boolean) as string[]
|
89
|
+
);
|
90
|
+
|
91
|
+
export const checkFont = (arg: { font: Font; template: Template }) => {
|
92
|
+
const {
|
93
|
+
font,
|
94
|
+
template: { schemas },
|
95
|
+
} = arg;
|
96
|
+
const fontValues = Object.values(font);
|
97
|
+
const fallbackFontNum = fontValues.reduce((acc, cur) => (cur.fallback ? acc + 1 : acc), 0);
|
98
|
+
if (fallbackFontNum === 0) {
|
99
|
+
throw Error(`fallback flag is not found in font. true fallback flag must be only one.`);
|
100
|
+
}
|
101
|
+
if (fallbackFontNum > 1) {
|
102
|
+
throw Error(
|
103
|
+
`${fallbackFontNum} fallback flags found in font. true fallback flag must be only one.`
|
104
|
+
);
|
105
|
+
}
|
106
|
+
|
107
|
+
const fontNamesInSchemas = getFontNamesInSchemas(schemas);
|
108
|
+
const fontNames = Object.keys(font);
|
109
|
+
if (fontNamesInSchemas.some((f) => !fontNames.includes(f))) {
|
110
|
+
throw Error(
|
111
|
+
`${fontNamesInSchemas
|
112
|
+
.filter((f) => !fontNames.includes(f))
|
113
|
+
.join()} of template.schemas is not found in font.`
|
114
|
+
);
|
115
|
+
}
|
116
|
+
};
|
117
|
+
|
118
|
+
const checkProps = <T>(data: unknown, zodSchema: z.ZodType<T>) => {
|
119
|
+
try {
|
120
|
+
zodSchema.parse(data);
|
121
|
+
} catch (e) {
|
122
|
+
if (e instanceof z.ZodError) {
|
123
|
+
const messages = e.issues.map(
|
124
|
+
(issue) => `ERROR POSITION: ${issue.path.join('.')}
|
125
|
+
ERROR MESSAGE: ${issue.message}
|
126
|
+
--------------------------`
|
127
|
+
);
|
128
|
+
|
129
|
+
const message = messages.join('\n');
|
130
|
+
throw Error(`Invalid argument:
|
131
|
+
--------------------------
|
132
|
+
${message}`);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
const commonProps = data as CommonProps;
|
136
|
+
const { template, options } = commonProps;
|
137
|
+
const font = options?.font;
|
138
|
+
if (font) {
|
139
|
+
checkFont({ font, template });
|
140
|
+
}
|
141
|
+
};
|
142
|
+
|
143
|
+
export const checkTemplate = (data: unknown) => checkProps(data, TemplateSchema);
|
144
|
+
export const checkUIProps = (data: unknown) => checkProps(data, UIPropsSchema);
|
145
|
+
export const checkPreviewProps = (data: unknown) => checkProps(data, PreviewPropsSchema);
|
146
|
+
export const checkDesignerProps = (data: unknown) => checkProps(data, DesignerPropsSchema);
|
147
|
+
export const checkGenerateProps = (data: unknown) => checkProps(data, GeneratePropsSchema);
|
148
|
+
|
149
|
+
export const validateBarcodeInput = (type: BarCodeType, input: string) => {
|
150
|
+
if (!input) return false;
|
151
|
+
if (type === 'qrcode') {
|
152
|
+
// 500文字以下
|
153
|
+
return input.length < 500;
|
154
|
+
}
|
155
|
+
if (type === 'japanpost') {
|
156
|
+
// 郵便番号は数字(0-9)のみ。住所表示番号は英数字(0-9,A-Z)とハイフン(-)が使用可能です。
|
157
|
+
const regexp = /^(\d{7})(\d|[A-Z]|-)+$/;
|
158
|
+
|
159
|
+
return regexp.test(input);
|
160
|
+
}
|
161
|
+
if (type === 'ean13') {
|
162
|
+
// 有効文字は数値(0-9)のみ。チェックデジットを含まない12桁orチェックデジットを含む13桁。
|
163
|
+
const regexp = /^\d{12}$|^\d{13}$/;
|
164
|
+
|
165
|
+
return regexp.test(input);
|
166
|
+
}
|
167
|
+
if (type === 'ean8') {
|
168
|
+
// 有効文字は数値(0-9)のみ。チェックデジットを含まない7桁orチェックデジットを含む8桁。
|
169
|
+
const regexp = /^\d{7}$|^\d{8}$/;
|
170
|
+
|
171
|
+
return regexp.test(input);
|
172
|
+
}
|
173
|
+
if (type === 'code39') {
|
174
|
+
// 有効文字は数字(0-9)。アルファベット大文字(A-Z)、記号(-.$/+%)、半角スペース。
|
175
|
+
const regexp = /^(\d|[A-Z]|\-|\.|\$|\/|\+|\%|\s)+$/;
|
176
|
+
|
177
|
+
return regexp.test(input);
|
178
|
+
}
|
179
|
+
if (type === 'code128') {
|
180
|
+
// 有効文字は漢字、ひらがな、カタカナ以外。
|
181
|
+
// https://qiita.com/graminume/items/2ac8dd9c32277fa9da64
|
182
|
+
return !input.match(
|
183
|
+
/([\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]|[A-Za-z0-9!"#$%&'()*+,-./:;<=>?@[\]^_`{|}〜])+/
|
184
|
+
);
|
185
|
+
}
|
186
|
+
if (type === 'nw7') {
|
187
|
+
// 有効文字はNW-7は数字(0-9)と記号(-.$:/+)。
|
188
|
+
// スタートコード/ストップコードとして、コードの始まりと終わりはアルファベット(A-D)のいずれかを使用してください。
|
189
|
+
const regexp = /^[A-Da-d]([0-9\-\.\$\:\/\+])+[A-Da-d]$/;
|
190
|
+
|
191
|
+
return regexp.test(input);
|
192
|
+
}
|
193
|
+
if (type === 'itf14') {
|
194
|
+
// 有効文字は数値(0-9)のみ。 チェックデジットを含まない13桁orチェックデジットを含む14桁。
|
195
|
+
const regexp = /^\d{13}$|^\d{14}$/;
|
196
|
+
|
197
|
+
return regexp.test(input);
|
198
|
+
}
|
199
|
+
if (type === 'upca') {
|
200
|
+
// 有効文字は数値(0-9)のみ。 チェックデジットを含まない11桁orチェックデジットを含む12桁。
|
201
|
+
const regexp = /^\d{11}$|^\d{12}$/;
|
202
|
+
|
203
|
+
return regexp.test(input);
|
204
|
+
}
|
205
|
+
if (type === 'upce') {
|
206
|
+
// 有効文字は数値(0-9)のみ。 1桁目に指定できる数字(ナンバーシステムキャラクタ)は0のみ。
|
207
|
+
// チェックデジットを含まない7桁orチェックデジットを含む8桁。
|
208
|
+
const regexp = /^0(\d{6}$|\d{7}$)/;
|
209
|
+
|
210
|
+
return regexp.test(input);
|
211
|
+
}
|
212
|
+
|
213
|
+
return false;
|
214
|
+
};
|
package/src/index.ts
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
import {
|
2
|
+
DEFAULT_FONT_SIZE,
|
3
|
+
DEFAULT_ALIGNMENT,
|
4
|
+
DEFAULT_LINE_HEIGHT,
|
5
|
+
DEFAULT_CHARACTER_SPACING,
|
6
|
+
DEFAULT_FONT_COLOR,
|
7
|
+
BLANK_PDF,
|
8
|
+
} from './constants';
|
9
|
+
import { schemaTypes, isImageSchema, isBarcodeSchema, isTextSchema } from './type';
|
10
|
+
import type {
|
11
|
+
Lang,
|
12
|
+
Size,
|
13
|
+
Alignment,
|
14
|
+
SchemaType,
|
15
|
+
BarCodeType,
|
16
|
+
TextSchema,
|
17
|
+
ImageSchema,
|
18
|
+
BarcodeSchema,
|
19
|
+
Schema,
|
20
|
+
SchemaForUI,
|
21
|
+
Font,
|
22
|
+
BasePdf,
|
23
|
+
Template,
|
24
|
+
CommonProps,
|
25
|
+
GeneratorOptions,
|
26
|
+
GenerateProps,
|
27
|
+
UIOptions,
|
28
|
+
UIProps,
|
29
|
+
PreviewProps,
|
30
|
+
PreviewReactProps,
|
31
|
+
DesignerProps,
|
32
|
+
DesignerReactProps,
|
33
|
+
} from './type';
|
34
|
+
import {
|
35
|
+
getB64BasePdf,
|
36
|
+
b64toUint8Array,
|
37
|
+
getFallbackFontName,
|
38
|
+
getDefaultFont,
|
39
|
+
checkFont,
|
40
|
+
checkTemplate,
|
41
|
+
checkUIProps,
|
42
|
+
checkPreviewProps,
|
43
|
+
checkDesignerProps,
|
44
|
+
checkGenerateProps,
|
45
|
+
validateBarcodeInput,
|
46
|
+
} from './helper';
|
47
|
+
|
48
|
+
export {
|
49
|
+
DEFAULT_FONT_SIZE,
|
50
|
+
DEFAULT_ALIGNMENT,
|
51
|
+
DEFAULT_LINE_HEIGHT,
|
52
|
+
DEFAULT_CHARACTER_SPACING,
|
53
|
+
DEFAULT_FONT_COLOR,
|
54
|
+
BLANK_PDF,
|
55
|
+
schemaTypes,
|
56
|
+
isTextSchema,
|
57
|
+
isImageSchema,
|
58
|
+
isBarcodeSchema,
|
59
|
+
getB64BasePdf,
|
60
|
+
b64toUint8Array,
|
61
|
+
getFallbackFontName,
|
62
|
+
getDefaultFont,
|
63
|
+
checkFont,
|
64
|
+
checkTemplate,
|
65
|
+
checkUIProps,
|
66
|
+
checkPreviewProps,
|
67
|
+
checkDesignerProps,
|
68
|
+
checkGenerateProps,
|
69
|
+
validateBarcodeInput,
|
70
|
+
};
|
71
|
+
|
72
|
+
export type {
|
73
|
+
Lang,
|
74
|
+
Size,
|
75
|
+
Alignment,
|
76
|
+
SchemaType,
|
77
|
+
BarCodeType,
|
78
|
+
TextSchema,
|
79
|
+
ImageSchema,
|
80
|
+
BarcodeSchema,
|
81
|
+
Schema,
|
82
|
+
SchemaForUI,
|
83
|
+
Font,
|
84
|
+
BasePdf,
|
85
|
+
Template,
|
86
|
+
CommonProps,
|
87
|
+
GeneratorOptions,
|
88
|
+
GenerateProps,
|
89
|
+
UIOptions,
|
90
|
+
UIProps,
|
91
|
+
PreviewProps,
|
92
|
+
PreviewReactProps,
|
93
|
+
DesignerProps,
|
94
|
+
DesignerReactProps,
|
95
|
+
};
|
package/src/schema.ts
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
/* eslint dot-notation: "off"*/
|
2
|
+
import { z } from 'zod';
|
3
|
+
|
4
|
+
const langs = ['en', 'ja'] as const;
|
5
|
+
export const Lang = z.enum(langs);
|
6
|
+
|
7
|
+
export const Size = z.object({ height: z.number(), width: z.number() });
|
8
|
+
|
9
|
+
const alignments = ['left', 'center', 'right'] as const;
|
10
|
+
export const Alignment = z.enum(alignments);
|
11
|
+
|
12
|
+
// prettier-ignore
|
13
|
+
export const barcodeSchemaTypes = ['qrcode', 'japanpost', 'ean13', 'ean8', 'code39', 'code128', 'nw7', 'itf14', 'upca', 'upce'] as const;
|
14
|
+
const notBarcodeSchemaTypes = ['text', 'image'] as const;
|
15
|
+
export const schemaTypes = [...notBarcodeSchemaTypes, ...barcodeSchemaTypes] as const;
|
16
|
+
|
17
|
+
export const BarcodeSchemaType = z.enum(barcodeSchemaTypes);
|
18
|
+
export const SchemaType = z.enum(schemaTypes);
|
19
|
+
|
20
|
+
export const CommonSchema = z.object({
|
21
|
+
type: SchemaType,
|
22
|
+
position: z.object({ x: z.number(), y: z.number() }),
|
23
|
+
width: z.number(),
|
24
|
+
height: z.number(),
|
25
|
+
rotate: z.number().optional(),
|
26
|
+
});
|
27
|
+
|
28
|
+
export const TextSchema = CommonSchema.extend({
|
29
|
+
type: z.literal(SchemaType.Enum.text),
|
30
|
+
alignment: Alignment.optional(),
|
31
|
+
fontSize: z.number().optional(),
|
32
|
+
fontName: z.string().optional(),
|
33
|
+
fontColor: z.string().optional(),
|
34
|
+
backgroundColor: z.string().optional(),
|
35
|
+
characterSpacing: z.number().optional(),
|
36
|
+
lineHeight: z.number().optional(),
|
37
|
+
});
|
38
|
+
|
39
|
+
export const ImageSchema = CommonSchema.extend({ type: z.literal(SchemaType.Enum.image) });
|
40
|
+
|
41
|
+
export const BarcodeSchema = CommonSchema.extend({ type: BarcodeSchemaType });
|
42
|
+
|
43
|
+
export const Schema = z.union([TextSchema, ImageSchema, BarcodeSchema]);
|
44
|
+
|
45
|
+
const SchemaForUIAdditionalInfo = z.object({ id: z.string(), key: z.string(), data: z.string() });
|
46
|
+
export const SchemaForUI = z.union([
|
47
|
+
TextSchema.merge(SchemaForUIAdditionalInfo),
|
48
|
+
ImageSchema.merge(SchemaForUIAdditionalInfo),
|
49
|
+
BarcodeSchema.merge(SchemaForUIAdditionalInfo),
|
50
|
+
]);
|
51
|
+
|
52
|
+
const ArrayBufferSchema: z.ZodSchema<ArrayBuffer> = z.any().refine((v) => v instanceof ArrayBuffer);
|
53
|
+
const Uint8ArraySchema: z.ZodSchema<Uint8Array> = z.any().refine((v) => v instanceof Uint8Array);
|
54
|
+
const Data = z.union([ArrayBufferSchema, Uint8ArraySchema]);
|
55
|
+
|
56
|
+
export const Font = z.record(
|
57
|
+
z.object({ data: Data, fallback: z.boolean().optional(), subset: z.boolean().optional() })
|
58
|
+
);
|
59
|
+
|
60
|
+
export const BasePdf = z.union([z.string(), Data]);
|
61
|
+
|
62
|
+
export const Template = z.object({
|
63
|
+
schemas: z.array(z.record(Schema)),
|
64
|
+
basePdf: BasePdf,
|
65
|
+
sampledata: z.array(z.record(z.string())).length(1).optional(),
|
66
|
+
columns: z.array(z.string()).optional(),
|
67
|
+
});
|
68
|
+
|
69
|
+
const Inputs = z.array(z.record(z.string())).min(1);
|
70
|
+
|
71
|
+
const CommonOptions = z.object({ font: Font.optional() });
|
72
|
+
|
73
|
+
export const CommonProps = z.object({
|
74
|
+
template: Template,
|
75
|
+
options: CommonOptions.optional(),
|
76
|
+
});
|
77
|
+
|
78
|
+
// -------------------generate-------------------
|
79
|
+
|
80
|
+
export const GeneratorOptions = CommonOptions.extend({
|
81
|
+
splitThreshold: z.number().optional(),
|
82
|
+
});
|
83
|
+
|
84
|
+
export const GenerateProps = CommonProps.extend({
|
85
|
+
inputs: Inputs,
|
86
|
+
options: GeneratorOptions.optional(),
|
87
|
+
}).strict();
|
88
|
+
|
89
|
+
// ---------------------------------------------
|
90
|
+
|
91
|
+
export const UIOptions = CommonOptions.extend({ lang: Lang.optional() });
|
92
|
+
|
93
|
+
const HTMLElementSchema: z.ZodSchema<HTMLElement> = z.any().refine((v) => v instanceof HTMLElement);
|
94
|
+
|
95
|
+
export const UIProps = CommonProps.extend({
|
96
|
+
domContainer: HTMLElementSchema,
|
97
|
+
options: UIOptions.optional(),
|
98
|
+
});
|
99
|
+
|
100
|
+
// -----------------Form, Viewer-----------------
|
101
|
+
|
102
|
+
export const PreviewProps = UIProps.extend({ inputs: Inputs }).strict();
|
103
|
+
export const PreviewReactProps = PreviewProps.omit({ domContainer: true }).extend({
|
104
|
+
onChangeInput: z
|
105
|
+
.function()
|
106
|
+
.args(z.object({ index: z.number(), value: z.string(), key: z.string() }))
|
107
|
+
.returns(z.void())
|
108
|
+
.optional(),
|
109
|
+
size: Size,
|
110
|
+
});
|
111
|
+
|
112
|
+
// ---------------Designer---------------
|
113
|
+
|
114
|
+
export const DesignerProps = UIProps.extend({}).strict();
|
115
|
+
export const DesignerReactProps = DesignerProps.omit({ domContainer: true }).extend({
|
116
|
+
onSaveTemplate: z.function().args(Template).returns(z.void()),
|
117
|
+
size: Size,
|
118
|
+
});
|
package/src/type.ts
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
import {
|
3
|
+
Lang,
|
4
|
+
Size,
|
5
|
+
Alignment,
|
6
|
+
barcodeSchemaTypes,
|
7
|
+
schemaTypes as _schemaTypes,
|
8
|
+
BarcodeSchemaType,
|
9
|
+
SchemaType,
|
10
|
+
CommonSchema as _CommonSchema,
|
11
|
+
TextSchema,
|
12
|
+
ImageSchema,
|
13
|
+
BarcodeSchema,
|
14
|
+
Schema,
|
15
|
+
SchemaForUI,
|
16
|
+
Font,
|
17
|
+
BasePdf,
|
18
|
+
Template,
|
19
|
+
CommonProps,
|
20
|
+
GeneratorOptions,
|
21
|
+
GenerateProps,
|
22
|
+
UIOptions,
|
23
|
+
UIProps,
|
24
|
+
PreviewProps,
|
25
|
+
PreviewReactProps,
|
26
|
+
DesignerProps,
|
27
|
+
DesignerReactProps,
|
28
|
+
} from './schema';
|
29
|
+
|
30
|
+
type CommonSchema = z.infer<typeof _CommonSchema>;
|
31
|
+
export const schemaTypes = _schemaTypes;
|
32
|
+
export const isTextSchema = (arg: CommonSchema): arg is TextSchema => arg.type === 'text';
|
33
|
+
export const isImageSchema = (arg: CommonSchema): arg is ImageSchema => arg.type === 'image';
|
34
|
+
export const isBarcodeSchema = (arg: CommonSchema): arg is BarcodeSchema =>
|
35
|
+
barcodeSchemaTypes.map((t) => t as string).includes(arg.type);
|
36
|
+
|
37
|
+
export type Lang = z.infer<typeof Lang>;
|
38
|
+
export type Size = z.infer<typeof Size>;
|
39
|
+
export type Alignment = z.infer<typeof Alignment>;
|
40
|
+
export type SchemaType = z.infer<typeof SchemaType>;
|
41
|
+
export type BarCodeType = z.infer<typeof BarcodeSchemaType>;
|
42
|
+
export type TextSchema = z.infer<typeof TextSchema>;
|
43
|
+
export type ImageSchema = z.infer<typeof ImageSchema>;
|
44
|
+
export type BarcodeSchema = z.infer<typeof BarcodeSchema>;
|
45
|
+
export type Schema = z.infer<typeof Schema>;
|
46
|
+
export type SchemaForUI = z.infer<typeof SchemaForUI>;
|
47
|
+
export type Font = z.infer<typeof Font>;
|
48
|
+
export type BasePdf = z.infer<typeof BasePdf>;
|
49
|
+
export type Template = z.infer<typeof Template>;
|
50
|
+
export type CommonProps = z.infer<typeof CommonProps>;
|
51
|
+
export type GeneratorOptions = z.infer<typeof GeneratorOptions>;
|
52
|
+
export type GenerateProps = z.infer<typeof GenerateProps>;
|
53
|
+
export type UIOptions = z.infer<typeof UIOptions>;
|
54
|
+
export type UIProps = z.infer<typeof UIProps>;
|
55
|
+
export type PreviewProps = z.infer<typeof PreviewProps>;
|
56
|
+
export type PreviewReactProps = z.infer<typeof PreviewReactProps>;
|
57
|
+
export type DesignerProps = z.infer<typeof DesignerProps>;
|
58
|
+
export type DesignerReactProps = z.infer<typeof DesignerReactProps>;
|
package/tsconfig.json
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"noImplicitAny": true,
|
4
|
+
"target": "ES2015",
|
5
|
+
"esModuleInterop": true,
|
6
|
+
"isolatedModules": true,
|
7
|
+
"declaration": true,
|
8
|
+
"declarationDir": "dist/types",
|
9
|
+
"module": "ES2015",
|
10
|
+
"lib": ["es6", "dom", "es2016", "es2017"],
|
11
|
+
"moduleResolution": "node",
|
12
|
+
"allowSyntheticDefaultImports": true,
|
13
|
+
"strict": true,
|
14
|
+
"types": ["node", "jest", "@types/jest"],
|
15
|
+
"typeRoots": ["node_modules/@types"],
|
16
|
+
"sourceMap": true
|
17
|
+
},
|
18
|
+
"baseUrl": ".",
|
19
|
+
"include": ["declaration.d.ts", "src/**/*.ts"],
|
20
|
+
"exclude": ["node_modules"]
|
21
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
const webpack = require('webpack');
|
3
|
+
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
4
|
+
const pkg = require('./package.json');
|
5
|
+
|
6
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
7
|
+
|
8
|
+
const BANNER = [
|
9
|
+
'@name ' + pkg.name,
|
10
|
+
'@version ' + pkg.version + ' | ' + new Date().toDateString(),
|
11
|
+
'@author ' + pkg.author,
|
12
|
+
'@license ' + pkg.license,
|
13
|
+
].join('\n');
|
14
|
+
|
15
|
+
const config = {
|
16
|
+
optimization: { minimize: isProduction },
|
17
|
+
resolve: {
|
18
|
+
extensions: ['.ts', '.js'],
|
19
|
+
},
|
20
|
+
plugins: [
|
21
|
+
// new BundleAnalyzerPlugin(),
|
22
|
+
new webpack.BannerPlugin({
|
23
|
+
banner: BANNER,
|
24
|
+
entryOnly: true,
|
25
|
+
}),
|
26
|
+
],
|
27
|
+
devtool: 'source-map',
|
28
|
+
devServer: {
|
29
|
+
historyApiFallback: false,
|
30
|
+
host: '0.0.0.0',
|
31
|
+
},
|
32
|
+
entry: './src/index.ts',
|
33
|
+
output: {
|
34
|
+
path: path.resolve(__dirname, 'dist'),
|
35
|
+
filename: 'index.js',
|
36
|
+
globalObject: 'this',
|
37
|
+
library: {
|
38
|
+
type: 'umd',
|
39
|
+
},
|
40
|
+
},
|
41
|
+
module: {
|
42
|
+
rules: [
|
43
|
+
{
|
44
|
+
test: /\.ts$/,
|
45
|
+
use: 'ts-loader',
|
46
|
+
},
|
47
|
+
{
|
48
|
+
test: /\.(ttf)$/i,
|
49
|
+
use: ['url-loader'],
|
50
|
+
},
|
51
|
+
],
|
52
|
+
},
|
53
|
+
};
|
54
|
+
module.exports = config;
|