pdfmake 0.3.12 → 0.3.13

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.13 - 2026-10-25
4
+
5
+ - Added horizontal table alignment via `tableAlignment`: `left` (default), `center`, or `right`
6
+ - Fixed PDF stream errors not rejecting promises returned by `getBuffer()`, `getBase64()` and `getDataUrl()`
7
+ - Fixed `getStream()` returning an already consumed stream; subsequent stream access now rejects
8
+ - Fixed `write()` hanging or failing after `getBuffer()`, `getBase64()` or `getDataUrl()` by reusing buffered PDF data
9
+ - Fixed attachments loaded from the virtual file system (including downloaded URL attachments) failing with "No src specified"
10
+ - Fixed sections with automatic page height sharing the first section's height and clipping content in subsequent sections
11
+ - Fixed vertical alignment of row-spanned table header cells when the table starts on a subsequent page
12
+ - Fixed text decoration positioning and automatic thickness for mixed font sizes depending on the order of text fragments
13
+ - Fixed adjacent text fragments with different `decorationThickness` values being rendered with the same decoration thickness
14
+ - Fixed wavy text decoration clipping height incorrectly depending on the vertical position on the page
15
+ - Fixed reversed paint order of table cell background fills in unbreakable blocks, which caused outer table fills to cover nested table fills
16
+ - Fixed percentage table column widths using incorrect padding and border widths when mixed with `auto` or star-sized columns
17
+ - Fixed `TypeError: Invalid base URL` when loading the browser build in React Native
18
+
3
19
  ## 0.3.12 - 2026-10-17
4
20
 
5
21
  - **Reduced browser bundle size by over 20%**
package/build/pdfmake.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! pdfmake v0.3.12, @license MIT, @link http://pdfmake.org */
1
+ /*! pdfmake v0.3.13, @license MIT, @link http://pdfmake.org */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory();
@@ -3840,7 +3840,7 @@ if ( true && module && typeof module.exports !== 'undefined') {
3840
3840
 
3841
3841
  /***/ },
3842
3842
 
3843
- /***/ 212
3843
+ /***/ 1862
3844
3844
  (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3845
3845
 
3846
3846
  "use strict";
@@ -5588,10 +5588,10 @@ var SHARED = '__core-js_shared__';
5588
5588
  var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {});
5589
5589
 
5590
5590
  (store.versions || (store.versions = [])).push({
5591
- version: '3.50.0',
5591
+ version: '3.51.0',
5592
5592
  mode: IS_PURE ? 'pure' : 'global',
5593
5593
  copyright: '© 2013–2025 Denis Pushkarev (zloirock.ru), 2025–2026 CoreJS Company (core-js.io). All rights reserved.',
5594
- license: 'https://github.com/zloirock/core-js/blob/v3.50.0/LICENSE',
5594
+ license: 'https://github.com/zloirock/core-js/blob/v3.51.0/LICENSE',
5595
5595
  source: 'https://github.com/zloirock/core-js'
5596
5596
  });
5597
5597
 
@@ -33728,7 +33728,7 @@ function isSameDate(a, b) {
33728
33728
  return a.getTime() === b.getTime();
33729
33729
  }
33730
33730
 
33731
- const ICC_PROFILE_PATH = new URL('./data/sRGB_IEC61966_2_1.icc', "file:///home/runner/work/pdfmake/pdfmake/node_modules/pdfkit/js/pdfkit.browser.mjs").href;
33731
+ const ICC_PROFILE_PATH = 'pdfkit/builtin/sRGB_IEC61966_2_1.icc';
33732
33732
  let iccProfile;
