@adnsistemas/pdf-lib 2.4.5 → 2.6.0
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/README.md +43 -0
- package/cjs/api/PDFDocument.d.ts +14 -0
- package/cjs/api/PDFDocument.d.ts.map +1 -1
- package/cjs/api/PDFDocument.js +51 -3
- package/cjs/api/PDFDocument.js.map +1 -1
- package/cjs/api/PDFDocumentOptions.d.ts +1 -0
- package/cjs/api/PDFDocumentOptions.d.ts.map +1 -1
- package/cjs/api/snapshot/DefaultDocumentSnapshot.d.ts +4 -0
- package/cjs/api/snapshot/DefaultDocumentSnapshot.d.ts.map +1 -1
- package/cjs/api/snapshot/DefaultDocumentSnapshot.js +10 -0
- package/cjs/api/snapshot/DefaultDocumentSnapshot.js.map +1 -1
- package/cjs/api/snapshot/DocumentSnapshot.d.ts +4 -0
- package/cjs/api/snapshot/DocumentSnapshot.d.ts.map +1 -1
- package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +5 -0
- package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
- package/cjs/api/snapshot/IncrementalDocumentSnapshot.js +17 -0
- package/cjs/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
- package/cjs/core/PDFContext.d.ts +10 -1
- package/cjs/core/PDFContext.d.ts.map +1 -1
- package/cjs/core/PDFContext.js +52 -2
- package/cjs/core/PDFContext.js.map +1 -1
- package/cjs/core/document/PDFCrossRefSection.d.ts +6 -1
- package/cjs/core/document/PDFCrossRefSection.d.ts.map +1 -1
- package/cjs/core/document/PDFCrossRefSection.js +65 -2
- package/cjs/core/document/PDFCrossRefSection.js.map +1 -1
- package/cjs/core/parser/PDFParser.d.ts +2 -2
- package/cjs/core/parser/PDFParser.d.ts.map +1 -1
- package/cjs/core/parser/PDFParser.js +23 -5
- package/cjs/core/parser/PDFParser.js.map +1 -1
- package/cjs/core/parser/PDFXRefStreamParser.d.ts.map +1 -1
- package/cjs/core/parser/PDFXRefStreamParser.js +6 -0
- package/cjs/core/parser/PDFXRefStreamParser.js.map +1 -1
- package/cjs/core/writers/PDFWriter.d.ts.map +1 -1
- package/cjs/core/writers/PDFWriter.js +10 -0
- package/cjs/core/writers/PDFWriter.js.map +1 -1
- package/dist/pdf-lib.esm.js +232 -12
- package/dist/pdf-lib.esm.js.map +1 -1
- package/dist/pdf-lib.esm.min.js +3 -3
- package/dist/pdf-lib.esm.min.js.map +1 -1
- package/dist/pdf-lib.js +232 -12
- package/dist/pdf-lib.js.map +1 -1
- package/dist/pdf-lib.min.js +3 -3
- package/dist/pdf-lib.min.js.map +1 -1
- package/es/api/PDFDocument.d.ts +14 -0
- package/es/api/PDFDocument.d.ts.map +1 -1
- package/es/api/PDFDocument.js +51 -3
- package/es/api/PDFDocument.js.map +1 -1
- package/es/api/PDFDocumentOptions.d.ts +1 -0
- package/es/api/PDFDocumentOptions.d.ts.map +1 -1
- package/es/api/snapshot/DefaultDocumentSnapshot.d.ts +4 -0
- package/es/api/snapshot/DefaultDocumentSnapshot.d.ts.map +1 -1
- package/es/api/snapshot/DefaultDocumentSnapshot.js +10 -0
- package/es/api/snapshot/DefaultDocumentSnapshot.js.map +1 -1
- package/es/api/snapshot/DocumentSnapshot.d.ts +4 -0
- package/es/api/snapshot/DocumentSnapshot.d.ts.map +1 -1
- package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +5 -0
- package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
- package/es/api/snapshot/IncrementalDocumentSnapshot.js +17 -0
- package/es/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
- package/es/core/PDFContext.d.ts +10 -1
- package/es/core/PDFContext.d.ts.map +1 -1
- package/es/core/PDFContext.js +52 -2
- package/es/core/PDFContext.js.map +1 -1
- package/es/core/document/PDFCrossRefSection.d.ts +6 -1
- package/es/core/document/PDFCrossRefSection.d.ts.map +1 -1
- package/es/core/document/PDFCrossRefSection.js +65 -2
- package/es/core/document/PDFCrossRefSection.js.map +1 -1
- package/es/core/parser/PDFParser.d.ts +2 -2
- package/es/core/parser/PDFParser.d.ts.map +1 -1
- package/es/core/parser/PDFParser.js +23 -5
- package/es/core/parser/PDFParser.js.map +1 -1
- package/es/core/parser/PDFXRefStreamParser.d.ts.map +1 -1
- package/es/core/parser/PDFXRefStreamParser.js +6 -0
- package/es/core/parser/PDFXRefStreamParser.js.map +1 -1
- package/es/core/writers/PDFWriter.d.ts.map +1 -1
- package/es/core/writers/PDFWriter.js +10 -0
- package/es/core/writers/PDFWriter.js.map +1 -1
- package/package.json +4 -4
- package/src/api/PDFDocument.ts +55 -0
- package/src/api/PDFDocumentOptions.ts +1 -0
- package/src/api/snapshot/DefaultDocumentSnapshot.ts +13 -0
- package/src/api/snapshot/DocumentSnapshot.ts +6 -0
- package/src/api/snapshot/IncrementalDocumentSnapshot.ts +20 -0
- package/src/core/PDFContext.ts +53 -2
- package/src/core/document/PDFCrossRefSection.ts +70 -2
- package/src/core/parser/PDFParser.ts +22 -3
- package/src/core/parser/PDFXRefStreamParser.ts +8 -0
- package/src/core/writers/PDFWriter.ts +11 -0
- package/ts3.4/cjs/api/PDFDocument.d.ts +14 -0
- package/ts3.4/cjs/api/PDFDocumentOptions.d.ts +1 -0
- package/ts3.4/cjs/api/snapshot/DefaultDocumentSnapshot.d.ts +4 -0
- package/ts3.4/cjs/api/snapshot/DocumentSnapshot.d.ts +4 -0
- package/ts3.4/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +5 -0
- package/ts3.4/cjs/core/PDFContext.d.ts +10 -1
- package/ts3.4/cjs/core/document/PDFCrossRefSection.d.ts +6 -1
- package/ts3.4/cjs/core/parser/PDFParser.d.ts +2 -2
- package/ts3.4/es/api/PDFDocument.d.ts +14 -0
- package/ts3.4/es/api/PDFDocumentOptions.d.ts +1 -0
- package/ts3.4/es/api/snapshot/DefaultDocumentSnapshot.d.ts +4 -0
- package/ts3.4/es/api/snapshot/DocumentSnapshot.d.ts +4 -0
- package/ts3.4/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +5 -0
- package/ts3.4/es/core/PDFContext.d.ts +10 -1
- package/ts3.4/es/core/document/PDFCrossRefSection.d.ts +6 -1
- package/ts3.4/es/core/parser/PDFParser.d.ts +2 -2
package/dist/pdf-lib.esm.js
CHANGED
|
@@ -9278,12 +9278,20 @@ SimpleRNG.withSeed = (seed) => new SimpleRNG(seed);
|
|
|
9278
9278
|
|
|
9279
9279
|
const byAscendingObjectNumber = ([a], [b]) => a.objectNumber - b.objectNumber;
|
|
9280
9280
|
class PDFContext {
|
|
9281
|
-
|
|
9281
|
+
get preserveObjectsVersions() {
|
|
9282
|
+
return this._preserveObjectsVersions;
|
|
9283
|
+
}
|
|
9284
|
+
constructor(preserveObjectsVersions) {
|
|
9282
9285
|
this.isDecrypted = true;
|
|
9286
|
+
this.xrefs = [];
|
|
9287
|
+
this._preserveObjectsVersions = preserveObjectsVersions
|
|
9288
|
+
? preserveObjectsVersions
|
|
9289
|
+
: false;
|
|
9283
9290
|
this.largestObjectNumber = 0;
|
|
9284
9291
|
this.header = PDFHeader.forVersion(1, 7);
|
|
9285
9292
|
this.trailerInfo = {};
|
|
9286
9293
|
this.indirectObjects = new Map();
|
|
9294
|
+
this.objectsPreviousVersions = new Map();
|
|
9287
9295
|
this.rng = SimpleRNG.withSeed(1);
|
|
9288
9296
|
this.pdfFileDetails = {
|
|
9289
9297
|
pdfSize: 0,
|
|
@@ -9292,6 +9300,18 @@ class PDFContext {
|
|
|
9292
9300
|
};
|
|
9293
9301
|
}
|
|
9294
9302
|
assign(ref, object) {
|
|
9303
|
+
if (this.preserveObjectsVersions) {
|
|
9304
|
+
const prevOV = this.indirectObjects.get(ref);
|
|
9305
|
+
if (prevOV) {
|
|
9306
|
+
const prevList = this.objectsPreviousVersions.get(ref);
|
|
9307
|
+
if (!prevList) {
|
|
9308
|
+
this.objectsPreviousVersions.set(ref, [prevOV]);
|
|
9309
|
+
}
|
|
9310
|
+
else {
|
|
9311
|
+
prevList.unshift(prevOV);
|
|
9312
|
+
}
|
|
9313
|
+
}
|
|
9314
|
+
}
|
|
9295
9315
|
this.indirectObjects.set(ref, object);
|
|
9296
9316
|
if (ref.objectNumber > this.largestObjectNumber) {
|
|
9297
9317
|
this.largestObjectNumber = ref.objectNumber;
|
|
@@ -9307,6 +9327,21 @@ class PDFContext {
|
|
|
9307
9327
|
return ref;
|
|
9308
9328
|
}
|
|
9309
9329
|
delete(ref) {
|
|
9330
|
+
if (this.snapshot)
|
|
9331
|
+
this.snapshot.markDeletedRef(ref);
|
|
9332
|
+
if (this.preserveObjectsVersions) {
|
|
9333
|
+
const object = this.indirectObjects.get(ref);
|
|
9334
|
+
if (object) {
|
|
9335
|
+
// check is not already deleted
|
|
9336
|
+
const verlist = this.objectsPreviousVersions.get(ref);
|
|
9337
|
+
if (verlist) {
|
|
9338
|
+
verlist.unshift(object);
|
|
9339
|
+
}
|
|
9340
|
+
else {
|
|
9341
|
+
this.objectsPreviousVersions.set(ref, [object]);
|
|
9342
|
+
}
|
|
9343
|
+
}
|
|
9344
|
+
}
|
|
9310
9345
|
return this.indirectObjects.delete(ref);
|
|
9311
9346
|
}
|
|
9312
9347
|
lookupMaybe(ref, ...types) {
|
|
@@ -9492,8 +9527,23 @@ class PDFContext {
|
|
|
9492
9527
|
if (this.snapshot)
|
|
9493
9528
|
this.snapshot.markObjForSave(obj);
|
|
9494
9529
|
}
|
|
9530
|
+
getObjectVersions(ref) {
|
|
9531
|
+
if (!this.preserveObjectsVersions)
|
|
9532
|
+
return [];
|
|
9533
|
+
const list = this.objectsPreviousVersions.get(ref);
|
|
9534
|
+
if (list)
|
|
9535
|
+
return list;
|
|
9536
|
+
return [];
|
|
9537
|
+
}
|
|
9538
|
+
listXrefEntries(xrefIndex = -1) {
|
|
9539
|
+
if (xrefIndex < 0)
|
|
9540
|
+
xrefIndex = this.xrefs.length - 1;
|
|
9541
|
+
if (xrefIndex < 0 || xrefIndex >= this.xrefs.length)
|
|
9542
|
+
return [];
|
|
9543
|
+
return this.xrefs[xrefIndex].listRefs();
|
|
9544
|
+
}
|
|
9495
9545
|
}
|
|
9496
|
-
PDFContext.create = () => new PDFContext();
|
|
9546
|
+
PDFContext.create = (withObjectVersions = false) => new PDFContext(withObjectVersions);
|
|
9497
9547
|
|
|
9498
9548
|
class PDFPageLeaf extends PDFDict {
|
|
9499
9549
|
constructor(map, context, autoNormalizeCTM = true) {
|
|
@@ -9840,6 +9890,7 @@ class DefaultDocumentSnapshot {
|
|
|
9840
9890
|
constructor() {
|
|
9841
9891
|
this.pdfSize = 0;
|
|
9842
9892
|
this.prevStartXRef = 0;
|
|
9893
|
+
this.deletedCount = 0;
|
|
9843
9894
|
}
|
|
9844
9895
|
shouldSave(_objectNumber) {
|
|
9845
9896
|
return true;
|
|
@@ -9856,11 +9907,22 @@ class DefaultDocumentSnapshot {
|
|
|
9856
9907
|
markObjsForSave(_objs) {
|
|
9857
9908
|
throw new Error('This method should not be called.');
|
|
9858
9909
|
}
|
|
9910
|
+
markDeletedObj(_obj) {
|
|
9911
|
+
throw new Error('This method should not be called.');
|
|
9912
|
+
}
|
|
9913
|
+
markDeletedRef(_ref) {
|
|
9914
|
+
throw new Error('This method should not be called.');
|
|
9915
|
+
}
|
|
9916
|
+
deletedRef(_index) {
|
|
9917
|
+
throw new Error('This method should not be called.');
|
|
9918
|
+
}
|
|
9859
9919
|
}
|
|
9860
9920
|
const defaultDocumentSnapshot = new DefaultDocumentSnapshot();
|
|
9861
9921
|
|
|
9862
9922
|
class IncrementalDocumentSnapshot {
|
|
9863
9923
|
constructor(lastObjectNumber, indirectObjects, pdfSize, prevStartXRef, context) {
|
|
9924
|
+
this.deletedCount = 0;
|
|
9925
|
+
this.deleted = [];
|
|
9864
9926
|
this.lastObjectNumber = lastObjectNumber;
|
|
9865
9927
|
this.changedObjects = indirectObjects;
|
|
9866
9928
|
this.pdfSize = pdfSize;
|
|
@@ -9893,11 +9955,26 @@ class IncrementalDocumentSnapshot {
|
|
|
9893
9955
|
.map((obj) => this.context.getRef(obj))
|
|
9894
9956
|
.filter((ref) => ref !== undefined));
|
|
9895
9957
|
}
|
|
9958
|
+
markDeletedRef(ref) {
|
|
9959
|
+
if (this.deleted.findIndex((dref) => dref.objectNumber === ref.objectNumber) <
|
|
9960
|
+
0)
|
|
9961
|
+
this.deletedCount = this.deleted.push(ref);
|
|
9962
|
+
}
|
|
9963
|
+
markDeletedObj(obj) {
|
|
9964
|
+
const oref = this.context.getRef(obj);
|
|
9965
|
+
if (oref)
|
|
9966
|
+
this.markDeletedRef(oref);
|
|
9967
|
+
}
|
|
9968
|
+
deletedRef(index) {
|
|
9969
|
+
if (index < 0 || index >= this.deleted.length)
|
|
9970
|
+
return null;
|
|
9971
|
+
return this.deleted[index];
|
|
9972
|
+
}
|
|
9896
9973
|
}
|
|
9897
9974
|
|
|
9898
9975
|
/**
|
|
9899
9976
|
* Entries should be added using the [[addEntry]] and [[addDeletedEntry]]
|
|
9900
|
-
* methods
|
|
9977
|
+
* methods.
|
|
9901
9978
|
*/
|
|
9902
9979
|
class PDFCrossRefSection {
|
|
9903
9980
|
constructor(firstEntry) {
|
|
@@ -9909,6 +9986,23 @@ class PDFCrossRefSection {
|
|
|
9909
9986
|
this.append({ ref, offset, deleted: false });
|
|
9910
9987
|
}
|
|
9911
9988
|
addDeletedEntry(ref, nextFreeObjectNumber) {
|
|
9989
|
+
// fix the first entry if required
|
|
9990
|
+
if (!this.subsections.length) {
|
|
9991
|
+
this.subsections = [
|
|
9992
|
+
[
|
|
9993
|
+
{
|
|
9994
|
+
ref: PDFRef.of(0, 65535),
|
|
9995
|
+
offset: ref.objectNumber,
|
|
9996
|
+
deleted: true,
|
|
9997
|
+
},
|
|
9998
|
+
],
|
|
9999
|
+
];
|
|
10000
|
+
this.chunkIdx = 0;
|
|
10001
|
+
this.chunkLength = 1;
|
|
10002
|
+
}
|
|
10003
|
+
else if (!this.subsections[0][0].offset) {
|
|
10004
|
+
this.subsections[0][0].offset = ref.objectNumber;
|
|
10005
|
+
}
|
|
9912
10006
|
this.append({ ref, offset: nextFreeObjectNumber, deleted: true });
|
|
9913
10007
|
}
|
|
9914
10008
|
toString() {
|
|
@@ -9991,7 +10085,37 @@ class PDFCrossRefSection {
|
|
|
9991
10085
|
}
|
|
9992
10086
|
const chunk = this.subsections[this.chunkIdx];
|
|
9993
10087
|
const prevEntry = chunk[this.chunkLength - 1];
|
|
9994
|
-
if (currEntry.ref.objectNumber - prevEntry.ref.objectNumber
|
|
10088
|
+
if (currEntry.ref.objectNumber - prevEntry.ref.objectNumber !== 1) {
|
|
10089
|
+
// the current chunk is not the right chunk, find the right one, or create a new one
|
|
10090
|
+
for (let c = 0; c < this.subsections.length; c++) {
|
|
10091
|
+
const first = this.subsections[c][0];
|
|
10092
|
+
const last = this.subsections[c][this.subsections[c].length - 1];
|
|
10093
|
+
if (first.ref.objectNumber > currEntry.ref.objectNumber) {
|
|
10094
|
+
// goes before this subsection, or at the start of it
|
|
10095
|
+
if (first.ref.objectNumber - currEntry.ref.objectNumber === 1) {
|
|
10096
|
+
// first element of subsection
|
|
10097
|
+
this.subsections[c].unshift(currEntry);
|
|
10098
|
+
if (c === this.chunkIdx)
|
|
10099
|
+
this.chunkLength += 1;
|
|
10100
|
+
return;
|
|
10101
|
+
}
|
|
10102
|
+
else {
|
|
10103
|
+
// create subsection
|
|
10104
|
+
this.subsections.splice(c, 0, [currEntry]);
|
|
10105
|
+
this.chunkIdx++;
|
|
10106
|
+
return;
|
|
10107
|
+
}
|
|
10108
|
+
}
|
|
10109
|
+
else if (last.ref.objectNumber > currEntry.ref.objectNumber) {
|
|
10110
|
+
// goes in this subsection, find its place..
|
|
10111
|
+
const cep = this.subsections[c].findIndex((ee) => ee.ref.objectNumber > currEntry.ref.objectNumber);
|
|
10112
|
+
this.subsections[c].splice(cep, 0, currEntry);
|
|
10113
|
+
if (c === this.chunkIdx)
|
|
10114
|
+
this.chunkLength += 1;
|
|
10115
|
+
}
|
|
10116
|
+
// bigger, keep looking
|
|
10117
|
+
}
|
|
10118
|
+
// if got to here, then a new subsection is required
|
|
9995
10119
|
this.subsections.push([currEntry]);
|
|
9996
10120
|
this.chunkIdx += 1;
|
|
9997
10121
|
this.chunkLength = 1;
|
|
@@ -10001,6 +10125,22 @@ class PDFCrossRefSection {
|
|
|
10001
10125
|
this.chunkLength += 1;
|
|
10002
10126
|
}
|
|
10003
10127
|
}
|
|
10128
|
+
/**
|
|
10129
|
+
* Returns all the entries in the XREF section, except the first one (object == 0)
|
|
10130
|
+
* @returns {Entry[]} All the entries in the XREF section
|
|
10131
|
+
*/
|
|
10132
|
+
listRefs() {
|
|
10133
|
+
const refList = [];
|
|
10134
|
+
for (let rangeIdx = 0, rangeLen = this.subsections.length; rangeIdx < rangeLen; rangeIdx++) {
|
|
10135
|
+
const range = this.subsections[rangeIdx];
|
|
10136
|
+
for (let entryIdx = 0, entryLen = range.length; entryIdx < entryLen; entryIdx++) {
|
|
10137
|
+
const entry = range[entryIdx];
|
|
10138
|
+
if (entry.ref.objectNumber)
|
|
10139
|
+
refList.push(entry);
|
|
10140
|
+
}
|
|
10141
|
+
}
|
|
10142
|
+
return refList;
|
|
10143
|
+
}
|
|
10004
10144
|
}
|
|
10005
10145
|
PDFCrossRefSection.create = () => new PDFCrossRefSection({
|
|
10006
10146
|
ref: PDFRef.of(0, 65535),
|
|
@@ -10232,6 +10372,15 @@ class PDFWriter {
|
|
|
10232
10372
|
if (this.shouldWaitForTick(1))
|
|
10233
10373
|
yield waitForTick();
|
|
10234
10374
|
}
|
|
10375
|
+
// deleted objects
|
|
10376
|
+
for (let idx = 0; idx < this.snapshot.deletedCount; idx++) {
|
|
10377
|
+
const dref = this.snapshot.deletedRef(idx);
|
|
10378
|
+
if (!dref)
|
|
10379
|
+
break;
|
|
10380
|
+
const nextdref = this.snapshot.deletedRef(idx + 1);
|
|
10381
|
+
// add 1 to generation number for deleted ref
|
|
10382
|
+
xref.addDeletedEntry(PDFRef.of(dref.objectNumber, dref.generationNumber + 1), nextdref ? nextdref.objectNumber : 0);
|
|
10383
|
+
}
|
|
10235
10384
|
const xrefOffset = size;
|
|
10236
10385
|
size += xref.sizeInBytes() + 1; // '\n'
|
|
10237
10386
|
const trailerDict = PDFTrailerDict.of(this.createTrailerDict(this.snapshot.prevStartXRef));
|
|
@@ -15764,11 +15913,17 @@ class PDFXRefStreamParser {
|
|
|
15764
15913
|
}
|
|
15765
15914
|
this.alreadyParsed = true;
|
|
15766
15915
|
this.context.trailerInfo = {
|
|
15916
|
+
Size: this.dict.lookup(PDFName.of('Size'), PDFNumber),
|
|
15767
15917
|
Root: this.dict.get(PDFName.of('Root')),
|
|
15768
15918
|
Encrypt: this.dict.get(PDFName.of('Encrypt')),
|
|
15769
15919
|
Info: this.dict.get(PDFName.of('Info')),
|
|
15770
15920
|
ID: this.dict.get(PDFName.of('ID')),
|
|
15771
15921
|
};
|
|
15922
|
+
// if open for incremental update, make sure next object number doesn't overlap a deleted one
|
|
15923
|
+
if (this.context.trailerInfo.Size &&
|
|
15924
|
+
this.context.pdfFileDetails.originalBytes)
|
|
15925
|
+
this.context.largestObjectNumber =
|
|
15926
|
+
this.context.trailerInfo.Size.asNumber() - 1;
|
|
15772
15927
|
const entries = this.parseEntries();
|
|
15773
15928
|
// for (let idx = 0, len = entries.length; idx < len; idx++) {
|
|
15774
15929
|
// const entry = entries[idx];
|
|
@@ -15813,8 +15968,8 @@ class PDFXRefStreamParser {
|
|
|
15813
15968
|
PDFXRefStreamParser.forStream = (rawStream) => new PDFXRefStreamParser(rawStream);
|
|
15814
15969
|
|
|
15815
15970
|
class PDFParser extends PDFObjectParser {
|
|
15816
|
-
constructor(pdfBytes, objectsPerTick = Infinity, throwOnInvalidObject = false, warnOnInvalidObjects = false, capNumbers = false, cryptoFactory, forIncrementalUpdate = false) {
|
|
15817
|
-
super(ByteStream.of(pdfBytes), PDFContext.create(), capNumbers, cryptoFactory);
|
|
15971
|
+
constructor(pdfBytes, objectsPerTick = Infinity, throwOnInvalidObject = false, warnOnInvalidObjects = false, capNumbers = false, cryptoFactory, forIncrementalUpdate = false, preserveObjectsVersions = false) {
|
|
15972
|
+
super(ByteStream.of(pdfBytes), PDFContext.create(preserveObjectsVersions), capNumbers, cryptoFactory);
|
|
15818
15973
|
this.alreadyParsed = false;
|
|
15819
15974
|
this.parsedObjects = 0;
|
|
15820
15975
|
this.shouldWaitForTick = () => {
|
|
@@ -15921,7 +16076,17 @@ class PDFParser extends PDFObjectParser {
|
|
|
15921
16076
|
}
|
|
15922
16077
|
else if (object instanceof PDFRawStream &&
|
|
15923
16078
|
object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
|
|
15924
|
-
PDFXRefStreamParser.forStream(object).parseIntoContext();
|
|
16079
|
+
const entries = PDFXRefStreamParser.forStream(object).parseIntoContext();
|
|
16080
|
+
if (entries.length) {
|
|
16081
|
+
const xref = PDFCrossRefSection.createEmpty();
|
|
16082
|
+
for (const entry of entries) {
|
|
16083
|
+
if (entry.deleted)
|
|
16084
|
+
xref.addDeletedEntry(entry.ref, entry.offset);
|
|
16085
|
+
else
|
|
16086
|
+
xref.addEntry(entry.ref, entry.offset);
|
|
16087
|
+
}
|
|
16088
|
+
this.context.xrefs.push(xref);
|
|
16089
|
+
}
|
|
15925
16090
|
}
|
|
15926
16091
|
// always register the object and the ref, to properly handle object numeration
|
|
15927
16092
|
this.context.assign(ref, object);
|
|
@@ -16021,11 +16186,16 @@ class PDFParser extends PDFObjectParser {
|
|
|
16021
16186
|
const dict = this.parseDict();
|
|
16022
16187
|
const { context } = this;
|
|
16023
16188
|
context.trailerInfo = {
|
|
16189
|
+
Size: dict.lookupMaybe(PDFName.of('Size'), PDFNumber) ||
|
|
16190
|
+
context.trailerInfo.Size,
|
|
16024
16191
|
Root: dict.get(PDFName.of('Root')) || context.trailerInfo.Root,
|
|
16025
16192
|
Encrypt: dict.get(PDFName.of('Encrypt')) || context.trailerInfo.Encrypt,
|
|
16026
16193
|
Info: dict.get(PDFName.of('Info')) || context.trailerInfo.Info,
|
|
16027
16194
|
ID: dict.get(PDFName.of('ID')) || context.trailerInfo.ID,
|
|
16028
16195
|
};
|
|
16196
|
+
// if open for incremental update, then deleted objects need to be preserved, and largestObjectNumber has to be Size-1
|
|
16197
|
+
if (context.trailerInfo.Size && context.pdfFileDetails.originalBytes)
|
|
16198
|
+
context.largestObjectNumber = context.trailerInfo.Size.asNumber() - 1;
|
|
16029
16199
|
}
|
|
16030
16200
|
maybeParseTrailer() {
|
|
16031
16201
|
this.skipWhitespaceAndComments();
|
|
@@ -16044,7 +16214,9 @@ class PDFParser extends PDFObjectParser {
|
|
|
16044
16214
|
parseDocumentSection() {
|
|
16045
16215
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16046
16216
|
yield this.parseIndirectObjects();
|
|
16047
|
-
this.maybeParseCrossRefSection();
|
|
16217
|
+
const xref = this.maybeParseCrossRefSection();
|
|
16218
|
+
if (xref)
|
|
16219
|
+
this.context.xrefs.push(xref);
|
|
16048
16220
|
this.maybeParseTrailerDict();
|
|
16049
16221
|
this.maybeParseTrailer();
|
|
16050
16222
|
// TODO: Can this be done only when needed, to avoid harming performance?
|
|
@@ -16101,7 +16273,7 @@ class PDFParser extends PDFObjectParser {
|
|
|
16101
16273
|
}
|
|
16102
16274
|
}
|
|
16103
16275
|
}
|
|
16104
|
-
PDFParser.forBytesWithOptions = (pdfBytes, objectsPerTick, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, cryptoFactory, forIncrementalUpdate) => new PDFParser(pdfBytes, objectsPerTick, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, cryptoFactory, forIncrementalUpdate);
|
|
16276
|
+
PDFParser.forBytesWithOptions = (pdfBytes, objectsPerTick, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, cryptoFactory, forIncrementalUpdate, preserveObjectsVersions) => new PDFParser(pdfBytes, objectsPerTick, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, cryptoFactory, forIncrementalUpdate, preserveObjectsVersions);
|
|
16105
16277
|
|
|
16106
16278
|
var cryptoJs = {exports: {}};
|
|
16107
16279
|
|
|
@@ -35630,7 +35802,7 @@ class PDFDocument {
|
|
|
35630
35802
|
*/
|
|
35631
35803
|
static load(pdf, options = {}) {
|
|
35632
35804
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35633
|
-
const { ignoreEncryption = false, parseSpeed = ParseSpeeds.Slow, throwOnInvalidObject = false, warnOnInvalidObjects = false, updateMetadata = true, capNumbers = false, password, forIncrementalUpdate = false, } = options;
|
|
35805
|
+
const { ignoreEncryption = false, parseSpeed = ParseSpeeds.Slow, throwOnInvalidObject = false, warnOnInvalidObjects = false, updateMetadata = true, capNumbers = false, password, forIncrementalUpdate = false, preserveObjectsVersions = false, } = options;
|
|
35634
35806
|
assertIs(pdf, 'pdf', ['string', Uint8Array, ArrayBuffer]);
|
|
35635
35807
|
assertIs(ignoreEncryption, 'ignoreEncryption', ['boolean']);
|
|
35636
35808
|
assertIs(parseSpeed, 'parseSpeed', ['number']);
|
|
@@ -35638,14 +35810,15 @@ class PDFDocument {
|
|
|
35638
35810
|
assertIs(warnOnInvalidObjects, 'warnOnInvalidObjects', ['boolean']);
|
|
35639
35811
|
assertIs(password, 'password', ['string', 'undefined']);
|
|
35640
35812
|
assertIs(forIncrementalUpdate, 'forIncrementalUpdate', ['boolean']);
|
|
35813
|
+
assertIs(preserveObjectsVersions, 'preserveObjectsVersions', ['boolean']);
|
|
35641
35814
|
const bytes = toUint8Array(pdf);
|
|
35642
|
-
const context = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, undefined, capNumbers, undefined, forIncrementalUpdate).parseDocument();
|
|
35815
|
+
const context = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, undefined, capNumbers, undefined, forIncrementalUpdate, preserveObjectsVersions).parseDocument();
|
|
35643
35816
|
if (!!context.lookup(context.trailerInfo.Encrypt) &&
|
|
35644
35817
|
password !== undefined) {
|
|
35645
35818
|
// Decrypt
|
|
35646
35819
|
const fileIds = context.lookup(context.trailerInfo.ID, PDFArray);
|
|
35647
35820
|
const encryptDict = context.lookup(context.trailerInfo.Encrypt, PDFDict);
|
|
35648
|
-
const decryptedContext = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password), forIncrementalUpdate).parseDocument();
|
|
35821
|
+
const decryptedContext = yield PDFParser.forBytesWithOptions(bytes, parseSpeed, throwOnInvalidObject, warnOnInvalidObjects, capNumbers, new CipherTransformFactory(encryptDict, fileIds.get(0).asBytes(), password), forIncrementalUpdate, preserveObjectsVersions).parseDocument();
|
|
35649
35822
|
const pdfDoc = new PDFDocument(decryptedContext, true, updateMetadata);
|
|
35650
35823
|
if (forIncrementalUpdate)
|
|
35651
35824
|
pdfDoc.takeSnapshot();
|
|
@@ -36108,8 +36281,10 @@ class PDFDocument {
|
|
|
36108
36281
|
if (this.pageCount === 0)
|
|
36109
36282
|
throw new RemovePageFromEmptyDocumentError();
|
|
36110
36283
|
assertRange(index, 'index', 0, pageCount - 1);
|
|
36284
|
+
const page = this.getPage(index);
|
|
36111
36285
|
this.catalog.removeLeafNode(index);
|
|
36112
36286
|
this.pageCount = pageCount - 1;
|
|
36287
|
+
this.context.delete(page.ref);
|
|
36113
36288
|
}
|
|
36114
36289
|
/**
|
|
36115
36290
|
* Add a page to the end of this document. This method accepts three
|
|
@@ -36937,6 +37112,51 @@ class PDFDocument {
|
|
|
36937
37112
|
}
|
|
36938
37113
|
return snapshot;
|
|
36939
37114
|
}
|
|
37115
|
+
/**
|
|
37116
|
+
* Returns the update version of the object as 'actual', and all the previous versions, of the objects
|
|
37117
|
+
* that has changed in the indicated update (or the last one).
|
|
37118
|
+
* If document wasn't load to preserve objects versions, an empty array is returned.
|
|
37119
|
+
* @param {number} lastUpdateMinusX If not the last update, how many updates before the last.
|
|
37120
|
+
* @returns {PDFObjectVersions[]} Objects modified in the update, and previous versions
|
|
37121
|
+
*/
|
|
37122
|
+
getChangedObjects(lastUpdateMinusX = 0) {
|
|
37123
|
+
if (!this.context.preserveObjectsVersions)
|
|
37124
|
+
return [];
|
|
37125
|
+
if (lastUpdateMinusX < 0)
|
|
37126
|
+
lastUpdateMinusX = 0;
|
|
37127
|
+
const upind = this.context.xrefs.length - lastUpdateMinusX - 1;
|
|
37128
|
+
const entries = this.context.listXrefEntries(upind);
|
|
37129
|
+
if (!entries.length)
|
|
37130
|
+
return [];
|
|
37131
|
+
const changed = new Map();
|
|
37132
|
+
for (const entry of entries) {
|
|
37133
|
+
const ref = entry.ref;
|
|
37134
|
+
changed.set(ref, {
|
|
37135
|
+
ref,
|
|
37136
|
+
actual: entry.deleted ? undefined : this.context.lookup(ref),
|
|
37137
|
+
previous: this.context.getObjectVersions(ref),
|
|
37138
|
+
});
|
|
37139
|
+
}
|
|
37140
|
+
// if not the las update, then check objects later modified and adjust PDFObjectVersions accordingly
|
|
37141
|
+
if (!lastUpdateMinusX)
|
|
37142
|
+
return Array.from(changed.entries()).map((value) => value[1]);
|
|
37143
|
+
while (lastUpdateMinusX) {
|
|
37144
|
+
lastUpdateMinusX -= 1;
|
|
37145
|
+
const upind = this.context.xrefs.length - lastUpdateMinusX - 1;
|
|
37146
|
+
const nentries = this.context.listXrefEntries(upind);
|
|
37147
|
+
for (const nentry of nentries) {
|
|
37148
|
+
const oce = changed.get(nentry.ref);
|
|
37149
|
+
if (oce && oce.actual) {
|
|
37150
|
+
oce.actual = oce.previous[0];
|
|
37151
|
+
oce.previous = oce.previous.slice(1);
|
|
37152
|
+
}
|
|
37153
|
+
}
|
|
37154
|
+
}
|
|
37155
|
+
// if PDF has errors, it may happen to end with objects that has no current, nor previous versions
|
|
37156
|
+
return Array.from(changed.entries())
|
|
37157
|
+
.map((value) => value[1])
|
|
37158
|
+
.filter((ov) => ov.actual || ov.previous.length);
|
|
37159
|
+
}
|
|
36940
37160
|
prepareForSave(options) {
|
|
36941
37161
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36942
37162
|
const { addDefaultPage = true, updateFieldAppearances = true } = options;
|