@pdfme/common 6.0.6 → 6.1.0-dev.2

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.
@@ -1,4 +1,4 @@
1
- import { Schema, Template, BasePdf, CommonOptions } from './types.js';
1
+ import { Schema, Template, BasePdf, CommonOptions, DynamicLayoutCallbackResult } from './types.js';
2
2
  interface ModifyTemplateForDynamicTableArg {
3
3
  template: Template;
4
4
  input: Record<string, string>;
@@ -9,7 +9,7 @@ interface ModifyTemplateForDynamicTableArg {
9
9
  basePdf: BasePdf;
10
10
  options: CommonOptions;
11
11
  _cache: Map<string | number, unknown>;
12
- }) => Promise<number[]>;
12
+ }) => Promise<DynamicLayoutCallbackResult>;
13
13
  }
14
14
  /**
15
15
  * Process a template containing tables with dynamic heights
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { PDFME_VERSION } from './version.js';
2
2
  import { MM_TO_PT_RATIO, PT_TO_MM_RATIO, PT_TO_PX_RATIO, BLANK_PDF, BLANK_A4_PDF, CUSTOM_A4_PDF, ZOOM, DEFAULT_FONT_NAME } from './constants.js';
3
- import type { ChangeSchemaItem, ChangeSchemas, SchemaPageArray, PropPanel, PropPanelSchema, PropPanelWidgetProps, PDFRenderProps, Mode, UIRenderProps, Plugin, Lang, Dict, Size, Schema, SchemaForUI, Font, ColorType, BasePdf, BlankPdf, CustomPdf, Template, CommonOptions, GeneratorOptions, Plugins, PluginRegistry, GenerateProps, UIOptions, UIProps, PreviewProps, DesignerProps } from './types.js';
3
+ import type { ChangeSchemaItem, ChangeSchemas, SchemaPageArray, PropPanel, PropPanelSchema, PropPanelWidgetProps, PDFRenderProps, Mode, UIRenderProps, Plugin, Lang, Dict, Size, Schema, SchemaForUI, Font, ColorType, BasePdf, BlankPdf, CustomPdf, Template, CommonOptions, GeneratorOptions, Plugins, PluginRegistry, GenerateProps, UIOptions, UIProps, PreviewProps, DesignerProps, DynamicLayoutArgs, DynamicLayoutCallbackResult, DynamicLayoutPatchArgs, DynamicLayoutResult, GetDynamicLayout } from './types.js';
4
4
  import { cloneDeep, getFallbackFontName, getDefaultFont, getB64BasePdf, b64toUint8Array, checkFont, checkInputs, checkUIOptions, checkTemplate, checkUIProps, checkPreviewProps, checkDesignerProps, checkGenerateProps, mm2pt, pt2mm, pt2px, px2mm, isHexValid, getInputFromTemplate, isBlankPdf, isUrlSafeToFetch } from './helper.js';
5
5
  import { getDynamicTemplate } from './dynamicTemplate.js';
6
6
  import { replacePlaceholders } from './expression.js';
7
7
  import { pluginRegistry } from './pluginRegistry.js';
8
8
  export { PDFME_VERSION, MM_TO_PT_RATIO, PT_TO_MM_RATIO, PT_TO_PX_RATIO, BLANK_PDF, BLANK_A4_PDF, CUSTOM_A4_PDF, ZOOM, DEFAULT_FONT_NAME, cloneDeep, getFallbackFontName, getDefaultFont, getB64BasePdf, b64toUint8Array, mm2pt, pt2mm, pt2px, px2mm, isHexValid, getInputFromTemplate, isBlankPdf, getDynamicTemplate, replacePlaceholders, checkFont, checkInputs, checkUIOptions, checkTemplate, checkUIProps, checkPreviewProps, checkDesignerProps, checkGenerateProps, pluginRegistry, isUrlSafeToFetch, };
9
- export type { Lang, Dict, Size, Schema, SchemaForUI, Font, ColorType, BasePdf, BlankPdf, CustomPdf, Template, CommonOptions, GeneratorOptions, Plugin, Plugins, PluginRegistry, GenerateProps, UIOptions, UIProps, PreviewProps, DesignerProps, ChangeSchemaItem, ChangeSchemas, SchemaPageArray, PropPanel, PropPanelSchema, PropPanelWidgetProps, PDFRenderProps, UIRenderProps, Mode, };
9
+ export type { Lang, Dict, Size, Schema, SchemaForUI, Font, ColorType, BasePdf, BlankPdf, CustomPdf, Template, CommonOptions, GeneratorOptions, Plugin, Plugins, PluginRegistry, GenerateProps, UIOptions, UIProps, PreviewProps, DesignerProps, ChangeSchemaItem, ChangeSchemas, SchemaPageArray, PropPanel, PropPanelSchema, PropPanelWidgetProps, PDFRenderProps, UIRenderProps, Mode, DynamicLayoutArgs, DynamicLayoutCallbackResult, DynamicLayoutPatchArgs, DynamicLayoutResult, GetDynamicLayout, };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { Buffer } from "buffer";
3
3
  import * as acorn from "acorn";
4
4
  //#region src/version.ts
5
- var PDFME_VERSION = "6.0.6";
5
+ var PDFME_VERSION = "6.1.0";
6
6
  //#endregion
7
7
  //#region src/constants.ts
8
8
  var PT_TO_PX_RATIO = 1.333;
@@ -105,10 +105,21 @@ z.object({
105
105
  "schemas.text.fit": z.string(),
106
106
  "schemas.text.dynamicFontSize": z.string(),
107
107
  "schemas.text.format": z.string(),
108
+ "schemas.text.plain": z.string(),
109
+ "schemas.text.inlineMarkdown": z.string(),
110
+ "schemas.text.markdownFonts": z.string(),
111
+ "schemas.text.boldFont": z.string(),
112
+ "schemas.text.italicFont": z.string(),
113
+ "schemas.text.boldItalicFont": z.string(),
114
+ "schemas.text.codeFont": z.string(),
115
+ "schemas.text.variantFallback": z.string(),
116
+ "schemas.text.synthetic": z.string(),
117
+ "schemas.text.error": z.string(),
108
118
  "schemas.radius": z.string(),
109
119
  "schemas.mvt.typingInstructions": z.string(),
110
120
  "schemas.mvt.sampleField": z.string(),
111
121
  "schemas.mvt.variablesSampleData": z.string(),
122
+ "schemas.mvt.placeholderDynamicVariable": z.string(),
112
123
  "schemas.barcodes.barColor": z.string(),
113
124
  "schemas.barcodes.includetext": z.string(),
114
125
  "schemas.table.alternateBackgroundColor": z.string(),
@@ -122,7 +133,18 @@ z.object({
122
133
  "schemas.date.locale": z.string(),
123
134
  "schemas.select.options": z.string(),
124
135
  "schemas.select.optionPlaceholder": z.string(),
125
- "schemas.radioGroup.groupName": z.string()
136
+ "schemas.radioGroup.groupName": z.string(),
137
+ "schemas.list.listStyle": z.string(),
138
+ "schemas.list.bullet": z.string(),
139
+ "schemas.list.ordered": z.string(),
140
+ "schemas.list.markerWidth": z.string(),
141
+ "schemas.list.markerGap": z.string(),
142
+ "schemas.list.indentSize": z.string(),
143
+ "schemas.list.itemSpacing": z.string(),
144
+ "schemas.list.addItem": z.string(),
145
+ "schemas.list.removeItem": z.string(),
146
+ "schemas.list.indentItem": z.string(),
147
+ "schemas.list.outdentItem": z.string()
126
148
  });
127
149
  z.enum([
128
150
  "viewer",
@@ -152,6 +174,10 @@ var Schema = z.object({
152
174
  start: z.number(),
153
175
  end: z.number().optional()
154
176
  }).optional(),
177
+ __itemRange: z.object({
178
+ start: z.number(),
179
+ end: z.number().optional()
180
+ }).optional(),
155
181
  __isSplit: z.boolean().optional()
156
182
  }).passthrough();
157
183
  var SchemaForUIAdditionalInfo = z.object({ id: z.string() });
@@ -440,7 +466,7 @@ function normalizePageSchemas(pageSchemas, paddingTop) {
440
466
  schema: cloneDeep(schema),
441
467
  baseY: localY,
442
468
  height: schema.height,
443
- dynamicHeights: [schema.height]
469
+ dynamicLayout: { heights: [schema.height] }
444
470
  });
445
471
  orderMap.set(schema.name, index);
446
472
  });
@@ -454,20 +480,21 @@ function normalizePageSchemas(pageSchemas, paddingTop) {
454
480
  };
455
481
  }
456
482
  /**
457
- * Place rows on pages, splitting across pages as needed.
483
+ * Place height units on pages, splitting across pages as needed.
458
484
  * @returns The final global Y coordinate after placement
459
485
  */
