@adnsistemas/pdf-lib 2.7.2 → 2.8.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.
Files changed (90) hide show
  1. package/README.md +5 -3
  2. package/cjs/api/PDFDocument.d.ts +16 -2
  3. package/cjs/api/PDFDocument.d.ts.map +1 -1
  4. package/cjs/api/PDFDocument.js +59 -5
  5. package/cjs/api/PDFDocument.js.map +1 -1
  6. package/cjs/api/PDFEmbeddedFile.d.ts +6 -0
  7. package/cjs/api/PDFEmbeddedFile.d.ts.map +1 -1
  8. package/cjs/api/PDFEmbeddedFile.js +10 -0
  9. package/cjs/api/PDFEmbeddedFile.js.map +1 -1
  10. package/cjs/api/PDFPage.js +1 -1
  11. package/cjs/api/operations.js +2 -2
  12. package/cjs/api/operations.js.map +1 -1
  13. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  14. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  15. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  16. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  17. package/cjs/core/embedders/JpegEmbedder.d.ts.map +1 -1
  18. package/cjs/core/embedders/JpegEmbedder.js +1 -1
  19. package/cjs/core/embedders/JpegEmbedder.js.map +1 -1
  20. package/cjs/core/objects/PDFString.js +1 -1
  21. package/cjs/core/parser/PDFObjectParser.d.ts.map +1 -1
  22. package/cjs/core/parser/PDFObjectParser.js +2 -1
  23. package/cjs/core/parser/PDFObjectParser.js.map +1 -1
  24. package/cjs/core/structures/PDFCatalog.d.ts +3 -0
  25. package/cjs/core/structures/PDFCatalog.d.ts.map +1 -1
  26. package/cjs/core/structures/PDFCatalog.js +7 -0
  27. package/cjs/core/structures/PDFCatalog.js.map +1 -1
  28. package/cjs/core/writers/PDFWriter.d.ts +8 -3
  29. package/cjs/core/writers/PDFWriter.d.ts.map +1 -1
  30. package/cjs/core/writers/PDFWriter.js +30 -7
  31. package/cjs/core/writers/PDFWriter.js.map +1 -1
  32. package/dist/pdf-lib.esm.js +115 -25
  33. package/dist/pdf-lib.esm.js.map +1 -1
  34. package/dist/pdf-lib.esm.min.js +3 -3
  35. package/dist/pdf-lib.esm.min.js.map +1 -1
  36. package/dist/pdf-lib.js +115 -25
  37. package/dist/pdf-lib.js.map +1 -1
  38. package/dist/pdf-lib.min.js +3 -3
  39. package/dist/pdf-lib.min.js.map +1 -1
  40. package/es/api/PDFDocument.d.ts +16 -2
  41. package/es/api/PDFDocument.d.ts.map +1 -1
  42. package/es/api/PDFDocument.js +59 -5
  43. package/es/api/PDFDocument.js.map +1 -1
  44. package/es/api/PDFEmbeddedFile.d.ts +6 -0
  45. package/es/api/PDFEmbeddedFile.d.ts.map +1 -1
  46. package/es/api/PDFEmbeddedFile.js +10 -0
  47. package/es/api/PDFEmbeddedFile.js.map +1 -1
  48. package/es/api/PDFPage.js +1 -1
  49. package/es/api/operations.js +2 -2
  50. package/es/api/operations.js.map +1 -1
  51. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  52. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  53. package/es/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  54. package/es/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  55. package/es/core/embedders/JpegEmbedder.d.ts.map +1 -1
  56. package/es/core/embedders/JpegEmbedder.js +1 -1
  57. package/es/core/embedders/JpegEmbedder.js.map +1 -1
  58. package/es/core/objects/PDFString.js +1 -1
  59. package/es/core/parser/PDFObjectParser.d.ts.map +1 -1
  60. package/es/core/parser/PDFObjectParser.js +3 -2
  61. package/es/core/parser/PDFObjectParser.js.map +1 -1
  62. package/es/core/structures/PDFCatalog.d.ts +3 -0
  63. package/es/core/structures/PDFCatalog.d.ts.map +1 -1
  64. package/es/core/structures/PDFCatalog.js +7 -0
  65. package/es/core/structures/PDFCatalog.js.map +1 -1
  66. package/es/core/writers/PDFWriter.d.ts +8 -3
  67. package/es/core/writers/PDFWriter.d.ts.map +1 -1
  68. package/es/core/writers/PDFWriter.js +30 -7
  69. package/es/core/writers/PDFWriter.js.map +1 -1
  70. package/package.json +4 -2
  71. package/src/api/PDFDocument.ts +75 -10
  72. package/src/api/PDFEmbeddedFile.ts +12 -0
  73. package/src/api/PDFPage.ts +1 -1
  74. package/src/api/operations.ts +2 -2
  75. package/src/api/snapshot/IncrementalDocumentSnapshot.ts +5 -11
  76. package/src/core/embedders/JpegEmbedder.ts +5 -1
  77. package/src/core/objects/PDFString.ts +1 -1
  78. package/src/core/parser/PDFObjectParser.ts +5 -2
  79. package/src/core/structures/PDFCatalog.ts +9 -0
  80. package/src/core/writers/PDFWriter.ts +32 -9
  81. package/ts3.4/cjs/api/PDFDocument.d.ts +16 -2
  82. package/ts3.4/cjs/api/PDFEmbeddedFile.d.ts +6 -0
  83. package/ts3.4/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  84. package/ts3.4/cjs/core/structures/PDFCatalog.d.ts +3 -0
  85. package/ts3.4/cjs/core/writers/PDFWriter.d.ts +11 -3
  86. package/ts3.4/es/api/PDFDocument.d.ts +16 -2
  87. package/ts3.4/es/api/PDFEmbeddedFile.d.ts +6 -0
  88. package/ts3.4/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  89. package/ts3.4/es/core/structures/PDFCatalog.d.ts +3 -0
  90. package/ts3.4/es/core/writers/PDFWriter.d.ts +11 -3
