pdf-lite 1.3.0 → 1.3.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/acroform/acroform.d.ts +258 -23
- package/dist/acroform/acroform.js +986 -174
- package/dist/core/decoder.d.ts +1 -1
- package/dist/core/decoder.js +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/objects/pdf-array.d.ts +1 -0
- package/dist/core/objects/pdf-array.js +4 -0
- package/dist/core/objects/pdf-dictionary.d.ts +1 -0
- package/dist/core/objects/pdf-dictionary.js +12 -0
- package/dist/core/objects/pdf-hexadecimal.d.ts +3 -1
- package/dist/core/objects/pdf-hexadecimal.js +14 -2
- package/dist/core/objects/pdf-indirect-object.d.ts +5 -3
- package/dist/core/objects/pdf-indirect-object.js +23 -5
- package/dist/core/objects/pdf-number.js +3 -0
- package/dist/core/objects/pdf-object.d.ts +6 -0
- package/dist/core/objects/pdf-object.js +10 -0
- package/dist/core/objects/pdf-stream.js +3 -0
- package/dist/core/objects/pdf-string.js +3 -0
- package/dist/core/ref.d.ts +5 -0
- package/dist/core/ref.js +14 -0
- package/dist/core/serializer.d.ts +1 -1
- package/dist/core/serializer.js +1 -1
- package/dist/core/tokeniser.d.ts +2 -2
- package/dist/core/tokeniser.js +2 -2
- package/dist/fonts/font-manager.js +6 -8
- package/dist/pdf/pdf-document.d.ts +6 -5
- package/dist/pdf/pdf-document.js +29 -21
- package/dist/pdf/pdf-revision.d.ts +33 -4
- package/dist/pdf/pdf-revision.js +100 -26
- package/dist/pdf/pdf-xref-lookup.js +3 -2
- package/dist/xfa/manager.js +2 -4
- package/package.json +1 -1
- /package/dist/core/{incremental-parser.d.ts → parser/incremental-parser.d.ts} +0 -0
- /package/dist/core/{incremental-parser.js → parser/incremental-parser.js} +0 -0
- /package/dist/core/{parser.d.ts → parser/parser.d.ts} +0 -0
- /package/dist/core/{parser.js → parser/parser.js} +0 -0
package/dist/core/decoder.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfObject } from './objects/pdf-object.js';
|
|
2
2
|
import { PdfToken } from './tokens/token.js';
|
|
3
|
-
import { IncrementalParser } from './incremental-parser.js';
|
|
3
|
+
import { IncrementalParser } from './parser/incremental-parser.js';
|
|
4
4
|
/**
|
|
5
5
|
* Decodes PDF tokens into PDF objects.
|
|
6
6
|
* Handles parsing of all PDF object types including dictionaries, arrays, streams, and xref tables.
|
package/dist/core/decoder.js
CHANGED
|
@@ -36,7 +36,7 @@ import { PdfComment } from './objects/pdf-comment.js';
|
|
|
36
36
|
import { PdfStartXRefToken } from './tokens/start-xref-token.js';
|
|
37
37
|
import { PdfStartXRef } from './objects/pdf-start-xref.js';
|
|
38
38
|
import { PdfWhitespaceToken } from './tokens/whitespace-token.js';
|
|
39
|
-
import { IncrementalParser } from './incremental-parser.js';
|
|
39
|
+
import { IncrementalParser } from './parser/incremental-parser.js';
|
|
40
40
|
import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
|
|
41
41
|
const DEFAULT_MAX_BUFFER_SIZE_BYTES = 10 * 1024 * 1024; // 10 MB
|
|
42
42
|
/**
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './decoder.js';
|
|
2
2
|
export * from './generators.js';
|
|
3
|
-
export * from './incremental-parser.js';
|
|
3
|
+
export * from './parser/incremental-parser.js';
|
|
4
4
|
export * from './objects/pdf-array.js';
|
|
5
5
|
export * from './objects/pdf-boolean.js';
|
|
6
6
|
export * from './objects/pdf-comment.js';
|
|
@@ -18,7 +18,7 @@ export * from './objects/pdf-stream.js';
|
|
|
18
18
|
export * from './objects/pdf-string.js';
|
|
19
19
|
export * from './objects/pdf-trailer.js';
|
|
20
20
|
export * from './objects/pdf-xref-table.js';
|
|
21
|
-
export * from './parser.js';
|
|
21
|
+
export * from './parser/parser.js';
|
|
22
22
|
export * from './ref.js';
|
|
23
23
|
export * from './serializer.js';
|
|
24
24
|
export * from './streams/object-stream.js';
|
package/dist/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './decoder.js';
|
|
2
2
|
export * from './generators.js';
|
|
3
|
-
export * from './incremental-parser.js';
|
|
3
|
+
export * from './parser/incremental-parser.js';
|
|
4
4
|
export * from './objects/pdf-array.js';
|
|
5
5
|
export * from './objects/pdf-boolean.js';
|
|
6
6
|
export * from './objects/pdf-comment.js';
|
|
@@ -18,7 +18,7 @@ export * from './objects/pdf-stream.js';
|
|
|
18
18
|
export * from './objects/pdf-string.js';
|
|
19
19
|
export * from './objects/pdf-trailer.js';
|
|
20
20
|
export * from './objects/pdf-xref-table.js';
|
|
21
|
-
export * from './parser.js';
|
|
21
|
+
export * from './parser/parser.js';
|
|
22
22
|
export * from './ref.js';
|
|
23
23
|
export * from './serializer.js';
|
|
24
24
|
export * from './streams/object-stream.js';
|
|
@@ -39,4 +39,8 @@ export class PdfArray extends PdfObject {
|
|
|
39
39
|
isModified() {
|
|
40
40
|
return (super.isModified() || this.items.some((item) => item.isModified()));
|
|
41
41
|
}
|
|
42
|
+
setImmutable(immutable) {
|
|
43
|
+
super.setImmutable(immutable);
|
|
44
|
+
this.items.forEach((item) => item.setImmutable(immutable));
|
|
45
|
+
}
|
|
42
46
|
}
|
|
@@ -28,6 +28,9 @@ export class PdfDictionary extends PdfObject {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
set(key, value) {
|
|
31
|
+
if (this.isImmutable()) {
|
|
32
|
+
throw new Error('Cannot modify an immutable PdfDictionary');
|
|
33
|
+
}
|
|
31
34
|
const currentValue = this.get(key);
|
|
32
35
|
if (currentValue !== value && !currentValue?.equals(value)) {
|
|
33
36
|
this.modified = true;
|
|
@@ -47,6 +50,9 @@ export class PdfDictionary extends PdfObject {
|
|
|
47
50
|
this.#entries.set(new PdfName(key), value);
|
|
48
51
|
}
|
|
49
52
|
delete(key) {
|
|
53
|
+
if (this.isImmutable()) {
|
|
54
|
+
throw new Error('Cannot modify an immutable PdfDictionary');
|
|
55
|
+
}
|
|
50
56
|
if (this.has(key)) {
|
|
51
57
|
this.modified = true;
|
|
52
58
|
}
|
|
@@ -141,4 +147,10 @@ export class PdfDictionary extends PdfObject {
|
|
|
141
147
|
return (super.isModified() ||
|
|
142
148
|
Array.from(this.#entries.values()).some((v) => v?.isModified()));
|
|
143
149
|
}
|
|
150
|
+
setImmutable(immutable) {
|
|
151
|
+
super.setImmutable(immutable);
|
|
152
|
+
for (const value of this.#entries.values()) {
|
|
153
|
+
value?.setImmutable(immutable);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
144
156
|
}
|
|
@@ -6,13 +6,15 @@ export declare class PdfHexadecimal extends PdfObject {
|
|
|
6
6
|
* The raw byte value represented by this hexadecimal object.
|
|
7
7
|
* NB: This is the hexadecimal representation, not the actual byte values.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
private _raw;
|
|
10
10
|
/**
|
|
11
11
|
* Original bytes from the PDF file, including angle brackets.
|
|
12
12
|
* Used to preserve exact formatting for incremental updates.
|
|
13
13
|
*/
|
|
14
14
|
private _originalBytes?;
|
|
15
15
|
constructor(value: string | ByteArray, format?: 'hex' | 'bytes', originalBytes?: ByteArray);
|
|
16
|
+
get raw(): ByteArray;
|
|
17
|
+
set raw(raw: ByteArray);
|
|
16
18
|
static toHexadecimal(data: string | ByteArray): PdfHexadecimal;
|
|
17
19
|
get bytes(): ByteArray;
|
|
18
20
|
toHexBytes(): ByteArray;
|
|
@@ -9,7 +9,7 @@ export class PdfHexadecimal extends PdfObject {
|
|
|
9
9
|
* The raw byte value represented by this hexadecimal object.
|
|
10
10
|
* NB: This is the hexadecimal representation, not the actual byte values.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
_raw;
|
|
13
13
|
/**
|
|
14
14
|
* Original bytes from the PDF file, including angle brackets.
|
|
15
15
|
* Used to preserve exact formatting for incremental updates.
|
|
@@ -24,9 +24,21 @@ export class PdfHexadecimal extends PdfObject {
|
|
|
24
24
|
else {
|
|
25
25
|
bytes = value instanceof Uint8Array ? value : stringToBytes(value);
|
|
26
26
|
}
|
|
27
|
-
this.
|
|
27
|
+
this._raw = bytes;
|
|
28
28
|
this._originalBytes = originalBytes;
|
|
29
29
|
}
|
|
30
|
+
get raw() {
|
|
31
|
+
return this._raw;
|
|
32
|
+
}
|
|
33
|
+
set raw(raw) {
|
|
34
|
+
if (this.isImmutable()) {
|
|
35
|
+
throw new Error('Cannot modify an immutable PdfHexadecimal');
|
|
36
|
+
}
|
|
37
|
+
this.setModified();
|
|
38
|
+
this._raw = raw;
|
|
39
|
+
// Clear original bytes when modified
|
|
40
|
+
this._originalBytes = undefined;
|
|
41
|
+
}
|
|
30
42
|
static toHexadecimal(data) {
|
|
31
43
|
return new PdfHexadecimal(data, 'bytes');
|
|
32
44
|
}
|
|
@@ -8,20 +8,22 @@ export declare class PdfIndirectObject<T extends PdfObject = PdfObject> extends
|
|
|
8
8
|
offset: Ref<number>;
|
|
9
9
|
encryptable?: boolean;
|
|
10
10
|
orderIndex?: number;
|
|
11
|
-
constructor(options
|
|
11
|
+
constructor(options?: {
|
|
12
12
|
objectNumber?: number;
|
|
13
13
|
generationNumber?: number;
|
|
14
|
-
content
|
|
14
|
+
content?: T;
|
|
15
15
|
offset?: number | Ref<number>;
|
|
16
16
|
encryptable?: boolean;
|
|
17
|
-
} | T);
|
|
17
|
+
} | T | PdfIndirectObject);
|
|
18
18
|
get reference(): PdfObjectReference;
|
|
19
19
|
isEncryptable(): boolean;
|
|
20
20
|
static createPlaceholder<T extends PdfObject>(objectNumber?: number, generationNumber?: number, content?: T): PdfIndirectObject<T extends unknown ? PdfNull : T>;
|
|
21
21
|
inPdf(): boolean;
|
|
22
22
|
matchesReference(ref?: PdfObjectReference): boolean;
|
|
23
23
|
protected tokenize(): import("../index.js").PdfToken[];
|
|
24
|
+
copyFrom(other: PdfIndirectObject): void;
|
|
24
25
|
clone(): this;
|
|
25
26
|
order(): number;
|
|
26
27
|
isModified(): boolean;
|
|
28
|
+
setImmutable(immutable?: boolean): void;
|
|
27
29
|
}
|
|
@@ -14,19 +14,25 @@ export class PdfIndirectObject extends PdfObjectReference {
|
|
|
14
14
|
encryptable;
|
|
15
15
|
orderIndex;
|
|
16
16
|
constructor(options) {
|
|
17
|
+
if (options instanceof PdfIndirectObject) {
|
|
18
|
+
super(options.objectNumber, options.generationNumber);
|
|
19
|
+
this.content = options.content.clone();
|
|
20
|
+
this.offset = options.offset.clone();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
17
23
|
if (options instanceof PdfObject) {
|
|
18
24
|
super(-1, 0);
|
|
19
25
|
this.content = options;
|
|
20
26
|
this.offset = new Ref(0);
|
|
21
27
|
return;
|
|
22
28
|
}
|
|
23
|
-
super(options
|
|
24
|
-
this.content = options
|
|
29
|
+
super(options?.objectNumber ?? -1, options?.generationNumber ?? 0);
|
|
30
|
+
this.content = options?.content ?? new PdfNull();
|
|
25
31
|
this.offset =
|
|
26
|
-
options
|
|
32
|
+
options?.offset instanceof Ref
|
|
27
33
|
? options.offset
|
|
28
|
-
: new Ref(options
|
|
29
|
-
this.encryptable = options
|
|
34
|
+
: new Ref(options?.offset ?? 0);
|
|
35
|
+
this.encryptable = options?.encryptable;
|
|
30
36
|
}
|
|
31
37
|
get reference() {
|
|
32
38
|
return new Proxy(this, {
|
|
@@ -81,6 +87,13 @@ export class PdfIndirectObject extends PdfObjectReference {
|
|
|
81
87
|
new PdfEndObjectToken(),
|
|
82
88
|
];
|
|
83
89
|
}
|
|
90
|
+
copyFrom(other) {
|
|
91
|
+
this.objectNumber = other.objectNumber;
|
|
92
|
+
this.generationNumber = other.generationNumber;
|
|
93
|
+
this.content = other.content.clone();
|
|
94
|
+
this.offset = other.offset.clone();
|
|
95
|
+
this.modified = true;
|
|
96
|
+
}
|
|
84
97
|
clone() {
|
|
85
98
|
return new PdfIndirectObject({
|
|
86
99
|
objectNumber: this.objectNumber,
|
|
@@ -97,4 +110,9 @@ export class PdfIndirectObject extends PdfObjectReference {
|
|
|
97
110
|
this.content.isModified() ||
|
|
98
111
|
this.offset.isModified);
|
|
99
112
|
}
|
|
113
|
+
setImmutable(immutable) {
|
|
114
|
+
super.setImmutable(immutable);
|
|
115
|
+
this.content.setImmutable(immutable);
|
|
116
|
+
this.offset.setImmutable(immutable);
|
|
117
|
+
}
|
|
100
118
|
}
|
|
@@ -7,6 +7,8 @@ export declare abstract class PdfObject {
|
|
|
7
7
|
postTokens?: PdfToken[];
|
|
8
8
|
/** Indicates whether the object has been modified. By default, assume it has been modified because it's a new object */
|
|
9
9
|
protected modified: boolean;
|
|
10
|
+
/** Indicates whether the object is immutable (cannot be modified) */
|
|
11
|
+
protected immutable: boolean;
|
|
10
12
|
/** Tokenizes the object into an array of PdfTokens */
|
|
11
13
|
protected abstract tokenize(): PdfToken[];
|
|
12
14
|
/** The type of this PDF object */
|
|
@@ -15,6 +17,10 @@ export declare abstract class PdfObject {
|
|
|
15
17
|
isModified(): boolean;
|
|
16
18
|
/** Sets the modified state of the object. Override this method if the modified state is determined differently */
|
|
17
19
|
setModified(modified?: boolean): void;
|
|
20
|
+
/** Indicates whether the object is immutable (cannot be modified) */
|
|
21
|
+
isImmutable(): boolean;
|
|
22
|
+
/** Sets the immutable state of the object */
|
|
23
|
+
setImmutable(immutable?: boolean): void;
|
|
18
24
|
/** Converts the object to an array of PdfTokens, including any pre or post tokens */
|
|
19
25
|
toTokens(): PdfToken[];
|
|
20
26
|
/** Converts the object to a ByteArray, optionally padding to a specified length */
|
|
@@ -7,6 +7,8 @@ export class PdfObject {
|
|
|
7
7
|
postTokens;
|
|
8
8
|
/** Indicates whether the object has been modified. By default, assume it has been modified because it's a new object */
|
|
9
9
|
modified = true;
|
|
10
|
+
/** Indicates whether the object is immutable (cannot be modified) */
|
|
11
|
+
immutable = false;
|
|
10
12
|
/** The type of this PDF object */
|
|
11
13
|
get objectType() {
|
|
12
14
|
return this.constructor.name;
|
|
@@ -19,6 +21,14 @@ export class PdfObject {
|
|
|
19
21
|
setModified(modified = true) {
|
|
20
22
|
this.modified = modified;
|
|
21
23
|
}
|
|
24
|
+
/** Indicates whether the object is immutable (cannot be modified) */
|
|
25
|
+
isImmutable() {
|
|
26
|
+
return this.immutable;
|
|
27
|
+
}
|
|
28
|
+
/** Sets the immutable state of the object */
|
|
29
|
+
setImmutable(immutable = true) {
|
|
30
|
+
this.immutable = immutable;
|
|
31
|
+
}
|
|
22
32
|
/** Converts the object to an array of PdfTokens, including any pre or post tokens */
|
|
23
33
|
toTokens() {
|
|
24
34
|
return [
|
|
@@ -44,6 +44,9 @@ export class PdfStream extends PdfObject {
|
|
|
44
44
|
return this.original.slice(0, length);
|
|
45
45
|
}
|
|
46
46
|
set raw(data) {
|
|
47
|
+
if (this.isImmutable()) {
|
|
48
|
+
throw new Error('Cannot modify an immutable PdfStream');
|
|
49
|
+
}
|
|
47
50
|
this.setModified();
|
|
48
51
|
this.original = data;
|
|
49
52
|
this.header.set('Length', new PdfNumber(data.length));
|
|
@@ -37,6 +37,9 @@ export class PdfString extends PdfObject {
|
|
|
37
37
|
return this._raw;
|
|
38
38
|
}
|
|
39
39
|
set raw(raw) {
|
|
40
|
+
if (this.isImmutable()) {
|
|
41
|
+
throw new Error('Cannot modify an immutable PdfString');
|
|
42
|
+
}
|
|
40
43
|
this.setModified();
|
|
41
44
|
this._raw = raw;
|
|
42
45
|
// Clear original bytes when modified
|
package/dist/core/ref.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare class Ref<T> {
|
|
|
23
23
|
/** Registered callbacks for update notifications */
|
|
24
24
|
callbacks: Array<RefUpdateCallback<T>>;
|
|
25
25
|
isModified: boolean;
|
|
26
|
+
protected immutable: boolean;
|
|
26
27
|
/**
|
|
27
28
|
* Creates a new Ref with an initial value.
|
|
28
29
|
*
|
|
@@ -30,6 +31,8 @@ export declare class Ref<T> {
|
|
|
30
31
|
* @throws Error if attempting to create a self-referencing Ref
|
|
31
32
|
*/
|
|
32
33
|
constructor(value: T | Ref<T>);
|
|
34
|
+
setImmutable(immutable?: boolean): void;
|
|
35
|
+
isImmutable(): boolean;
|
|
33
36
|
/**
|
|
34
37
|
* Updates the reference to a new value or another Ref.
|
|
35
38
|
* Notifies all registered callbacks of the change.
|
|
@@ -56,4 +59,6 @@ export declare class Ref<T> {
|
|
|
56
59
|
* @param callback - The function to call on value updates
|
|
57
60
|
*/
|
|
58
61
|
onUpdate(callback: RefUpdateCallback<T>): void;
|
|
62
|
+
/** Creates a new Ref with the same resolved value. */
|
|
63
|
+
clone(): Ref<T>;
|
|
59
64
|
}
|
package/dist/core/ref.js
CHANGED
|
@@ -17,6 +17,7 @@ export class Ref {
|
|
|
17
17
|
/** Registered callbacks for update notifications */
|
|
18
18
|
callbacks = [];
|
|
19
19
|
isModified = false;
|
|
20
|
+
immutable = false;
|
|
20
21
|
/**
|
|
21
22
|
* Creates a new Ref with an initial value.
|
|
22
23
|
*
|
|
@@ -29,6 +30,12 @@ export class Ref {
|
|
|
29
30
|
}
|
|
30
31
|
this.value = value;
|
|
31
32
|
}
|
|
33
|
+
setImmutable(immutable = true) {
|
|
34
|
+
this.immutable = immutable;
|
|
35
|
+
}
|
|
36
|
+
isImmutable() {
|
|
37
|
+
return this.immutable;
|
|
38
|
+
}
|
|
32
39
|
/**
|
|
33
40
|
* Updates the reference to a new value or another Ref.
|
|
34
41
|
* Notifies all registered callbacks of the change.
|
|
@@ -42,6 +49,9 @@ export class Ref {
|
|
|
42
49
|
const resolvedNewValue = newValue instanceof Ref ? newValue.resolve() : newValue;
|
|
43
50
|
const oldValue = this.resolve();
|
|
44
51
|
if (oldValue !== resolvedNewValue) {
|
|
52
|
+
if (this.immutable) {
|
|
53
|
+
throw new Error(`Cannot update an immutable Ref (${oldValue} -> ${resolvedNewValue})`);
|
|
54
|
+
}
|
|
45
55
|
this.isModified = true;
|
|
46
56
|
}
|
|
47
57
|
this.value = newValue;
|
|
@@ -81,4 +91,8 @@ export class Ref {
|
|
|
81
91
|
onUpdate(callback) {
|
|
82
92
|
this.callbacks.push(callback);
|
|
83
93
|
}
|
|
94
|
+
/** Creates a new Ref with the same resolved value. */
|
|
95
|
+
clone() {
|
|
96
|
+
return new Ref(this.resolve());
|
|
97
|
+
}
|
|
84
98
|
}
|
package/dist/core/serializer.js
CHANGED
package/dist/core/tokeniser.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IncrementalParser } from './incremental-parser.js';
|
|
1
|
+
import { IncrementalParser } from './parser/incremental-parser.js';
|
|
2
2
|
import { PdfObject } from './objects/pdf-object.js';
|
|
3
3
|
import { PdfToken } from './tokens/token.js';
|
|
4
|
-
import { Parser } from './parser.js';
|
|
4
|
+
import { Parser } from './parser/parser.js';
|
|
5
5
|
import { ByteArray } from '../types.js';
|
|
6
6
|
/**
|
|
7
7
|
* Type alias for a parser that converts bytes to PDF tokens.
|
package/dist/core/tokeniser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assert } from '../utils/assert.js';
|
|
2
2
|
import { bytesToString } from '../utils/bytesToString.js';
|
|
3
3
|
import { unescapeString } from '../utils/unescapeString.js';
|
|
4
|
-
import { IncrementalParser } from './incremental-parser.js';
|
|
4
|
+
import { IncrementalParser } from './parser/incremental-parser.js';
|
|
5
5
|
import { PdfBooleanToken } from './tokens/boolean-token.js';
|
|
6
6
|
import { PdfCommentToken } from './tokens/comment-token.js';
|
|
7
7
|
import { PdfEndArrayToken } from './tokens/end-array-token.js';
|
|
@@ -25,7 +25,7 @@ import { PdfWhitespaceToken } from './tokens/whitespace-token.js';
|
|
|
25
25
|
import { PdfXRefTableEntryToken } from './tokens/xref-table-entry-token.js';
|
|
26
26
|
import { PdfXRefTableSectionStartToken } from './tokens/xref-table-section-start-token.js';
|
|
27
27
|
import { PdfXRefTableStartToken } from './tokens/xref-table-start-token.js';
|
|
28
|
-
import { Parser } from './parser.js';
|
|
28
|
+
import { Parser } from './parser/parser.js';
|
|
29
29
|
import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
|
|
30
30
|
import { stringToBytes } from '../utils/stringToBytes.js';
|
|
31
31
|
const ByteMap = {
|
|
@@ -273,10 +273,10 @@ export class PdfFontManager {
|
|
|
273
273
|
*/
|
|
274
274
|
async collectAllFontsFromPdf() {
|
|
275
275
|
const fonts = new Map();
|
|
276
|
-
const catalog = this.document.
|
|
276
|
+
const catalog = this.document.root;
|
|
277
277
|
if (!catalog)
|
|
278
278
|
return fonts;
|
|
279
|
-
const pagesRef = catalog.get('Pages');
|
|
279
|
+
const pagesRef = catalog.content.get('Pages');
|
|
280
280
|
if (!pagesRef)
|
|
281
281
|
return fonts;
|
|
282
282
|
const pagesObjRef = pagesRef.as(PdfObjectReference);
|
|
@@ -290,11 +290,11 @@ export class PdfFontManager {
|
|
|
290
290
|
* This ensures fonts are available to form fields.
|
|
291
291
|
*/
|
|
292
292
|
async addFontToAcroFormResources(resourceName, fontObject) {
|
|
293
|
-
const catalog = this.document.
|
|
293
|
+
const catalog = this.document.root;
|
|
294
294
|
if (!catalog)
|
|
295
295
|
return;
|
|
296
296
|
// Get AcroForm dictionary
|
|
297
|
-
const acroFormRef = catalog.get('AcroForm');
|
|
297
|
+
const acroFormRef = catalog.content.get('AcroForm');
|
|
298
298
|
if (!acroFormRef)
|
|
299
299
|
return;
|
|
300
300
|
let acroFormDict;
|
|
@@ -339,10 +339,8 @@ export class PdfFontManager {
|
|
|
339
339
|
* This is more efficient than adding to each individual page.
|
|
340
340
|
*/
|
|
341
341
|
async addFontToPageResources(resourceName, fontObject) {
|
|
342
|
-
const catalog = this.document.
|
|
343
|
-
|
|
344
|
-
return;
|
|
345
|
-
const pagesRef = catalog.get('Pages');
|
|
342
|
+
const catalog = this.document.root;
|
|
343
|
+
const pagesRef = catalog.content.get('Pages');
|
|
346
344
|
if (!pagesRef)
|
|
347
345
|
return;
|
|
348
346
|
const pagesObjRef = pagesRef.as(PdfObjectReference);
|
|
@@ -33,8 +33,6 @@ import { PdfFontManager } from '../fonts/font-manager.js';
|
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export declare class PdfDocument extends PdfObject {
|
|
36
|
-
/** PDF version comment header */
|
|
37
|
-
header: PdfComment;
|
|
38
36
|
/** List of document revisions for incremental updates */
|
|
39
37
|
revisions: PdfRevision[];
|
|
40
38
|
/** Signer instance for digital signature operations */
|
|
@@ -65,6 +63,8 @@ export declare class PdfDocument extends PdfObject {
|
|
|
65
63
|
securityHandler?: PdfSecurityHandler;
|
|
66
64
|
signer?: PdfSigner;
|
|
67
65
|
});
|
|
66
|
+
get header(): PdfComment | undefined;
|
|
67
|
+
set header(comment: PdfComment | undefined);
|
|
68
68
|
/** XFA manager for handling XFA forms */
|
|
69
69
|
get xfa(): PdfXfaManager;
|
|
70
70
|
/** AcroForm manager for handling form fields */
|
|
@@ -125,13 +125,14 @@ export declare class PdfDocument extends PdfObject {
|
|
|
125
125
|
* @throws Error if the encryption dictionary reference points to a non-dictionary object
|
|
126
126
|
*/
|
|
127
127
|
get encryptionDictionary(): PdfEncryptionDictionaryObject | undefined;
|
|
128
|
+
get rootReference(): PdfObjectReference;
|
|
128
129
|
/**
|
|
129
|
-
* Gets the document catalog (root) dictionary.
|
|
130
|
+
* Gets the document catalog (root) dictionary, or creates one if it doesn't exist.
|
|
130
131
|
*
|
|
131
|
-
* @returns The root dictionary
|
|
132
|
+
* @returns The root dictionary
|
|
132
133
|
* @throws Error if the Root reference points to a non-dictionary object
|
|
133
134
|
*/
|
|
134
|
-
get
|
|
135
|
+
get root(): PdfIndirectObject<PdfDictionary>;
|
|
135
136
|
/**
|
|
136
137
|
* Gets the reference to the metadata stream from the document catalog.
|
|
137
138
|
*
|
package/dist/pdf/pdf-document.js
CHANGED
|
@@ -20,6 +20,7 @@ import { PdfSigner } from '../signing/signer.js';
|
|
|
20
20
|
import { PdfXfaManager } from '../xfa/manager.js';
|
|
21
21
|
import { PdfAcroFormManager } from '../acroform/manager.js';
|
|
22
22
|
import { PdfFontManager } from '../fonts/font-manager.js';
|
|
23
|
+
import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
|
|
23
24
|
/**
|
|
24
25
|
* Represents a PDF document with support for reading, writing, and modifying PDF files.
|
|
25
26
|
* Handles document structure, revisions, encryption, and digital signatures.
|
|
@@ -38,8 +39,6 @@ import { PdfFontManager } from '../fonts/font-manager.js';
|
|
|
38
39
|
* ```
|
|
39
40
|
*/
|
|
40
41
|
export class PdfDocument extends PdfObject {
|
|
41
|
-
/** PDF version comment header */
|
|
42
|
-
header = PdfComment.versionComment('1.7');
|
|
43
42
|
/** List of document revisions for incremental updates */
|
|
44
43
|
revisions;
|
|
45
44
|
/** Signer instance for digital signature operations */
|
|
@@ -83,6 +82,13 @@ export class PdfDocument extends PdfObject {
|
|
|
83
82
|
this.securityHandler =
|
|
84
83
|
options?.securityHandler ?? this.getSecurityHandler();
|
|
85
84
|
}
|
|
85
|
+
get header() {
|
|
86
|
+
return this.revisions[0].header;
|
|
87
|
+
}
|
|
88
|
+
set header(comment) {
|
|
89
|
+
if (comment)
|
|
90
|
+
this.revisions[0].header = comment;
|
|
91
|
+
}
|
|
86
92
|
/** XFA manager for handling XFA forms */
|
|
87
93
|
get xfa() {
|
|
88
94
|
if (!this._xfa) {
|
|
@@ -157,6 +163,9 @@ export class PdfDocument extends PdfObject {
|
|
|
157
163
|
this.startNewRevision();
|
|
158
164
|
}
|
|
159
165
|
for (const obj of objects) {
|
|
166
|
+
if (obj.isImmutable()) {
|
|
167
|
+
throw new Error('Risky adding a immutable obj');
|
|
168
|
+
}
|
|
160
169
|
this.toBeCommitted.push(obj);
|
|
161
170
|
this.latestRevision.addObject(obj);
|
|
162
171
|
}
|
|
@@ -227,16 +236,24 @@ export class PdfDocument extends PdfObject {
|
|
|
227
236
|
encryptionDictObject.encryptable = false;
|
|
228
237
|
return encryptionDictObject;
|
|
229
238
|
}
|
|
239
|
+
get rootReference() {
|
|
240
|
+
return this.root.reference;
|
|
241
|
+
}
|
|
230
242
|
/**
|
|
231
|
-
* Gets the document catalog (root) dictionary.
|
|
243
|
+
* Gets the document catalog (root) dictionary, or creates one if it doesn't exist.
|
|
232
244
|
*
|
|
233
|
-
* @returns The root dictionary
|
|
245
|
+
* @returns The root dictionary
|
|
234
246
|
* @throws Error if the Root reference points to a non-dictionary object
|
|
235
247
|
*/
|
|
236
|
-
get
|
|
248
|
+
get root() {
|
|
237
249
|
const rootRef = this.trailerDict.get('Root')?.as(PdfObjectReference);
|
|
238
250
|
if (!rootRef) {
|
|
239
|
-
|
|
251
|
+
const rootObject = new PdfIndirectObject({
|
|
252
|
+
content: new PdfDictionary(),
|
|
253
|
+
});
|
|
254
|
+
this.add(rootObject);
|
|
255
|
+
this.trailerDict.set('Root', rootObject.reference);
|
|
256
|
+
return rootObject;
|
|
240
257
|
}
|
|
241
258
|
const rootObject = this.findUncompressedObject(rootRef);
|
|
242
259
|
if (!rootObject) {
|
|
@@ -245,7 +262,7 @@ export class PdfDocument extends PdfObject {
|
|
|
245
262
|
if (!(rootObject?.content instanceof PdfDictionary)) {
|
|
246
263
|
throw new Error(`Root object ${rootRef.objectNumber} ${rootRef.generationNumber} is not a dictionary, it is a ${rootObject?.content.objectType}`);
|
|
247
264
|
}
|
|
248
|
-
return rootObject
|
|
265
|
+
return rootObject;
|
|
249
266
|
}
|
|
250
267
|
/**
|
|
251
268
|
* Gets the reference to the metadata stream from the document catalog.
|
|
@@ -253,11 +270,11 @@ export class PdfDocument extends PdfObject {
|
|
|
253
270
|
* @returns The metadata stream reference or undefined if not present
|
|
254
271
|
*/
|
|
255
272
|
get metadataStreamReference() {
|
|
256
|
-
const root = this.
|
|
273
|
+
const root = this.root;
|
|
257
274
|
if (!root) {
|
|
258
275
|
return;
|
|
259
276
|
}
|
|
260
|
-
const metadataRef = root.get('Metadata')?.as(PdfObjectReference);
|
|
277
|
+
const metadataRef = root.content.get('Metadata')?.as(PdfObjectReference);
|
|
261
278
|
if (!metadataRef) {
|
|
262
279
|
return;
|
|
263
280
|
}
|
|
@@ -501,9 +518,6 @@ export class PdfDocument extends PdfObject {
|
|
|
501
518
|
foundObject = foundObject.clone();
|
|
502
519
|
await this.securityHandler.decryptObject(foundObject);
|
|
503
520
|
}
|
|
504
|
-
else if (this.isIncremental()) {
|
|
505
|
-
foundObject = foundObject.clone(); // Clone to prevent modifications in locked revisions
|
|
506
|
-
}
|
|
507
521
|
return foundObject;
|
|
508
522
|
}
|
|
509
523
|
/**
|
|
@@ -591,7 +605,7 @@ export class PdfDocument extends PdfObject {
|
|
|
591
605
|
* @throws Error if the document has no root dictionary
|
|
592
606
|
*/
|
|
593
607
|
async setDocumentSecurityStore(dss) {
|
|
594
|
-
let rootDictionary = this.
|
|
608
|
+
let rootDictionary = this.root?.content;
|
|
595
609
|
if (!rootDictionary) {
|
|
596
610
|
throw new Error('Cannot set DSS - document has no root dictionary');
|
|
597
611
|
}
|
|
@@ -615,10 +629,6 @@ export class PdfDocument extends PdfObject {
|
|
|
615
629
|
}
|
|
616
630
|
return tokens.map((token) => ({ token, object: obj }));
|
|
617
631
|
});
|
|
618
|
-
const headerTokens = this.header
|
|
619
|
-
.toTokens()
|
|
620
|
-
.map((token) => ({ token, object: this.header }));
|
|
621
|
-
documentTokens.unshift(...headerTokens);
|
|
622
632
|
return documentTokens;
|
|
623
633
|
}
|
|
624
634
|
tokenize() {
|
|
@@ -698,9 +708,7 @@ export class PdfDocument extends PdfObject {
|
|
|
698
708
|
toBytes() {
|
|
699
709
|
this.calculateOffsets();
|
|
700
710
|
this.updateRevisions();
|
|
701
|
-
|
|
702
|
-
serializer.feedMany(this.toTokens());
|
|
703
|
-
return serializer.toBytes();
|
|
711
|
+
return concatUint8Arrays(...this.revisions.map((x) => x.toBytes()));
|
|
704
712
|
}
|
|
705
713
|
/**
|
|
706
714
|
* Serializes the document to a Base64-encoded string.
|
|
@@ -725,7 +733,7 @@ export class PdfDocument extends PdfObject {
|
|
|
725
733
|
const clonedRevisions = this.revisions.map((rev) => rev.clone());
|
|
726
734
|
return new PdfDocument({
|
|
727
735
|
revisions: clonedRevisions,
|
|
728
|
-
version: this.header
|
|
736
|
+
version: this.header?.clone(),
|
|
729
737
|
securityHandler: this.securityHandler,
|
|
730
738
|
});
|
|
731
739
|
}
|