@f-o-t/pdf 0.1.0 → 0.1.4
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/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/objects.d.ts +42 -0
- package/dist/core/objects.d.ts.map +1 -0
- package/dist/errors.d.ts +58 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/index-4jtcmpfh.js +48 -0
- package/dist/index-4jtcmpfh.js.map +10 -0
- package/dist/index-jsfksnj3.js +503 -0
- package/dist/index-jsfksnj3.js.map +14 -0
- package/dist/index-kjz7by1m.js +572 -0
- package/dist/index-kjz7by1m.js.map +13 -0
- package/dist/index.d.ts +7 -808
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -5
- package/dist/index.js.map +9 -0
- package/dist/plugins/generation/document.d.ts +38 -0
- package/dist/plugins/generation/document.d.ts.map +1 -0
- package/dist/plugins/generation/fonts.d.ts +59 -0
- package/dist/plugins/generation/fonts.d.ts.map +1 -0
- package/dist/plugins/generation/index.d.ts +5 -0
- package/dist/plugins/generation/index.d.ts.map +1 -0
- package/dist/plugins/generation/index.js +26 -0
- package/dist/plugins/generation/index.js.map +9 -0
- package/dist/plugins/generation/page.d.ts +56 -0
- package/dist/plugins/generation/page.d.ts.map +1 -0
- package/dist/plugins/generation/writer.d.ts +14 -0
- package/dist/plugins/generation/writer.d.ts.map +1 -0
- package/dist/plugins/parsing/index.d.ts +4 -0
- package/dist/plugins/parsing/index.d.ts.map +1 -0
- package/dist/plugins/parsing/index.js +16 -0
- package/dist/plugins/parsing/index.js.map +9 -0
- package/dist/plugins/parsing/lexer.d.ts +76 -0
- package/dist/plugins/parsing/lexer.d.ts.map +1 -0
- package/dist/plugins/parsing/parser.d.ts +63 -0
- package/dist/plugins/parsing/parser.d.ts.map +1 -0
- package/dist/plugins/parsing/reader.d.ts +66 -0
- package/dist/plugins/parsing/reader.d.ts.map +1 -0
- package/dist/schemas.d.ts +233 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/types.d.ts +123 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +27 -70
- package/dist/generation/index.d.ts +0 -268
- package/dist/generation/index.js +0 -26
- package/dist/parsing/index.d.ts +0 -234
- package/dist/parsing/index.js +0 -16
- package/dist/shared/chunk-10ftnz45.js +0 -572
- package/dist/shared/chunk-37mjkw9w.js +0 -492
- package/dist/shared/chunk-6dengthp.js +0 -48
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { PDFArray, PDFDictionary, PDFName, PDFRef, PDFStream, PDFValue } from "../types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Create a PDF Name object
|
|
4
|
+
*/
|
|
5
|
+
export declare function createName(value: string): PDFName;
|
|
6
|
+
/**
|
|
7
|
+
* Create a PDF Reference
|
|
8
|
+
*/
|
|
9
|
+
export declare function createRef(objectNumber: number, generation?: number): PDFRef;
|
|
10
|
+
/**
|
|
11
|
+
* Create a PDF Dictionary
|
|
12
|
+
*/
|
|
13
|
+
export declare function createDictionary(entries?: Record<string, PDFValue>): PDFDictionary;
|
|
14
|
+
/**
|
|
15
|
+
* Create a PDF Array
|
|
16
|
+
*/
|
|
17
|
+
export declare function createArray(values?: PDFValue[]): PDFArray;
|
|
18
|
+
/**
|
|
19
|
+
* Create a PDF Stream
|
|
20
|
+
*/
|
|
21
|
+
export declare function createStream(data: Uint8Array, dictionary?: PDFDictionary): PDFStream;
|
|
22
|
+
/**
|
|
23
|
+
* Type guard for PDF Reference
|
|
24
|
+
*/
|
|
25
|
+
export declare function isRef(value: unknown): value is PDFRef;
|
|
26
|
+
/**
|
|
27
|
+
* Type guard for PDF Name
|
|
28
|
+
*/
|
|
29
|
+
export declare function isName(value: unknown): value is PDFName;
|
|
30
|
+
/**
|
|
31
|
+
* Type guard for PDF Dictionary
|
|
32
|
+
*/
|
|
33
|
+
export declare function isDictionary(value: unknown): value is PDFDictionary;
|
|
34
|
+
/**
|
|
35
|
+
* Type guard for PDF Stream
|
|
36
|
+
*/
|
|
37
|
+
export declare function isStream(value: unknown): value is PDFStream;
|
|
38
|
+
/**
|
|
39
|
+
* Type guard for PDF Array
|
|
40
|
+
*/
|
|
41
|
+
export declare function isArray(value: unknown): value is PDFArray;
|
|
42
|
+
//# sourceMappingURL=objects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../src/core/objects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACT,QAAQ,EACR,aAAa,EACb,OAAO,EACP,MAAM,EACN,SAAS,EACT,QAAQ,EACV,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,SAAI,GAAG,MAAM,CAUtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAClC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,QAAQ,EAAO,GAAG,QAAQ,CAE7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CACzB,IAAI,EAAE,UAAU,EAChB,UAAU,CAAC,EAAE,aAAa,GAC1B,SAAS,CAKX;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CASrD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CASvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CASnE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAU3D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEzD"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all PDF errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class PDFError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when PDF parsing fails
|
|
9
|
+
*/
|
|
10
|
+
export declare class PDFParseError extends PDFError {
|
|
11
|
+
readonly offset?: number | undefined;
|
|
12
|
+
constructor(message: string, offset?: number | undefined);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Error thrown when PDF generation fails
|
|
16
|
+
*/
|
|
17
|
+
export declare class PDFGenerationError extends PDFError {
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Error thrown when PDF object is invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare class InvalidPDFObjectError extends PDFError {
|
|
24
|
+
readonly objectType: string;
|
|
25
|
+
constructor(objectType: string, reason: string);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Error thrown when font is not found
|
|
29
|
+
*/
|
|
30
|
+
export declare class FontNotFoundError extends PDFError {
|
|
31
|
+
readonly fontName: string;
|
|
32
|
+
constructor(fontName: string);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error thrown when image is invalid
|
|
36
|
+
*/
|
|
37
|
+
export declare class InvalidImageError extends PDFError {
|
|
38
|
+
constructor(reason: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when PDF signature fails
|
|
42
|
+
*/
|
|
43
|
+
export declare class PDFSignatureError extends PDFError {
|
|
44
|
+
constructor(reason: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when PDF encryption fails
|
|
48
|
+
*/
|
|
49
|
+
export declare class PDFEncryptionError extends PDFError {
|
|
50
|
+
constructor(reason: string);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when required feature is not implemented
|
|
54
|
+
*/
|
|
55
|
+
export declare class NotImplementedError extends PDFError {
|
|
56
|
+
constructor(feature: string);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;gBACpB,OAAO,EAAE,MAAM;CAO7B;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;aAGrB,MAAM,CAAC,EAAE,MAAM;gBAD/B,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,MAAM,YAAA;CAKpC;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;gBACjC,OAAO,EAAE,MAAM;CAI7B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;aAE7B,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAClC,MAAM,EAAE,MAAM;CAKnB;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;aAChB,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAI9C;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBAChC,MAAM,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBAChC,MAAM,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;gBACjC,MAAM,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;gBAClC,OAAO,EAAE,MAAM;CAI7B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/core/objects.ts
|
|
3
|
+
function createName(value) {
|
|
4
|
+
return { type: "name", value };
|
|
5
|
+
}
|
|
6
|
+
function createRef(objectNumber, generation = 0) {
|
|
7
|
+
if (objectNumber < 1) {
|
|
8
|
+
throw new Error(`Object number must be positive, got ${objectNumber}`);
|
|
9
|
+
}
|
|
10
|
+
if (generation < 0 || generation > 65535) {
|
|
11
|
+
throw new Error(`Generation number must be between 0 and 65535, got ${generation}`);
|
|
12
|
+
}
|
|
13
|
+
return { objectNumber, generation };
|
|
14
|
+
}
|
|
15
|
+
function createDictionary(entries) {
|
|
16
|
+
if (entries) {
|
|
17
|
+
return { ...entries };
|
|
18
|
+
}
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
function createArray(values = []) {
|
|
22
|
+
return values;
|
|
23
|
+
}
|
|
24
|
+
function createStream(data, dictionary) {
|
|
25
|
+
return {
|
|
26
|
+
dictionary: dictionary ?? createDictionary(),
|
|
27
|
+
data
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function isRef(value) {
|
|
31
|
+
return typeof value === "object" && value !== null && "objectNumber" in value && "generation" in value && typeof value.objectNumber === "number" && typeof value.generation === "number";
|
|
32
|
+
}
|
|
33
|
+
function isName(value) {
|
|
34
|
+
return typeof value === "object" && value !== null && "type" in value && value.type === "name" && "value" in value && typeof value.value === "string";
|
|
35
|
+
}
|
|
36
|
+
function isDictionary(value) {
|
|
37
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !isRef(value) && !isName(value) && !isStream(value);
|
|
38
|
+
}
|
|
39
|
+
function isStream(value) {
|
|
40
|
+
return typeof value === "object" && value !== null && "dictionary" in value && "data" in value && typeof value.dictionary === "object" && value.dictionary !== null && value.data instanceof Uint8Array;
|
|
41
|
+
}
|
|
42
|
+
function isArray(value) {
|
|
43
|
+
return Array.isArray(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { createName, createRef, createDictionary, createArray, createStream, isRef, isName, isDictionary, isStream, isArray };
|
|
47
|
+
|
|
48
|
+
//# debugId=EFECF6FCAFD31BCA64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core/objects.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n PDFArray,\n PDFDictionary,\n PDFName,\n PDFRef,\n PDFStream,\n PDFValue,\n} from \"../types.ts\";\n\n/**\n * Create a PDF Name object\n */\nexport function createName(value: string): PDFName {\n return { type: \"name\", value };\n}\n\n/**\n * Create a PDF Reference\n */\nexport function createRef(objectNumber: number, generation = 0): PDFRef {\n if (objectNumber < 1) {\n throw new Error(`Object number must be positive, got ${objectNumber}`);\n }\n if (generation < 0 || generation > 65535) {\n throw new Error(\n `Generation number must be between 0 and 65535, got ${generation}`,\n );\n }\n return { objectNumber, generation };\n}\n\n/**\n * Create a PDF Dictionary\n */\nexport function createDictionary(\n entries?: Record<string, PDFValue>,\n): PDFDictionary {\n if (entries) {\n return { ...entries };\n }\n return {};\n}\n\n/**\n * Create a PDF Array\n */\nexport function createArray(values: PDFValue[] = []): PDFArray {\n return values;\n}\n\n/**\n * Create a PDF Stream\n */\nexport function createStream(\n data: Uint8Array,\n dictionary?: PDFDictionary,\n): PDFStream {\n return {\n dictionary: dictionary ?? createDictionary(),\n data,\n };\n}\n\n/**\n * Type guard for PDF Reference\n */\nexport function isRef(value: unknown): value is PDFRef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"objectNumber\" in value &&\n \"generation\" in value &&\n typeof (value as PDFRef).objectNumber === \"number\" &&\n typeof (value as PDFRef).generation === \"number\"\n );\n}\n\n/**\n * Type guard for PDF Name\n */\nexport function isName(value: unknown): value is PDFName {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as PDFName).type === \"name\" &&\n \"value\" in value &&\n typeof (value as PDFName).value === \"string\"\n );\n}\n\n/**\n * Type guard for PDF Dictionary\n */\nexport function isDictionary(value: unknown): value is PDFDictionary {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !isRef(value) &&\n !isName(value) &&\n !isStream(value)\n );\n}\n\n/**\n * Type guard for PDF Stream\n */\nexport function isStream(value: unknown): value is PDFStream {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"dictionary\" in value &&\n \"data\" in value &&\n typeof (value as PDFStream).dictionary === \"object\" &&\n (value as PDFStream).dictionary !== null &&\n (value as PDFStream).data instanceof Uint8Array\n );\n}\n\n/**\n * Type guard for PDF Array\n */\nexport function isArray(value: unknown): value is PDFArray {\n return Array.isArray(value);\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;AAYO,SAAS,UAAU,CAAC,OAAwB;AAAA,EAChD,OAAO,EAAE,MAAM,QAAQ,MAAM;AAAA;AAMzB,SAAS,SAAS,CAAC,cAAsB,aAAa,GAAW;AAAA,EACrE,IAAI,eAAe,GAAG;AAAA,IACnB,MAAM,IAAI,MAAM,uCAAuC,cAAc;AAAA,EACxE;AAAA,EACA,IAAI,aAAa,KAAK,aAAa,OAAO;AAAA,IACvC,MAAM,IAAI,MACP,sDAAsD,YACzD;AAAA,EACH;AAAA,EACA,OAAO,EAAE,cAAc,WAAW;AAAA;AAM9B,SAAS,gBAAgB,CAC7B,SACc;AAAA,EACd,IAAI,SAAS;AAAA,IACV,OAAO,KAAK,QAAQ;AAAA,EACvB;AAAA,EACA,OAAO,CAAC;AAAA;AAMJ,SAAS,WAAW,CAAC,SAAqB,CAAC,GAAa;AAAA,EAC5D,OAAO;AAAA;AAMH,SAAS,YAAY,CACzB,MACA,YACU;AAAA,EACV,OAAO;AAAA,IACJ,YAAY,cAAc,iBAAiB;AAAA,IAC3C;AAAA,EACH;AAAA;AAMI,SAAS,KAAK,CAAC,OAAiC;AAAA,EACpD,OACG,OAAO,UAAU,YACjB,UAAU,QACV,kBAAkB,SAClB,gBAAgB,SAChB,OAAQ,MAAiB,iBAAiB,YAC1C,OAAQ,MAAiB,eAAe;AAAA;AAOvC,SAAS,MAAM,CAAC,OAAkC;AAAA,EACtD,OACG,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAkB,SAAS,UAC5B,WAAW,SACX,OAAQ,MAAkB,UAAU;AAAA;AAOnC,SAAS,YAAY,CAAC,OAAwC;AAAA,EAClE,OACG,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACpB,CAAC,MAAM,KAAK,KACZ,CAAC,OAAO,KAAK,KACb,CAAC,SAAS,KAAK;AAAA;AAOd,SAAS,QAAQ,CAAC,OAAoC;AAAA,EAC1D,OACG,OAAO,UAAU,YACjB,UAAU,QACV,gBAAgB,SAChB,UAAU,SACV,OAAQ,MAAoB,eAAe,YAC1C,MAAoB,eAAe,QACnC,MAAoB,gBAAgB;AAAA;AAOpC,SAAS,OAAO,CAAC,OAAmC;AAAA,EACxD,OAAO,MAAM,QAAQ,KAAK;AAAA;",
|
|
8
|
+
"debugId": "EFECF6FCAFD31BCA64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
createArray,
|
|
4
|
+
createDictionary,
|
|
5
|
+
createName,
|
|
6
|
+
createRef,
|
|
7
|
+
createStream
|
|
8
|
+
} from "./index-4jtcmpfh.js";
|
|
9
|
+
|
|
10
|
+
// src/schemas.ts
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
var PDFRefSchema = z.object({
|
|
13
|
+
objectNumber: z.number().int().positive(),
|
|
14
|
+
generation: z.number().int().nonnegative()
|
|
15
|
+
});
|
|
16
|
+
var PDFNameSchema = z.object({
|
|
17
|
+
type: z.literal("name"),
|
|
18
|
+
value: z.string()
|
|
19
|
+
});
|
|
20
|
+
var PageSizeSchema = z.union([
|
|
21
|
+
z.enum(["A4", "Letter", "Legal", "A3", "A5", "Tabloid"]),
|
|
22
|
+
z.object({
|
|
23
|
+
width: z.number().positive(),
|
|
24
|
+
height: z.number().positive()
|
|
25
|
+
})
|
|
26
|
+
]);
|
|
27
|
+
var RGBColorSchema = z.object({
|
|
28
|
+
type: z.literal("rgb"),
|
|
29
|
+
r: z.number().min(0).max(1),
|
|
30
|
+
g: z.number().min(0).max(1),
|
|
31
|
+
b: z.number().min(0).max(1)
|
|
32
|
+
});
|
|
33
|
+
var CMYKColorSchema = z.object({
|
|
34
|
+
type: z.literal("cmyk"),
|
|
35
|
+
c: z.number().min(0).max(1),
|
|
36
|
+
m: z.number().min(0).max(1),
|
|
37
|
+
y: z.number().min(0).max(1),
|
|
38
|
+
k: z.number().min(0).max(1)
|
|
39
|
+
});
|
|
40
|
+
var GrayColorSchema = z.object({
|
|
41
|
+
type: z.literal("gray"),
|
|
42
|
+
gray: z.number().min(0).max(1)
|
|
43
|
+
});
|
|
44
|
+
var PDFColorSchema = z.union([
|
|
45
|
+
RGBColorSchema,
|
|
46
|
+
CMYKColorSchema,
|
|
47
|
+
GrayColorSchema
|
|
48
|
+
]);
|
|
49
|
+
var TextOptionsSchema = z.object({
|
|
50
|
+
x: z.number(),
|
|
51
|
+
y: z.number(),
|
|
52
|
+
size: z.number().positive().optional(),
|
|
53
|
+
font: z.string().optional(),
|
|
54
|
+
color: PDFColorSchema.optional(),
|
|
55
|
+
align: z.enum(["left", "center", "right"]).optional()
|
|
56
|
+
});
|
|
57
|
+
var RectOptionsSchema = z.object({
|
|
58
|
+
x: z.number(),
|
|
59
|
+
y: z.number(),
|
|
60
|
+
width: z.number().positive(),
|
|
61
|
+
height: z.number().positive(),
|
|
62
|
+
fill: PDFColorSchema.optional(),
|
|
63
|
+
stroke: PDFColorSchema.optional(),
|
|
64
|
+
lineWidth: z.number().positive().optional()
|
|
65
|
+
});
|
|
66
|
+
var LineOptionsSchema = z.object({
|
|
67
|
+
x1: z.number(),
|
|
68
|
+
y1: z.number(),
|
|
69
|
+
x2: z.number(),
|
|
70
|
+
y2: z.number(),
|
|
71
|
+
color: PDFColorSchema.optional(),
|
|
72
|
+
lineWidth: z.number().positive().optional()
|
|
73
|
+
});
|
|
74
|
+
var PDFMetadataSchema = z.object({
|
|
75
|
+
title: z.string().optional(),
|
|
76
|
+
author: z.string().optional(),
|
|
77
|
+
subject: z.string().optional(),
|
|
78
|
+
keywords: z.array(z.string()).optional(),
|
|
79
|
+
creator: z.string().optional(),
|
|
80
|
+
producer: z.string().optional(),
|
|
81
|
+
creationDate: z.date().optional(),
|
|
82
|
+
modificationDate: z.date().optional()
|
|
83
|
+
});
|
|
84
|
+
var PDFDictionarySchema = z.lazy(() => z.record(z.string(), PDFValueSchema));
|
|
85
|
+
var PDFArraySchema = z.lazy(() => z.array(PDFValueSchema));
|
|
86
|
+
var PDFStreamSchema = z.object({
|
|
87
|
+
dictionary: PDFDictionarySchema,
|
|
88
|
+
data: z.instanceof(Uint8Array)
|
|
89
|
+
});
|
|
90
|
+
var PDFValueSchema = z.lazy(() => z.union([
|
|
91
|
+
z.boolean(),
|
|
92
|
+
z.number(),
|
|
93
|
+
z.string(),
|
|
94
|
+
PDFNameSchema,
|
|
95
|
+
PDFArraySchema,
|
|
96
|
+
PDFDictionarySchema,
|
|
97
|
+
PDFStreamSchema,
|
|
98
|
+
z.null(),
|
|
99
|
+
PDFRefSchema
|
|
100
|
+
]));
|
|
101
|
+
var PDFIndirectObjectSchema = z.object({
|
|
102
|
+
ref: PDFRefSchema,
|
|
103
|
+
value: PDFValueSchema
|
|
104
|
+
});
|
|
105
|
+
var PDFObjectTypeSchema = z.enum([
|
|
106
|
+
"boolean",
|
|
107
|
+
"number",
|
|
108
|
+
"string",
|
|
109
|
+
"name",
|
|
110
|
+
"array",
|
|
111
|
+
"dictionary",
|
|
112
|
+
"stream",
|
|
113
|
+
"null",
|
|
114
|
+
"indirect"
|
|
115
|
+
]);
|
|
116
|
+
var PDFVersionSchema = z.enum(["1.4", "1.5", "1.6", "1.7"]);
|
|
117
|
+
|
|
118
|
+
// src/plugins/generation/fonts.ts
|
|
119
|
+
var STANDARD_FONTS = {
|
|
120
|
+
"Times-Roman": "Times-Roman",
|
|
121
|
+
"Times-Bold": "Times-Bold",
|
|
122
|
+
"Times-Italic": "Times-Italic",
|
|
123
|
+
"Times-BoldItalic": "Times-BoldItalic",
|
|
124
|
+
Helvetica: "Helvetica",
|
|
125
|
+
"Helvetica-Bold": "Helvetica-Bold",
|
|
126
|
+
"Helvetica-Oblique": "Helvetica-Oblique",
|
|
127
|
+
"Helvetica-BoldOblique": "Helvetica-BoldOblique",
|
|
128
|
+
Courier: "Courier",
|
|
129
|
+
"Courier-Bold": "Courier-Bold",
|
|
130
|
+
"Courier-Oblique": "Courier-Oblique",
|
|
131
|
+
"Courier-BoldOblique": "Courier-BoldOblique",
|
|
132
|
+
Symbol: "Symbol",
|
|
133
|
+
ZapfDingbats: "ZapfDingbats"
|
|
134
|
+
};
|
|
135
|
+
var FONT_FAMILIES = {
|
|
136
|
+
times: {
|
|
137
|
+
regular: "Times-Roman",
|
|
138
|
+
bold: "Times-Bold",
|
|
139
|
+
italic: "Times-Italic",
|
|
140
|
+
boldItalic: "Times-BoldItalic"
|
|
141
|
+
},
|
|
142
|
+
helvetica: {
|
|
143
|
+
regular: "Helvetica",
|
|
144
|
+
bold: "Helvetica-Bold",
|
|
145
|
+
oblique: "Helvetica-Oblique",
|
|
146
|
+
boldOblique: "Helvetica-BoldOblique"
|
|
147
|
+
},
|
|
148
|
+
courier: {
|
|
149
|
+
regular: "Courier",
|
|
150
|
+
bold: "Courier-Bold",
|
|
151
|
+
oblique: "Courier-Oblique",
|
|
152
|
+
boldOblique: "Courier-BoldOblique"
|
|
153
|
+
},
|
|
154
|
+
symbol: {
|
|
155
|
+
regular: "Symbol"
|
|
156
|
+
},
|
|
157
|
+
zapfDingbats: {
|
|
158
|
+
regular: "ZapfDingbats"
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
function isStandardFont(font) {
|
|
162
|
+
return font in STANDARD_FONTS;
|
|
163
|
+
}
|
|
164
|
+
function getFontRefName(font) {
|
|
165
|
+
return `F${Object.keys(STANDARD_FONTS).indexOf(font) + 1}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/plugins/generation/page.ts
|
|
169
|
+
var PAGE_SIZES = {
|
|
170
|
+
A4: { width: 595, height: 842 },
|
|
171
|
+
Letter: { width: 612, height: 792 },
|
|
172
|
+
Legal: { width: 612, height: 1008 },
|
|
173
|
+
A3: { width: 842, height: 1191 },
|
|
174
|
+
A5: { width: 420, height: 595 },
|
|
175
|
+
Tabloid: { width: 792, height: 1224 }
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
class PDFPage {
|
|
179
|
+
ref;
|
|
180
|
+
size;
|
|
181
|
+
parent;
|
|
182
|
+
contentStream = [];
|
|
183
|
+
resources;
|
|
184
|
+
constructor(ref, options = {}) {
|
|
185
|
+
this.ref = ref;
|
|
186
|
+
this.size = PageSizeSchema.parse(options.size ?? "A4");
|
|
187
|
+
this.parent = options.parent;
|
|
188
|
+
this.resources = createDictionary({
|
|
189
|
+
Font: createDictionary()
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
getDimensions() {
|
|
193
|
+
if (typeof this.size === "string") {
|
|
194
|
+
return PAGE_SIZES[this.size];
|
|
195
|
+
}
|
|
196
|
+
return this.size;
|
|
197
|
+
}
|
|
198
|
+
setFillColor(color) {
|
|
199
|
+
if (color.type === "rgb") {
|
|
200
|
+
this.contentStream.push(`${color.r} ${color.g} ${color.b} rg`);
|
|
201
|
+
} else if (color.type === "cmyk") {
|
|
202
|
+
this.contentStream.push(`${color.c} ${color.m} ${color.y} ${color.k} k`);
|
|
203
|
+
} else if (color.type === "gray") {
|
|
204
|
+
this.contentStream.push(`${color.gray} g`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
setStrokeColor(color) {
|
|
208
|
+
if (color.type === "rgb") {
|
|
209
|
+
this.contentStream.push(`${color.r} ${color.g} ${color.b} RG`);
|
|
210
|
+
} else if (color.type === "cmyk") {
|
|
211
|
+
this.contentStream.push(`${color.c} ${color.m} ${color.y} ${color.k} K`);
|
|
212
|
+
} else if (color.type === "gray") {
|
|
213
|
+
this.contentStream.push(`${color.gray} G`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
drawText(text, options) {
|
|
217
|
+
const validOptions = TextOptionsSchema.parse(options);
|
|
218
|
+
const { x, y, size = 12, font = "Helvetica", color, align = "left" } = validOptions;
|
|
219
|
+
const fontName = font || "Helvetica";
|
|
220
|
+
if (!isStandardFont(fontName)) {
|
|
221
|
+
throw new Error(`Font "${fontName}" is not a standard PDF font. Use one of: ${Object.keys(STANDARD_FONTS).join(", ")}`);
|
|
222
|
+
}
|
|
223
|
+
const fontRefName = getFontRefName(fontName);
|
|
224
|
+
const fontDict = this.resources.Font;
|
|
225
|
+
if (!fontDict[fontRefName]) {
|
|
226
|
+
const fontObj = createDictionary({
|
|
227
|
+
Type: createName("Font"),
|
|
228
|
+
Subtype: createName("Type1"),
|
|
229
|
+
BaseFont: createName(fontName)
|
|
230
|
+
});
|
|
231
|
+
fontDict[fontRefName] = fontObj;
|
|
232
|
+
}
|
|
233
|
+
let xPos = x;
|
|
234
|
+
if (align === "center") {
|
|
235
|
+
xPos = x - text.length * size * 0.3;
|
|
236
|
+
} else if (align === "right") {
|
|
237
|
+
xPos = x - text.length * size * 0.6;
|
|
238
|
+
}
|
|
239
|
+
if (color) {
|
|
240
|
+
this.setFillColor(color);
|
|
241
|
+
}
|
|
242
|
+
this.contentStream.push("BT");
|
|
243
|
+
this.contentStream.push(`/${fontRefName} ${size} Tf`);
|
|
244
|
+
this.contentStream.push(`${xPos} ${y} Td`);
|
|
245
|
+
const escapedText = text.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
|
|
246
|
+
this.contentStream.push(`(${escapedText}) Tj`);
|
|
247
|
+
this.contentStream.push("ET");
|
|
248
|
+
}
|
|
249
|
+
drawRectangle(options) {
|
|
250
|
+
const validOptions = RectOptionsSchema.parse(options);
|
|
251
|
+
const { x, y, width, height, fill, stroke, lineWidth = 1 } = validOptions;
|
|
252
|
+
if (lineWidth && stroke) {
|
|
253
|
+
this.contentStream.push(`${lineWidth} w`);
|
|
254
|
+
}
|
|
255
|
+
if (fill) {
|
|
256
|
+
this.setFillColor(fill);
|
|
257
|
+
}
|
|
258
|
+
if (stroke) {
|
|
259
|
+
this.setStrokeColor(stroke);
|
|
260
|
+
}
|
|
261
|
+
this.contentStream.push(`${x} ${y} ${width} ${height} re`);
|
|
262
|
+
if (fill && stroke) {
|
|
263
|
+
this.contentStream.push("B");
|
|
264
|
+
} else if (fill) {
|
|
265
|
+
this.contentStream.push("f");
|
|
266
|
+
} else if (stroke) {
|
|
267
|
+
this.contentStream.push("S");
|
|
268
|
+
} else {
|
|
269
|
+
this.contentStream.push("S");
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
drawLine(options) {
|
|
273
|
+
const validOptions = LineOptionsSchema.parse(options);
|
|
274
|
+
const { x1, y1, x2, y2, color, lineWidth = 1 } = validOptions;
|
|
275
|
+
if (lineWidth) {
|
|
276
|
+
this.contentStream.push(`${lineWidth} w`);
|
|
277
|
+
}
|
|
278
|
+
if (color) {
|
|
279
|
+
this.setStrokeColor(color);
|
|
280
|
+
}
|
|
281
|
+
this.contentStream.push(`${x1} ${y1} m`);
|
|
282
|
+
this.contentStream.push(`${x2} ${y2} l`);
|
|
283
|
+
this.contentStream.push("S");
|
|
284
|
+
}
|
|
285
|
+
getContentStreamRef() {
|
|
286
|
+
return createRef(this.ref.objectNumber + 1, 0);
|
|
287
|
+
}
|
|
288
|
+
toContentStream() {
|
|
289
|
+
const content = this.contentStream.join(`
|
|
290
|
+
`);
|
|
291
|
+
const data = new TextEncoder().encode(content);
|
|
292
|
+
const dict = createDictionary({
|
|
293
|
+
Length: data.length
|
|
294
|
+
});
|
|
295
|
+
return createStream(data, dict);
|
|
296
|
+
}
|
|
297
|
+
toDictionary() {
|
|
298
|
+
const dims = this.getDimensions();
|
|
299
|
+
const dict = createDictionary({
|
|
300
|
+
Type: createName("Page"),
|
|
301
|
+
MediaBox: createArray([0, 0, dims.width, dims.height]),
|
|
302
|
+
Contents: this.getContentStreamRef(),
|
|
303
|
+
Resources: this.resources
|
|
304
|
+
});
|
|
305
|
+
if (this.parent) {
|
|
306
|
+
dict.Parent = this.parent;
|
|
307
|
+
}
|
|
308
|
+
return dict;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/plugins/generation/writer.ts
|
|
313
|
+
function serializeValue(value) {
|
|
314
|
+
if (value === null) {
|
|
315
|
+
return "null";
|
|
316
|
+
}
|
|
317
|
+
if (typeof value === "boolean") {
|
|
318
|
+
return value ? "true" : "false";
|
|
319
|
+
}
|
|
320
|
+
if (typeof value === "number") {
|
|
321
|
+
return value.toString();
|
|
322
|
+
}
|
|
323
|
+
if (typeof value === "string") {
|
|
324
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
|
|
325
|
+
return `(${escaped})`;
|
|
326
|
+
}
|
|
327
|
+
if (isName(value)) {
|
|
328
|
+
return `/${value.value}`;
|
|
329
|
+
}
|
|
330
|
+
if (isRef(value)) {
|
|
331
|
+
return `${value.objectNumber} ${value.generation} R`;
|
|
332
|
+
}
|
|
333
|
+
if (Array.isArray(value)) {
|
|
334
|
+
return `[${value.map(serializeValue).join(" ")}]`;
|
|
335
|
+
}
|
|
336
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
337
|
+
const dict = value;
|
|
338
|
+
const entries = Object.entries(dict).map(([key, val]) => `/${key} ${serializeValue(val)}`).join(`
|
|
339
|
+
`);
|
|
340
|
+
return `<<
|
|
341
|
+
${entries}
|
|
342
|
+
>>`;
|
|
343
|
+
}
|
|
344
|
+
return "";
|
|
345
|
+
}
|
|
346
|
+
function serializeStream(stream) {
|
|
347
|
+
const dictStr = serializeValue(stream.dictionary);
|
|
348
|
+
const header = new TextEncoder().encode(`${dictStr}
|
|
349
|
+
stream
|
|
350
|
+
`);
|
|
351
|
+
const footer = new TextEncoder().encode(`
|
|
352
|
+
endstream`);
|
|
353
|
+
const result = new Uint8Array(header.length + stream.data.length + footer.length);
|
|
354
|
+
result.set(header, 0);
|
|
355
|
+
result.set(stream.data, header.length);
|
|
356
|
+
result.set(footer, header.length + stream.data.length);
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
function serializeObject(objectNumber, generation, value) {
|
|
360
|
+
const header = `${objectNumber} ${generation} obj
|
|
361
|
+
`;
|
|
362
|
+
let body;
|
|
363
|
+
if (isStream(value)) {
|
|
364
|
+
body = serializeStream(value);
|
|
365
|
+
} else {
|
|
366
|
+
body = new TextEncoder().encode(serializeValue(value));
|
|
367
|
+
}
|
|
368
|
+
const footer = new TextEncoder().encode(`
|
|
369
|
+
endobj
|
|
370
|
+
`);
|
|
371
|
+
const result = new Uint8Array(header.length + body.length + footer.length);
|
|
372
|
+
result.set(new TextEncoder().encode(header), 0);
|
|
373
|
+
result.set(body, header.length);
|
|
374
|
+
result.set(footer, header.length + body.length);
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
function isName(value) {
|
|
378
|
+
return typeof value === "object" && value !== null && value.type === "name";
|
|
379
|
+
}
|
|
380
|
+
function isRef(value) {
|
|
381
|
+
return typeof value === "object" && value !== null && "objectNumber" in value && "generation" in value;
|
|
382
|
+
}
|
|
383
|
+
function isStream(value) {
|
|
384
|
+
return typeof value === "object" && value !== null && "data" in value && value.data instanceof Uint8Array;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/plugins/generation/document.ts
|
|
388
|
+
class PDFDocument {
|
|
389
|
+
version;
|
|
390
|
+
metadata;
|
|
391
|
+
objects = new Map;
|
|
392
|
+
nextObjectNumber = 1;
|
|
393
|
+
catalog;
|
|
394
|
+
pages;
|
|
395
|
+
pagesArray = [];
|
|
396
|
+
constructor(options = {}) {
|
|
397
|
+
this.version = PDFVersionSchema.parse(options.version ?? "1.7");
|
|
398
|
+
this.metadata = PDFMetadataSchema.parse(options.metadata ?? {});
|
|
399
|
+
this.catalog = this.allocateRef();
|
|
400
|
+
this.pages = this.allocateRef();
|
|
401
|
+
const catalogDict = createDictionary({
|
|
402
|
+
Type: createName("Catalog"),
|
|
403
|
+
Pages: this.pages
|
|
404
|
+
});
|
|
405
|
+
this.objects.set(this.catalog.objectNumber, catalogDict);
|
|
406
|
+
const pagesDict = createDictionary({
|
|
407
|
+
Type: createName("Pages"),
|
|
408
|
+
Kids: createArray([]),
|
|
409
|
+
Count: 0
|
|
410
|
+
});
|
|
411
|
+
this.objects.set(this.pages.objectNumber, pagesDict);
|
|
412
|
+
if (Object.keys(this.metadata).length > 0) {
|
|
413
|
+
const infoRef = this.allocateRef();
|
|
414
|
+
const metadataDict = {};
|
|
415
|
+
if (this.metadata.title)
|
|
416
|
+
metadataDict.Title = this.metadata.title;
|
|
417
|
+
if (this.metadata.author)
|
|
418
|
+
metadataDict.Author = this.metadata.author;
|
|
419
|
+
if (this.metadata.subject)
|
|
420
|
+
metadataDict.Subject = this.metadata.subject;
|
|
421
|
+
if (this.metadata.creator)
|
|
422
|
+
metadataDict.Creator = this.metadata.creator;
|
|
423
|
+
if (this.metadata.producer)
|
|
424
|
+
metadataDict.Producer = this.metadata.producer;
|
|
425
|
+
const infoDict = createDictionary(metadataDict);
|
|
426
|
+
this.objects.set(infoRef.objectNumber, infoDict);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
allocateRef() {
|
|
430
|
+
return createRef(this.nextObjectNumber++, 0);
|
|
431
|
+
}
|
|
432
|
+
addPage(options) {
|
|
433
|
+
const pageRef = this.allocateRef();
|
|
434
|
+
const contentStreamRef = this.allocateRef();
|
|
435
|
+
const page = new PDFPage(pageRef, { ...options, parent: this.pages });
|
|
436
|
+
this.pagesArray.push(page);
|
|
437
|
+
const pagesDict = this.objects.get(this.pages.objectNumber);
|
|
438
|
+
const kids = pagesDict.Kids;
|
|
439
|
+
kids.push(pageRef);
|
|
440
|
+
pagesDict.Count = pagesDict.Count + 1;
|
|
441
|
+
this.objects.set(pageRef.objectNumber, page.toDictionary());
|
|
442
|
+
this.objects.set(contentStreamRef.objectNumber, page.toContentStream());
|
|
443
|
+
return page;
|
|
444
|
+
}
|
|
445
|
+
save() {
|
|
446
|
+
for (const page of this.pagesArray) {
|
|
447
|
+
this.objects.set(page.ref.objectNumber, page.toDictionary());
|
|
448
|
+
const contentStreamRef = page.getContentStreamRef();
|
|
449
|
+
this.objects.set(contentStreamRef.objectNumber, page.toContentStream());
|
|
450
|
+
}
|
|
451
|
+
const parts = [];
|
|
452
|
+
const header = new TextEncoder().encode(`%PDF-${this.version}
|
|
453
|
+
%\xE2\xE3\xCF\xD3
|
|
454
|
+
`);
|
|
455
|
+
parts.push(header);
|
|
456
|
+
const offsets = [0];
|
|
457
|
+
let currentOffset = header.length;
|
|
458
|
+
const objectNumbers = Array.from(this.objects.keys()).sort((a, b) => a - b);
|
|
459
|
+
for (const objNum of objectNumbers) {
|
|
460
|
+
const obj = this.objects.get(objNum);
|
|
461
|
+
const objBytes = serializeObject(objNum, 0, obj);
|
|
462
|
+
parts.push(objBytes);
|
|
463
|
+
offsets[objNum] = currentOffset;
|
|
464
|
+
currentOffset += objBytes.length;
|
|
465
|
+
}
|
|
466
|
+
const xrefStart = currentOffset;
|
|
467
|
+
const xrefLines = [`xref
|
|
468
|
+
0 ${offsets.length}
|
|
469
|
+
`];
|
|
470
|
+
xrefLines.push(`0000000000 65535 f
|
|
471
|
+
`);
|
|
472
|
+
for (let i = 1;i < offsets.length; i++) {
|
|
473
|
+
const offset = offsets[i] || 0;
|
|
474
|
+
const offsetStr = offset.toString().padStart(10, "0");
|
|
475
|
+
xrefLines.push(`${offsetStr} 00000 n
|
|
476
|
+
`);
|
|
477
|
+
}
|
|
478
|
+
const xref = new TextEncoder().encode(xrefLines.join(""));
|
|
479
|
+
parts.push(xref);
|
|
480
|
+
const trailerDict = serializeValue(createDictionary({
|
|
481
|
+
Size: offsets.length,
|
|
482
|
+
Root: this.catalog
|
|
483
|
+
}));
|
|
484
|
+
const trailer = new TextEncoder().encode(`trailer
|
|
485
|
+
${trailerDict}
|
|
486
|
+
startxref
|
|
487
|
+
${xrefStart}
|
|
488
|
+
%%EOF
|
|
489
|
+
`);
|
|
490
|
+
parts.push(trailer);
|
|
491
|
+
const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
|
|
492
|
+
const result = new Uint8Array(totalLength);
|
|
493
|
+
let position = 0;
|
|
494
|
+
for (const part of parts) {
|
|
495
|
+
result.set(part, position);
|
|
496
|
+
position += part.length;
|
|
497
|
+
}
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
export { PDFRefSchema, PDFNameSchema, PageSizeSchema, RGBColorSchema, CMYKColorSchema, GrayColorSchema, PDFColorSchema, TextOptionsSchema, RectOptionsSchema, LineOptionsSchema, PDFMetadataSchema, PDFDictionarySchema, PDFArraySchema, PDFStreamSchema, PDFValueSchema, PDFIndirectObjectSchema, PDFObjectTypeSchema, PDFVersionSchema, STANDARD_FONTS, FONT_FAMILIES, isStandardFont, getFontRefName, PDFPage, serializeValue, serializeStream, serializeObject, PDFDocument };
|
|
502
|
+
|
|
503
|
+
//# debugId=CC23B1DD7B3E218A64756E2164756E21
|