460
- function placeRowsOnPages(schema, dynamicHeights, startGlobalY, contentHeight, paddingTop, pages) {
461
- let currentRowIndex = 0;
486
+ function placeUnitsOnPages(schema, dynamicLayout, startGlobalY, contentHeight, paddingTop, pages) {
487
+ const dynamicHeights = dynamicLayout.heights;
488
+ let currentUnitIndex = 0;
462
489
  let currentPageIndex = Math.floor(startGlobalY / contentHeight);
463
490
  let currentYInPage = startGlobalY % contentHeight;
464
491
  if (currentYInPage < 0) currentYInPage = 0;
465
492
  let actualGlobalEndY = 0;
466
493
  const isSplittable = dynamicHeights.length > 1;
467
- while (currentRowIndex < dynamicHeights.length) {
494
+ while (currentUnitIndex < dynamicHeights.length) {
468
495
  while (pages.length <= currentPageIndex) pages.push([]);
469
496
  const spaceLeft = contentHeight - currentYInPage;
470
- if (dynamicHeights[currentRowIndex] > spaceLeft + EPSILON) {
497
+ if (dynamicHeights[currentUnitIndex] > spaceLeft + EPSILON) {
471
498
  if (!(Math.abs(spaceLeft - contentHeight) <= EPSILON)) {
472
499
  currentPageIndex++;
473
500
  currentYInPage = 0;
@@ -475,40 +502,41 @@ function placeRowsOnPages(schema, dynamicHeights, startGlobalY, contentHeight, p
475
502
  }
476
503
  }
477
504
  let chunkHeight = 0;
478
- const startRowIndex = currentRowIndex;
479
- while (currentRowIndex < dynamicHeights.length) {
480
- const h = dynamicHeights[currentRowIndex];
505
+ const startUnitIndex = currentUnitIndex;
506
+ while (currentUnitIndex < dynamicHeights.length) {
507
+ const h = dynamicHeights[currentUnitIndex];
481
508
  if (currentYInPage + chunkHeight + h <= contentHeight + EPSILON) {
482
509
  chunkHeight += h;
483
- currentRowIndex++;
510
+ currentUnitIndex++;
484
511
  } else break;
485
512
  }
486
513
  const isAtPageTop = currentYInPage <= EPSILON;
487
- if (isSplittable && startRowIndex === 0 && currentRowIndex === 1 && dynamicHeights.length > 1 && !isAtPageTop) {
488
- currentRowIndex = 0;
514
+ if (dynamicLayout.avoidFirstUnitOnly && isSplittable && startUnitIndex === 0 && currentUnitIndex === 1 && dynamicHeights.length > 1 && !isAtPageTop) {
515
+ currentUnitIndex = 0;
489
516
  currentPageIndex++;
490
517
  currentYInPage = 0;
491
518
  continue;
492
519
  }
493
- if (currentRowIndex === startRowIndex) {
494
- chunkHeight += dynamicHeights[currentRowIndex];
495
- currentRowIndex++;
520
+ if (currentUnitIndex === startUnitIndex) {
521
+ chunkHeight += dynamicHeights[currentUnitIndex];
522
+ currentUnitIndex++;
496
523
  }
524
+ const patch = dynamicLayout.patchSplitSchema?.({
525
+ schema,
526
+ start: startUnitIndex,
527
+ end: currentUnitIndex,
528
+ isSplit: startUnitIndex > 0,
529
+ chunkHeight
530
+ }) ?? {};
497
531
  const newSchema = {
498
532
  ...schema,
533
+ ...patch,
499
534
  height: chunkHeight,
500
535
  position: {
501
536
  ...schema.position,
502
537
  y: currentYInPage + paddingTop
503
538
  }
504
539
  };
505
- if (isSplittable) {
506
- newSchema.__bodyRange = {
507
- start: startRowIndex === 0 ? 0 : startRowIndex - 1,
508
- end: currentRowIndex - 1
509
- };
510
- newSchema.__isSplit = startRowIndex > 0;
511
- }
512
540
  pages[currentPageIndex].push(newSchema);
513
541
  currentYInPage += chunkHeight;
514
542
  if (currentYInPage >= contentHeight - EPSILON) {
@@ -539,12 +567,19 @@ function processDynamicPage(items, orderMap, contentHeight, paddingTop) {
539
567
  let totalYOffset = 0;
540
568
  for (const item of items) {
541
569
  const currentGlobalStartY = item.baseY + totalYOffset;
542
- totalYOffset = placeRowsOnPages(item.schema, item.dynamicHeights, currentGlobalStartY, contentHeight, paddingTop, pages) - (item.baseY + item.height);
570
+ totalYOffset = placeUnitsOnPages(item.schema, item.dynamicLayout, currentGlobalStartY, contentHeight, paddingTop, pages) - (item.baseY + item.height);
543
571
  }
544
572
  sortPagesByOrder(pages, orderMap);
545
573
  removeTrailingEmptyPages(pages);
546
574
  return pages;
547
575
  }
576
+ var normalizeDynamicLayoutResult = (result) => {
577
+ const dynamicLayout = Array.isArray(result) ? { heights: result } : result;
578
+ return {
579
+ ...dynamicLayout,
580
+ heights: dynamicLayout.heights.length === 0 ? [0] : dynamicLayout.heights
581
+ };
582
+ };
548
583
  /**
549
584
  * Process a template containing tables with dynamic heights
550
585
  * and generate a new template with proper page breaks.
@@ -576,9 +611,9 @@ var getDynamicTemplate = async (arg) => {
576
611
  basePdf,
577
612
  options,
578
613
  _cache
579
- }).then((heights) => heights.length === 0 ? [0] : heights);
614
+ }).then(normalizeDynamicLayoutResult);
580
615
  }));
581
- for (let j = 0; j < chunkResults.length; j++) items[i + j].dynamicHeights = chunkResults[j];
616
+ for (let j = 0; j < chunkResults.length; j++) items[i + j].dynamicLayout = chunkResults[j];
582
617
  }
583
618
  const processedPages = processDynamicPage(items, orderMap, contentHeight, paddingTop);
584
619
  resultPages.push(...processedPages);
@@ -607,11 +642,18 @@ var getDynamicTemplate = async (arg) => {
607
642
  //#endregion
608
643
  //#region src/expression.ts
609
644
  var expressionCache = /* @__PURE__ */ new Map();
610
- var parseDataCache = /* @__PURE__ */ new Map();
645
+ /**
646
+ * Parse each string value in `data` as JSON, falling back to the original
647
+ * string on failure. Previously memoized via a module-level `parseDataCache`
648
+ * Map keyed by `JSON.stringify(data)`, but that was a severe memory leak:
649
+ * - Cache was never evicted.
650
+ * - Key was a multi-MB string whenever `data` included schema.content with
651
+ * base64 (e.g. image schemas) or inputs containing base64 values. Every
652
+ * unique inputs state pinned its own multi-MB key for the app lifetime.
653
+ * Parsing is O(fields) and cheap; removing the cache is strictly a win.
654
+ */
611
655
  var parseData = (data) => {
612
- const key = JSON.stringify(data);
613
- if (parseDataCache.has(key)) return parseDataCache.get(key);
614
- const parsed = Object.fromEntries(Object.entries(data).map(([key, value]) => {
656
+ return Object.fromEntries(Object.entries(data).map(([key, value]) => {
615
657
  if (typeof value === "string") try {
616
658
  return [key, JSON.parse(value)];
617
659
  } catch {
@@ -619,8 +661,6 @@ var parseData = (data) => {
619
661
  }
620
662
  return [key, value];
621
663
  }));
622
- parseDataCache.set(key, parsed);
623
- return parsed;
624
664
  };
625
665
  var padZero = (num) => String(num).padStart(2, "0");
626
666
  var formatDate = (date) => `${date.getFullYear()}/${padZero(date.getMonth() + 1)}/${padZero(date.getDate())}`;