@@ -9002,7 +9002,7 @@ class PDFString extends PDFObject {
9002
9002
  pushByte(CharCodes$1.LeftParen);
9003
9003
  else if (byte === CharCodes$1.RightParen)
9004
9004
  pushByte(CharCodes$1.RightParen);
9005
- else if (byte === CharCodes$1.Backspace)
9005
+ else if (byte === CharCodes$1.BackSlash)
9006
9006
  pushByte(CharCodes$1.BackSlash);
9007
9007
  else if (byte >= CharCodes$1.Zero && byte <= CharCodes$1.Seven) {
9008
9008
  octal += char;
@@ -9982,13 +9982,9 @@ class IncrementalDocumentSnapshot {
9982
9982
  this.context = context;
9983
9983
  }
9984
9984
  shouldSave(objectNumber) {
9985
- if (objectNumber > this.lastObjectNumber) {
9985
+ if (objectNumber > this.lastObjectNumber)
9986
9986
  return true;
9987
- }
9988
- if (this.changedObjects.includes(objectNumber)) {
9989
- return true;
9990
- }
9991
- return false;
9987
+ return this.changedObjects.has(objectNumber);
9992
9988
  }
9993
9989
  markRefForSave(ref) {
9994
9990
  this.markRefsForSave([ref]);
@@ -9996,7 +9992,7 @@ class IncrementalDocumentSnapshot {
9996
9992
  markRefsForSave(refs) {
9997
9993
  refs.forEach((ref) => {
9998
9994
  if (ref)
9999
- this.changedObjects.push(ref.objectNumber);
9995
+ this.changedObjects.add(ref.objectNumber);
10000
9996
  });
10001
9997
  }
10002
9998
  markObjForSave(obj) {
@@ -10331,6 +10327,11 @@ class PDFWriter {
10331
10327
  * be corrected, to be accurate.
10332
10328
  */
10333
10329
  this._largestSkippedObjectNum = 0;
10330
+ /**
10331
+ * Used to check wheter an object should be saved or not, preserves the object number of the
10332
+ * last XRef Stream object, if there is one.
10333
+ */
10334
+ this._lastXRefObjectNumber = 0;
10334
10335
  this.shouldWaitForTick = (n) => {
10335
10336
  this.parsedObjects += n;
10336
10337
  return this.parsedObjects % this.objectsPerTick === 0;
@@ -10341,20 +10342,37 @@ class PDFWriter {
10341
10342
  }
10342
10343
  /**
10343
10344
  * For incremental saves, defers the decision to the snapshot.
10344
- * For full saves, checks that the object is not an XRef stream object.
10345
+ * For full saves, checks that the object is not the last XRef stream object.
10345
10346
  * @param {boolean} incremental If making an incremental save, or a full save of the PDF
10346
10347
  * @param {number} objNum Object number
10347
- * @param {PDFObject} object PDFObject used to check if it is an XRef stream, when not 'incremental' saving
10348
+ * @param {[PDFRef, PDFObject][]} objects List of objects that form the PDF
10348
10349
  * @returns {boolean} whether the object should be saved or not
10349
10350
  */
10350
- shouldSave(incremental, objNum, object) {
10351
+ shouldSave(incremental, objNum, objects) {
10351
10352
  let should = true;
10352
10353
  if (incremental) {
10353
10354
  should = this.snapshot.shouldSave(objNum);
10354
10355
  }
10355
10356
  else {
10356
- should = !(object instanceof PDFRawStream &&
10357
- object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef'));
10357
+ // only the last XRef Stream will be regenerated on save
10358
+ if (!this._lastXRefObjectNumber) {
10359
+ // if no XRef Stream, then nothing should be skipped
10360
+ this._lastXRefObjectNumber = this.context.largestObjectNumber + 1;
10361
+ const checkWatermark = this._lastXRefObjectNumber - 10; // max number of objects in the final part of the PDF to check
10362
+ // search the last XRef Stream, if there is one, objects are expected to be in object number order
10363
+ for (let idx = objects.length - 1; idx > 0; idx--) {
10364
+ // if not in last 'rangeToCheck' objects, there is none that should be skipped, most probably a linearized PDF, or without XRef Streams
10365
+ if (objects[idx][0].objectNumber < checkWatermark)
10366
+ break;
10367
+ const object = objects[idx][1];
10368
+ if (object instanceof PDFRawStream &&
10369
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
10370
+ this._lastXRefObjectNumber = objects[idx][0].objectNumber;
10371
+ break;
10372
+ }
10373
+ }
10374
+ }
10375
+ should = objNum !== this._lastXRefObjectNumber;
10358
10376
  }
10359
10377
  if (!should && this._largestSkippedObjectNum < objNum)
10360
10378
  this._largestSkippedObjectNum = objNum;
@@ -10373,7 +10391,7 @@ class PDFWriter {
10373
10391
  buffer[offset++] = CharCodes$1.Newline;
10374
10392
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
10375
10393
  const [ref, object] = indirectObjects[idx];
10376
- if (!this.shouldSave(incremental, ref.objectNumber, object)) {
10394
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects)) {
10377
10395
  continue;
10378
10396
  }
10379
10397
  const objectNumber = String(ref.objectNumber);
@@ -10439,6 +10457,7 @@ class PDFWriter {
10439
10457
  computeBufferSize(incremental) {
10440
10458
  return __awaiter(this, void 0, void 0, function* () {
10441
10459
  this._largestSkippedObjectNum = 0;
10460
+ this._lastXRefObjectNumber = 0;
10442
10461
  const header = PDFHeader.forVersion(1, 7);
10443
10462
  let size = this.snapshot.pdfSize;
10444
10463
  if (!incremental) {
@@ -10451,7 +10470,7 @@ class PDFWriter {
10451
10470
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
10452
10471
  const indirectObject = indirectObjects[idx];
10453
10472
  const [ref, object] = indirectObject;
10454
- if (!this.shouldSave(incremental, ref.objectNumber, object))
10473
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects))
10455
10474
  continue;
10456
10475
  if (security)
10457
10476
  this.encrypt(ref, object, security);
@@ -12426,6 +12445,12 @@ class PDFCatalog extends PDFDict {
12426
12445
  AcroForm() {
12427
12446
  return this.lookupMaybe(PDFName.of('AcroForm'), PDFDict);
12428
12447
  }
12448
+ Names() {
12449
+ return this.lookupMaybe(PDFName.of('Names'), PDFDict);
12450
+ }
12451
+ AttachedFiles() {
12452
+ return this.lookupMaybe(PDFName.of('AF'), PDFArray);
12453
+ }
12429
12454
  getAcroForm() {
12430
12455
  const dict = this.AcroForm();
12431
12456
  if (!dict)
@@ -13256,7 +13281,7 @@ const ChannelToColorSpace = {
13256
13281
  class JpegEmbedder {
13257
13282
  static for(imageData) {
13258
13283
  return __awaiter(this, void 0, void 0, function* () {
13259
- const dataView = new DataView(imageData.buffer);
13284
+ const dataView = new DataView(imageData.buffer, imageData.byteOffset, imageData.byteLength);
13260
13285
  const soi = dataView.getUint16(0);
13261
13286
  if (soi !== 0xffd8)
13262
13287
  throw new Error('SOI not found in JPEG');
@@ -15913,7 +15938,8 @@ class PDFObjectParser extends BaseParser {
15913
15938
  let actualValue = value.substring(1, value.length - 1);
15914
15939
  if (this.cryptoFactory && ref) {
15915
15940
  const transformer = this.cryptoFactory.createCipherTransform(ref.objectNumber, ref.generationNumber);
15916
- actualValue = transformer.decryptString(actualValue);
15941
+ const decrypted = transformer.decryptBytes(PDFString.of(actualValue).asBytes());
15942
+ actualValue = arrayAsString(decrypted);
15917
15943
  }
15918
15944
  // Remove the outer parens so they aren't part of the contents
15919
15945
  return PDFString.of(actualValue);
@@ -29497,13 +29523,13 @@ const drawOptionList = (options) => {
29497
29523
  ];
29498
29524
  };
29499
29525
  const getDrawingOperator = ({ color, borderWidth, borderColor, fillRule, }) => {
29500
- if (color && borderColor && borderWidth) {
29526
+ if (color && borderColor && borderWidth !== 0) {
29501
29527
  return fillAndStroke;
29502
29528
  }
29503
29529
  else if (color) {
29504
29530
  return fillRule === FillRule.EvenOdd ? fillEvenOdd : fill;
29505
29531
  }
29506
- else if (borderColor && borderWidth) {
29532
+ else if (borderColor && borderWidth !== 0) {
29507
29533
  return stroke;
29508
29534
  }
29509
29535
  return undefined;
@@ -34208,6 +34234,16 @@ class PDFEmbeddedFile {
34208
34234
  getEmbedder() {
34209
34235
  return this.embedder;
34210
34236
  }
34237
+ /**
34238
+ * Returns whether or not this file has already been embedded.
34239
+ * @returns true if the file has already been embedded, false otherwise.
34240
+ */
34241
+ getAlreadyEmbedded() {
34242
+ return this.alreadyEmbedded;
34243
+ }
34244
+ getRef() {
34245
+ return this.ref;
34246
+ }
34211
34247
  }
34212
34248
  /**
34213
34249
  * > **NOTE:** You probably don't want to call this method directly. Instead,
@@ -36770,13 +36806,17 @@ class PDFDocument {
36770
36806
  for (let idx = 0, len = EFNames.size(); idx < len; idx += 2) {
36771
36807
  const fileName = EFNames.lookup(idx);
36772
36808
  const fileSpec = EFNames.lookup(idx + 1, PDFDict);
36773
- rawAttachments.push({ fileName, fileSpec });
36809
+ rawAttachments.push({
36810
+ fileName,
36811
+ fileSpec,
36812
+ specRef: EFNames.get(idx + 1),
36813
+ });
36774
36814
  }
36775
36815
  return rawAttachments;
36776
36816
  }
36777
36817
  getSavedAttachments() {
36778
36818
  const rawAttachments = this.getRawAttachments();
36779
- return rawAttachments.flatMap(({ fileName, fileSpec }) => {
36819
+ return rawAttachments.flatMap(({ fileName, fileSpec, specRef }) => {
36780
36820
  const efDict = fileSpec.lookup(PDFName.of('EF'));
36781
36821
  if (!(efDict instanceof PDFDict))
36782
36822
  return [];
@@ -36809,7 +36849,11 @@ class PDFDocument {
36809
36849
  modificationDate = modDateRaw.decodeDate();
36810
36850
  }
36811
36851
  }
36812
- const description = fileSpec.lookup(PDFName.of('Desc')).decodeText();
36852
+ const descRaw = fileSpec.lookup(PDFName.of('Desc'));
36853
+ let description;
36854
+ if (descRaw instanceof PDFHexString) {
36855
+ description = descRaw.decodeText();
36856
+ }
36813
36857
  return [
36814
36858
  {
36815
36859
  name: fileName.decodeText(),
@@ -36819,12 +36863,16 @@ class PDFDocument {
36819
36863
  description,
36820
36864
  creationDate,
36821
36865
  modificationDate,
36866
+ embeddedFileDict: efDict,
36867
+ specRef,
36822
36868
  },
36823
36869
  ];
36824
36870
  });
36825
36871
  }
36826
36872
  getUnsavedAttachments() {
36827
- const attachments = this.embeddedFiles.map((file) => {
36873
+ const attachments = this.embeddedFiles.flatMap((file) => {
36874
+ if (file.getAlreadyEmbedded())
36875
+ return [];
36828
36876
  const embedder = file.getEmbedder();
36829
36877
  return {
36830
36878
  name: embedder.fileName,
@@ -36834,6 +36882,7 @@ class PDFDocument {
36834
36882
  afRelationship: embedder.options.afRelationship,
36835
36883
  creationDate: embedder.options.creationDate,
36836
36884
  modificationDate: embedder.options.modificationDate,
36885
+ pdfEmbeddedFile: file,
36837
36886
  };
36838
36887
  });
36839
36888
  return attachments;
@@ -36848,6 +36897,47 @@ class PDFDocument {
36848
36897
  const unsavedAttachments = this.getUnsavedAttachments();
36849
36898
  return [...savedAttachments, ...unsavedAttachments];
36850
36899
  }
36900
+ /**
36901
+ * Removes an attachment from PDF, based on name.
36902
+ * @param {string} name Name of the attachmet to remove.
36903
+ */
36904
+ detach(name) {
36905
+ const attachedFiles = this.getAttachments();
36906
+ attachedFiles.forEach((file) => {
36907
+ var _a, _b, _c;
36908
+ if (file.name !== name)
36909
+ return;
36910
+ // the file wasn't embedded into context yet
36911
+ if ('pdfEmbeddedFile' in file) {
36912
+ const i = this.embeddedFiles.findIndex((f) => file.pdfEmbeddedFile === f);
36913
+ if (i !== undefined)
36914
+ this.embeddedFiles.splice(i, 1);
36915
+ }
36916
+ else {
36917
+ // remove references from catalog
36918
+ const namesArr = (_a = this.catalog
36919
+ .Names()) === null || _a === void 0 ? void 0 : _a.lookup(PDFName.of('EmbeddedFiles'), PDFDict).lookup(PDFName.of('Names'), PDFArray);
36920
+ const iNames = namesArr === null || namesArr === void 0 ? void 0 : namesArr.indexOf(file.specRef);
36921
+ if (iNames !== undefined && iNames > 0) {
36922
+ // attachment spec ref
36923
+ namesArr === null || namesArr === void 0 ? void 0 : namesArr.remove(iNames);
36924
+ // attachment name
36925
+ namesArr === null || namesArr === void 0 ? void 0 : namesArr.remove(iNames - 1);
36926
+ }
36927
+ // AF-Tag for PDF-A3 compliance
36928
+ const AF = this.catalog.AttachedFiles();
36929
+ const afIndex = AF === null || AF === void 0 ? void 0 : AF.indexOf(file.specRef);
36930
+ if (afIndex !== undefined)
36931
+ AF === null || AF === void 0 ? void 0 : AF.remove(afIndex);
36932
+ // remove references from context
36933
+ const streamRef = (_c = (_b = this.context
36934
+ .lookupMaybe(file.specRef, PDFDict)) === null || _b === void 0 ? void 0 : _b.lookupMaybe(PDFName.of('EF'), PDFDict)) === null || _c === void 0 ? void 0 : _c.get(PDFName.of('F'));
36935
+ if (streamRef)
36936
+ this.context.delete(streamRef);
36937
+ this.context.delete(file.specRef);
36938
+ }
36939
+ });
36940
+ }
36851
36941
  /**
36852
36942
  * Embed a font into this document. The input data can be provided in multiple
36853
36943
  * formats:
@@ -37305,7 +37395,7 @@ class PDFDocument {
37305
37395
  return undefined;
37306
37396
  }
37307
37397
  takeSnapshot() {
37308
- const indirectObjects = [];
37398
+ const indirectObjects = new Set();
37309
37399
  const snapshot = new IncrementalDocumentSnapshot(this.context.largestObjectNumber, indirectObjects, this.context.pdfFileDetails.pdfSize, this.context.pdfFileDetails.prevStartXRef, this.context);
37310
37400
  if (!this.context.snapshot && this.context.pdfFileDetails.originalBytes) {
37311
37401
  this.context.snapshot = snapshot;
@@ -38539,7 +38629,7 @@ class PDFPage {
38539
38629
  rotate: (_c = options.rotate) !== null && _c !== void 0 ? _c : degrees(0),
38540
38630
  color: (_d = options.color) !== null && _d !== void 0 ? _d : undefined,
38541
38631
  borderColor: (_e = options.borderColor) !== null && _e !== void 0 ? _e : undefined,
38542
- borderWidth: (_f = options.borderWidth) !== null && _f !== void 0 ? _f : 0,
38632
+ borderWidth: (_f = options.borderWidth) !== null && _f !== void 0 ? _f : 1,
38543
38633
  borderDashArray: (_g = options.borderDashArray) !== null && _g !== void 0 ? _g : undefined,
38544
38634
  borderDashPhase: (_h = options.borderDashPhase) !== null && _h !== void 0 ? _h : undefined,
38545
38635
  borderLineCap: (_j = options.borderLineCap) !== null && _j !== void 0 ? _j : undefined,