33733
33733
  var PDFA = {
33734
33734
  initPDFA(pSubset) {
@@ -35060,12 +35060,12 @@ class PDFDocument extends pdfkit_browser_PDFDocument {
35060
35060
  }
35061
35061
  return obj;
35062
35062
  };
35063
- if (typeof src === 'object') {
35064
- return checkRequired(src);
35065
- }
35066
- let attachment = checkRequired(this.attachments[src]);
35063
+ let attachment = checkRequired(typeof src === 'object' ? src : this.attachments[src]);
35067
35064
  if (this.virtualfs && this.virtualfs.existsSync(attachment.src)) {
35068
- return this.virtualfs.readFileSync(attachment.src);
35065
+ return {
35066
+ ...attachment,
35067
+ src: this.virtualfs.readFileSync(attachment.src)
35068
+ };
35069
35069
  }
35070
35070
  this.validateLocalFile(attachment.src);
35071
35071
  return attachment;
@@ -36077,7 +36077,7 @@ function buildColumnWidths(columns, availableWidth, offsetTotal, tableNode) {
36077
36077
  let starMaxMax = 0;
36078
36078
  let fixedColumns = [];
36079
36079
  let initial_availableWidth = availableWidth;
36080
- columns.forEach(column => {
36080
+ columns.forEach((column, colIndex) => {
36081
36081
  if (isAutoColumn(column)) {
36082
36082
  autoColumns.push(column);
36083
36083
  autoMin += column._minWidth;
@@ -36087,10 +36087,17 @@ function buildColumnWidths(columns, availableWidth, offsetTotal, tableNode) {
36087
36087
  starMaxMin = Math.max(starMaxMin, column._minWidth);
36088
36088
  starMaxMax = Math.max(starMaxMax, column._maxWidth);
36089
36089
  } else {
36090
- fixedColumns.push(column);
36090
+ fixedColumns.push({
36091
+ column,
36092
+ colIndex
36093
+ });
36091
36094
  }
36092
36095
  });
36093
- fixedColumns.forEach((col, colIndex) => {
36096
+ fixedColumns.forEach(_ref => {
36097
+ let {
36098
+ column: col,
36099
+ colIndex
36100
+ } = _ref;
36094
36101
  // width specified as %
36095
36102
  if (isString(col.width) && /\d+%/.test(col.width)) {
36096
36103
  // In tables we have to take into consideration the reserved width for paddings and borders
@@ -36103,7 +36110,7 @@ function buildColumnWidths(columns, availableWidth, offsetTotal, tableNode) {
36103
36110
  if (colIndex === 0) {
36104
36111
  // first column assumes whole borderLeft and half of border right
36105
36112
  reservedWidth = paddingLeft + paddingRight + borderLeft + borderRight / 2;
36106
- } else if (colIndex === fixedColumns.length - 1) {
36113
+ } else if (colIndex === columns.length - 1) {
36107
36114
  // last column assumes whole borderRight and half of border left
36108
36115
  reservedWidth = paddingLeft + paddingRight + borderLeft / 2 + borderRight;
36109
36116
  } else {
@@ -38206,7 +38213,9 @@ class DocumentContext extends (events_namespaceFn().EventEmitter) {
38206
38213
  }
38207
38214
  let page = {
38208
38215
  items: [],
38209
- pageSize: pageSize,
38216
+ pageSize: {
38217
+ ...pageSize
38218
+ },
38210
38219
  pageMargins: this.pageMargins,
38211
38220
  customProperties: customProperties
38212
38221
  };
@@ -38558,6 +38567,7 @@ class ElementWriter extends (events_namespaceFn().EventEmitter) {
38558
38567
  if (!useBlockXOffset && block.height > ctx.availableHeight) {
38559
38568
  return false;
38560
38569
  }
38570
+ let unbreakableFillsInserted = 0;
38561
38571
  block.items.forEach(item => {
38562
38572
  switch (item.type) {
38563
38573
  case 'line':
@@ -38577,9 +38587,11 @@ class ElementWriter extends (events_namespaceFn().EventEmitter) {
38577
38587
  offsetVector(v, useBlockXOffset ? block.xOffset || 0 : ctx.x, useBlockYOffset ? block.yOffset || 0 : ctx.y);
38578
38588
  if (v._isFillColorFromUnbreakable) {
38579
38589
  // If the item is a fillColor from an unbreakable block
38580
- // We have to add it at the beginning of the items body array of the page
38590
+ // We have to add it at the beginning of the items body array of the page,
38591
+ // after the fills already inserted from this block so that they keep their draw order
38581
38592
  delete v._isFillColorFromUnbreakable;
38582
- const endOfBackgroundItemsIndex = ctx.backgroundLength[ctx.page];
38593
+ const endOfBackgroundItemsIndex = ctx.backgroundLength[ctx.page] + unbreakableFillsInserted;
38594
+ unbreakableFillsInserted++;
38583
38595
  page.items.splice(endOfBackgroundItemsIndex, 0, {
38584
38596
  type: 'vector',
38585
38597
  item: v
@@ -38936,9 +38948,13 @@ class PageElementWriter extends src_ElementWriter {
38936
38948
  /**
38937
38949
  * Move to the next column in a column group (snaking columns).
38938
38950
  * Handles repeatables and emits columnChanged event.
38951
+ * @param {Function} [updateContext] - Adjust the new column before inserting repeatables
38939
38952
  */
38940
- moveToNextColumn() {
38953
+ moveToNextColumn(updateContext) {
38941
38954
  let nextColumn = this.context().moveToNextColumn();
38955
+ if (updateContext) {
38956
+ updateContext(this.context());
38957
+ }
38942
38958
 
38943
38959
  // Handle repeatables (like table headers) for the new column
38944
38960
  this.repeatables.forEach(function (rep) {
@@ -39149,6 +39165,7 @@ class TableProcessor {
39149
39165
  availableWidth = writer.context().availableWidth - this.offsets.total;
39150
39166
  columnCalculator.buildColumnWidths(tableNode.table.widths, availableWidth, this.offsets.total, tableNode);
39151
39167
  this.tableWidth = tableNode._offsets.total + getTableInnerContentWidth();
39168
+ this.alignTable(writer.context());
39152
39169
  this.rowSpanData = prepareRowSpanData();
39153
39170
  this.cleanUpRepeatables = false;
39154
39171
 
@@ -39181,6 +39198,15 @@ class TableProcessor {
39181
39198
  // update the border properties of all cells before drawing any lines
39182
39199
  prepareCellBorders(this.tableNode.table.body);
39183
39200
  }
39201
+ alignTable(context) {
39202
+ const freeWidth = Math.max(0, context.availableWidth - this.tableWidth);
39203
+ this.alignmentOffset = this.tableNode.tableAlignment === 'center' ? freeWidth / 2 : this.tableNode.tableAlignment === 'right' ? freeWidth : 0;
39204
+ if (this.alignmentOffset) {
39205
+ // Keep the container width intact: column widths have already been resolved.
39206
+ // Row snapshots preserve this origin across page breaks.
39207
+ context.addMargin(this.alignmentOffset, -this.alignmentOffset);
39208
+ }
39209
+ }
39184
39210
  onRowBreak(rowIndex, writer) {
39185
39211
  return () => {
39186
39212
  let offset = this.rowPaddingTop + (!this.headerRows ? this.topLineWidth : 0);
@@ -39390,6 +39416,9 @@ class TableProcessor {
39390
39416
  if (this.cleanUpRepeatables) {
39391
39417
  writer.popFromRepeatables();
39392
39418
  }
39419
+ if (this.alignmentOffset) {
39420
+ writer.context().addMargin(-this.alignmentOffset, this.alignmentOffset);
39421
+ }
39393
39422
  }
39394
39423
  endRow(rowIndex, writer, pageBreaks) {
39395
39424
  const getLineXs = () => {
@@ -40215,8 +40244,9 @@ class LayoutBuilder {
40215
40244
  * When in snaking columns, first tries moving to next column.
40216
40245
  * If no columns available, moves to next page and resets x to left margin.
40217
40246
  * @param {string} pageOrientation - Optional page orientation for the new page
40247
+ * @param {TableProcessor} [tableProcessor] - Reapply table alignment in the new column
40218
40248
  */
40219
- snakingAwarePageBreak(pageOrientation) {
40249
+ snakingAwarePageBreak(pageOrientation, tableProcessor) {
40220
40250
  let ctx = this.writer.context();
40221
40251
  let snakingSnapshot = ctx.getSnakingSnapshot();
40222
40252
  if (!snakingSnapshot) {
@@ -40225,7 +40255,7 @@ class LayoutBuilder {
40225
40255
 
40226
40256
  // Try flowing to next column first
40227
40257
  if (this.writer.canMoveToNextColumn()) {
40228
- this.writer.moveToNextColumn();
40258
+ this.writer.moveToNextColumn(tableProcessor ? context => tableProcessor.alignTable(context) : undefined);
40229
40259
  return;
40230
40260
  }
40231
40261
 
@@ -40239,6 +40269,9 @@ class LayoutBuilder {
40239
40269
  let savedLastColumnWidth = ctx.lastColumnWidth;
40240
40270
  ctx.resetSnakingColumnsForNewPage();
40241
40271
  ctx.lastColumnWidth = savedLastColumnWidth;
40272
+ if (tableProcessor) {
40273
+ tableProcessor.alignTable(ctx);
40274
+ }
40242
40275
  }
40243
40276
 
40244
40277
  // vertical container
@@ -40690,7 +40723,7 @@ class LayoutBuilder {
40690
40723
  let rowTopPageY = this.cell._leftEndingCell._startingRowSpanY + this.cell._leftEndingCell._rowTopPageYPadding;
40691
40724
  return this.cell._leftEndingCell._rowTopPageY - rowTopPageY + this.cell._leftEndingCell._bottomY;
40692
40725
  } else {
40693
- if (this.cell.positions[0].pageNumber !== this.cell._leftEndingCell._lastPageNumber) {
40726
+ if (this.cell._lastPageNumber !== this.cell._leftEndingCell._lastPageNumber) {
40694
40727
  return this.bottomY - this.cell._leftEndingCell._bottomY;
40695
40728
  }
40696
40729
  return this.viewHeight + this.cell._leftEndingCell._bottomY - this.bottomY;
@@ -40764,7 +40797,11 @@ class LayoutBuilder {
40764
40797
  // or fall back to a minimum of padding + line height + border
40765
40798
  let minRowHeight = lastRowHeight > 0 ? lastRowHeight : processor.rowPaddingTop + 14 + processor.rowPaddingBottom + processor.bottomLineWidth + processor.topLineWidth;
40766
40799
  if (this.writer.context().availableHeight < minRowHeight) {
40767
- this.snakingAwarePageBreak();
40800
+ // Column selection needs the container origin, before table alignment.
40801
+ if (processor.alignmentOffset) {
40802
+ this.writer.context().addMargin(-processor.alignmentOffset, processor.alignmentOffset);
40803
+ }
40804
+ this.snakingAwarePageBreak(undefined, processor);
40768
40805
 
40769
40806
  // Skip border when headerRows present (header repeat includes it)
40770
40807
  if (processor.layout.hLineWhenBroken !== false && !processor.headerRows) {
@@ -41147,7 +41184,7 @@ const groupDecorations = (line, pdfDocument) => {
41147
41184
  let thickness = isNumber(inline.decorationThickness) ? inline.decorationThickness : null;
41148
41185
  for (let ii = 0, ll = decoration.length; ii < ll; ii++) {
41149
41186
  let decorationItem = decoration[ii];
41150
- if (!currentGroup || decorationItem !== currentGroup.decoration || style !== currentGroup.decorationStyle || color !== currentGroup.decorationColor) {
41187
+ if (!currentGroup || decorationItem !== currentGroup.decoration || style !== currentGroup.decorationStyle || color !== currentGroup.decorationColor || thickness !== currentGroup.decorationThickness) {
41151
41188
  currentGroup = {
41152
41189
  line: line,
41153
41190
  decoration: decorationItem,
@@ -41195,7 +41232,7 @@ class TextDecorator {
41195
41232
  let max = 0;
41196
41233
  for (let i = 0, l = group.inlines.length; i < l; i++) {
41197
41234
  let inline = group.inlines[i];
41198
- max = inline.fontSize > max ? i : max;
41235
+ max = inline.fontSize > group.inlines[max].fontSize ? i : max;
41199
41236
  }
41200
41237
  return group.inlines[max];
41201
41238
  };
@@ -41261,7 +41298,7 @@ class TextDecorator {
41261
41298
  sv = 1;
41262
41299
  let nbWaves = Math.ceil(totalWidth / (sh * 2)) + 1;
41263
41300
  let rwx = x + firstInline.x - 1;
41264
- this.pdfDocument.rect(x + firstInline.x, y - sv, totalWidth, y + sv).clip();
41301
+ this.pdfDocument.rect(x + firstInline.x, y - sv, totalWidth, 2 * sv).clip();
41265
41302
  this.pdfDocument.lineWidth(lw / 3);
41266
41303
  this.pdfDocument.moveTo(rwx, y);
41267
41304
  for (let i = 0; i < nbWaves; i++) {
@@ -42172,13 +42209,25 @@ class OutputDocument {
42172
42209
  constructor(pdfDocumentPromise) {
42173
42210
  this.pdfDocumentPromise = pdfDocumentPromise;
42174
42211
  this.bufferPromise = null;
42212
+ this.streamEnded = false;
42213
+ this.streamEndListenerAttached = false;
42175
42214
  }
42176
42215
 
42177
42216
  /**
42178
42217
  * @returns {Promise<object>}
42179
42218
  */
42180
- getStream() {
42181
- return this.pdfDocumentPromise;
42219
+ async getStream() {
42220
+ const stream = await this.pdfDocumentPromise;
42221
+ if (this.streamEnded) {
42222
+ throw new Error('PDF stream has already been consumed.');
42223
+ }
42224
+ if (!this.streamEndListenerAttached) {
42225
+ stream.once('end', () => {
42226
+ this.streamEnded = true;
42227
+ });
42228
+ this.streamEndListenerAttached = true;
42229
+ }
42230
+ return stream;
42182
42231
  }
42183
42232
 
42184
42233
  /**
@@ -42187,7 +42236,7 @@ class OutputDocument {
42187
42236
  getBuffer() {
42188
42237
  const getBufferInternal = async () => {
42189
42238
  const stream = await this.getStream();
42190
- return new Promise(resolve => {
42239
+ return new Promise((resolve, reject) => {
42191
42240
  let chunks = [];
42192
42241
  stream.on('data', chunk => {
42193
42242
  chunks.push(chunk);
@@ -42195,6 +42244,7 @@ class OutputDocument {
42195
42244
  stream.on('end', () => {
42196
42245
  resolve(OutputDocument_Buffer.concat(chunks));
42197
42246
  });
42247
+ stream.on('error', reject);
42198
42248
  stream.end();
42199
42249
  });
42200
42250
  };
@@ -42222,7 +42272,7 @@ class OutputDocument {
42222
42272
  }
42223
42273
  /* harmony default export */ const src_OutputDocument = (OutputDocument);
42224
42274
  // EXTERNAL MODULE: ./node_modules/file-saver/dist/FileSaver.min.js
42225
- var FileSaver_min = __webpack_require__(8802);
42275
+ var FileSaver_min = __webpack_require__(3643);
42226
42276
  ;// ./src/browser-extensions/OutputDocumentBrowser.js
42227
42277
 
42228
42278
 
@@ -42378,7 +42428,7 @@ class browser_extensions_pdfmake extends src_base {
42378
42428
  /***/ 1001
42379
42429
  (module, __unused_webpack_exports, __webpack_require__) {
42380
42430
 
42381
- module.exports = __webpack_require__(212)["default"];
42431
+ module.exports = __webpack_require__(1862)["default"];
42382
42432
 
42383
42433
  /***/ },
42384
42434
 
@@ -49795,7 +49845,7 @@ module.exports = {
49795
49845
 
49796
49846
  /***/ },
49797
49847
 
49798
- /***/ 8802
49848
+ /***/ 3643
49799
49849
  (module, exports, __webpack_require__) {
49800
49850
 
49801
49851
  var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(a,b){if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b),