@pixldocs/canvas-renderer 0.5.218 → 0.5.220
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/{index-D3NJNdX_.cjs → index-DRHaeOxK.cjs} +103 -16
- package/dist/{index-D3NJNdX_.cjs.map → index-DRHaeOxK.cjs.map} +1 -1
- package/dist/{index-CZk_GpIL.js → index-KtRZhEPi.js} +103 -16
- package/dist/{index-CZk_GpIL.js.map → index-KtRZhEPi.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +76 -0
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-som_tmDY.js → vectorPdfExport-D5bhT-57.js} +4 -4
- package/dist/{vectorPdfExport-som_tmDY.js.map → vectorPdfExport-D5bhT-57.js.map} +1 -1
- package/dist/{vectorPdfExport-CoZ-RUqL.cjs → vectorPdfExport-UBFTDrVt.cjs} +4 -4
- package/dist/{vectorPdfExport-CoZ-RUqL.cjs.map → vectorPdfExport-UBFTDrVt.cjs.map} +1 -1
- package/package.json +1 -1
|
@@ -13626,7 +13626,9 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13626
13626
|
function convert(defs, parentId) {
|
|
13627
13627
|
var _a, _b;
|
|
13628
13628
|
for (const def of defs) {
|
|
13629
|
-
|
|
13629
|
+
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
13630
|
+
const defFields = def.fields ?? def.entryFields ?? [];
|
|
13631
|
+
if (isRepeatable) {
|
|
13630
13632
|
const rawPrefix = def.templateKeyPrefix || def.label.toLowerCase().replace(/\s+/g, "_");
|
|
13631
13633
|
const labelPrefix = rawPrefix.startsWith("field_") ? rawPrefix : `field_${rawPrefix}`;
|
|
13632
13634
|
const treeNodeId = repeatableNodeMap == null ? void 0 : repeatableNodeMap.get(def.label.trim().toLowerCase());
|
|
@@ -13640,7 +13642,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13640
13642
|
templateKeyPrefix: prefix,
|
|
13641
13643
|
minEntries,
|
|
13642
13644
|
maxEntries: def.maxEntries,
|
|
13643
|
-
entryFields:
|
|
13645
|
+
entryFields: defFields.map((f, i) => ({
|
|
13644
13646
|
key: f.key,
|
|
13645
13647
|
label: f.label,
|
|
13646
13648
|
type: mapFormDefFieldType(f.type),
|
|
@@ -13665,7 +13667,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13665
13667
|
label: def.label,
|
|
13666
13668
|
order: def.order ?? 0,
|
|
13667
13669
|
type: "single",
|
|
13668
|
-
fields:
|
|
13670
|
+
fields: defFields.map((f, i) => ({
|
|
13669
13671
|
key: f.key,
|
|
13670
13672
|
label: f.label,
|
|
13671
13673
|
type: mapFormDefFieldType(f.type),
|
|
@@ -17276,7 +17278,7 @@ function repeatablePageToSection(page) {
|
|
|
17276
17278
|
label: page.label,
|
|
17277
17279
|
description: page.description,
|
|
17278
17280
|
order: typeof page.order === "number" ? page.order + 1e4 : 1e4,
|
|
17279
|
-
fields: page.fields,
|
|
17281
|
+
fields: page.fields ?? page.entryFields ?? [],
|
|
17280
17282
|
repeatable: true,
|
|
17281
17283
|
minEntries: page.minEntries,
|
|
17282
17284
|
maxEntries: page.maxEntries,
|
|
@@ -17348,7 +17350,14 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17348
17350
|
const minEntries = page.minEntries != null ? Math.max(0, page.minEntries) : 1;
|
|
17349
17351
|
let entryCount;
|
|
17350
17352
|
if (Array.isArray(entries)) {
|
|
17351
|
-
|
|
17353
|
+
const realEntries = entries.filter((entry) => {
|
|
17354
|
+
if (!isRecord(entry)) return false;
|
|
17355
|
+
return Object.keys(entry).some(
|
|
17356
|
+
(k) => k !== ENTRY_ID_KEY && k !== ENTRY_NAME_KEY
|
|
17357
|
+
);
|
|
17358
|
+
});
|
|
17359
|
+
const count = minEntries === 0 ? realEntries.length : Math.max(1, realEntries.length);
|
|
17360
|
+
entryCount = count;
|
|
17352
17361
|
} else {
|
|
17353
17362
|
entryCount = minEntries === 0 ? 0 : minEntries;
|
|
17354
17363
|
}
|
|
@@ -17359,6 +17368,25 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17359
17368
|
};
|
|
17360
17369
|
});
|
|
17361
17370
|
}
|
|
17371
|
+
function sanitizeSectionStateAgainstSchema(state, schema) {
|
|
17372
|
+
if (!state) return {};
|
|
17373
|
+
if (!schema) return { ...state };
|
|
17374
|
+
const known = /* @__PURE__ */ new Set();
|
|
17375
|
+
for (const s of schema.sections ?? []) known.add(s.id);
|
|
17376
|
+
for (const p of schema.repeatablePages ?? []) known.add(p.id);
|
|
17377
|
+
const out = {};
|
|
17378
|
+
for (const [key, value] of Object.entries(state)) {
|
|
17379
|
+
if (known.has(key)) {
|
|
17380
|
+
out[key] = value;
|
|
17381
|
+
continue;
|
|
17382
|
+
}
|
|
17383
|
+
const compositeMatch = /^(.+?)_(\d+)_(.+)$/.exec(key);
|
|
17384
|
+
if (compositeMatch && known.has(compositeMatch[1]) && known.has(compositeMatch[3])) {
|
|
17385
|
+
out[key] = value;
|
|
17386
|
+
}
|
|
17387
|
+
}
|
|
17388
|
+
return out;
|
|
17389
|
+
}
|
|
17362
17390
|
async function fetchRow(supabaseUrl, anonKey, table, id) {
|
|
17363
17391
|
const url = `${supabaseUrl}/rest/v1/${table}?id=eq.${id}&select=*`;
|
|
17364
17392
|
const res = await fetch(url, {
|
|
@@ -17591,7 +17619,8 @@ async function resolveFromForm(options) {
|
|
|
17591
17619
|
let mergedSectionState = { ...sectionState };
|
|
17592
17620
|
const templateDefaultData = templateRow.default_data;
|
|
17593
17621
|
if (templateDefaultData && isDefaultDataV2(templateDefaultData)) {
|
|
17594
|
-
const
|
|
17622
|
+
const rawDefaults = templateDefaultData.sectionState;
|
|
17623
|
+
const defaults = sanitizeSectionStateAgainstSchema(rawDefaults, formSchema);
|
|
17595
17624
|
for (const key of Object.keys(defaults)) {
|
|
17596
17625
|
if (!(key in mergedSectionState)) {
|
|
17597
17626
|
mergedSectionState[key] = defaults[key];
|
|
@@ -17600,6 +17629,7 @@ async function resolveFromForm(options) {
|
|
|
17600
17629
|
}
|
|
17601
17630
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, templateDefaultMetaSectionState, inferredSections);
|
|
17602
17631
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, defaultFormMetaSectionState, inferredSections);
|
|
17632
|
+
mergedSectionState = sanitizeSectionStateAgainstSchema(mergedSectionState, formSchema);
|
|
17603
17633
|
const flatFormData = flattenSectionStateToFormData(mergedSectionState, inferredSections);
|
|
17604
17634
|
const dynamicFields = templateConfig.dynamicFields || [];
|
|
17605
17635
|
const mappings = [];
|
|
@@ -17618,7 +17648,8 @@ async function resolveFromForm(options) {
|
|
|
17618
17648
|
(repeatableFromSchema ?? []).map((r) => [baseId(r.nodeId), r])
|
|
17619
17649
|
);
|
|
17620
17650
|
const topLevelRepeatables = inferredSections.filter((s) => s.type === "repeatable" && !s.parentId).map((s) => {
|
|
17621
|
-
const
|
|
17651
|
+
const rawEntries = mergedSectionState[s.id];
|
|
17652
|
+
const entries = Array.isArray(rawEntries) ? rawEntries : [];
|
|
17622
17653
|
const nodeId = s.treeNodeId ?? s.id;
|
|
17623
17654
|
const schemaRepeatable = repeatableFromSchemaByBase.get(baseId(nodeId));
|
|
17624
17655
|
const entryMeta = entries.map((e) => getRepeatableEntryMeta(e, s));
|
|
@@ -17630,11 +17661,13 @@ async function resolveFromForm(options) {
|
|
|
17630
17661
|
const parentId = s.parentId;
|
|
17631
17662
|
const parentSection = inferredSections.find((ps) => ps.id === parentId);
|
|
17632
17663
|
const parentNodeId = parentSection ? parentSection.treeNodeId ?? parentSection.id : parentId;
|
|
17633
|
-
const
|
|
17664
|
+
const rawParentEntries = mergedSectionState[parentId];
|
|
17665
|
+
const parentEntries = Array.isArray(rawParentEntries) ? rawParentEntries : [];
|
|
17634
17666
|
const nestedEntryMeta = {};
|
|
17635
17667
|
const merged = [];
|
|
17636
17668
|
for (let pi = 0; pi < parentEntries.length; pi++) {
|
|
17637
|
-
const
|
|
17669
|
+
const rawChildEntries = mergedSectionState[`${parentId}_${pi}_${s.id}`];
|
|
17670
|
+
const childEntries = Array.isArray(rawChildEntries) ? rawChildEntries : [];
|
|
17638
17671
|
const meta = childEntries.map((e) => getRepeatableEntryMeta(e, s));
|
|
17639
17672
|
nestedEntryMeta[`${baseId(parentNodeId)}_${pi + 1}_${baseId(nodeId)}`] = meta;
|
|
17640
17673
|
merged.push(...meta);
|
|
@@ -17674,13 +17707,15 @@ async function resolveFromForm(options) {
|
|
|
17674
17707
|
if (s.type !== "repeatable") continue;
|
|
17675
17708
|
const parentId = s.parentId;
|
|
17676
17709
|
if (parentId == null) continue;
|
|
17677
|
-
const
|
|
17710
|
+
const rawParentEntries2 = mergedSectionState[parentId];
|
|
17711
|
+
const parentEntries = Array.isArray(rawParentEntries2) ? rawParentEntries2 : [];
|
|
17678
17712
|
const parentSection = inferredSections.find((ps) => ps.id === parentId);
|
|
17679
17713
|
const parentTreeNodeId = parentSection ? parentSection.treeNodeId ?? parentSection.id : parentId;
|
|
17680
17714
|
const childTreeNodeId = s.treeNodeId ?? s.id;
|
|
17681
17715
|
for (let pi = 0; pi < parentEntries.length; pi++) {
|
|
17682
17716
|
const compositeKey = `${parentId}_${pi}_${s.id}`;
|
|
17683
|
-
const
|
|
17717
|
+
const rawEntries2 = mergedSectionState[compositeKey];
|
|
17718
|
+
const entries = Array.isArray(rawEntries2) ? rawEntries2 : [];
|
|
17684
17719
|
const nestedKey = `${baseId(parentTreeNodeId)}_${pi + 1}_${baseId(childTreeNodeId)}`;
|
|
17685
17720
|
repeatableNestedEntryCounts[nestedKey] = Math.max(1, entries.length);
|
|
17686
17721
|
}
|
|
@@ -19039,9 +19074,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19039
19074
|
}
|
|
19040
19075
|
return svgString;
|
|
19041
19076
|
}
|
|
19042
|
-
const resolvedPackageVersion = "0.5.
|
|
19077
|
+
const resolvedPackageVersion = "0.5.220";
|
|
19043
19078
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19044
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
19079
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.220";
|
|
19045
19080
|
const roundParityValue = (value) => {
|
|
19046
19081
|
if (typeof value !== "number") return value;
|
|
19047
19082
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -19602,6 +19637,58 @@ class PixldocsRenderer {
|
|
|
19602
19637
|
compressionQuality
|
|
19603
19638
|
});
|
|
19604
19639
|
}
|
|
19640
|
+
/**
|
|
19641
|
+
* Render the template AND deliver the resulting PDF to the user — currently
|
|
19642
|
+
* via email (SendGrid). The PDF is rendered server-side on EC2, uploaded to
|
|
19643
|
+
* S3 (returned as `pdfUrl` for download fallback), and emailed with the PDF
|
|
19644
|
+
* attached.
|
|
19645
|
+
*
|
|
19646
|
+
* Every delivery is logged in the `delivery_log` table for audit + admin
|
|
19647
|
+
* resend. The same `pdfUrl` is returned to the caller so the host app can
|
|
19648
|
+
* also offer a "Download" button on the success screen.
|
|
19649
|
+
*
|
|
19650
|
+
* ```ts
|
|
19651
|
+
* const result = await renderer.renderAndDeliver({
|
|
19652
|
+
* templateId, formSchemaId, sectionState,
|
|
19653
|
+
* project: 'biomaker',
|
|
19654
|
+
* recipient: { email: 'user@example.com', name: 'Anya' },
|
|
19655
|
+
* });
|
|
19656
|
+
* // → { jobId, pdfUrl, deliveries: [{ channel: 'email', status: 'sent' }] }
|
|
19657
|
+
* ```
|
|
19658
|
+
*
|
|
19659
|
+
* Requires `RendererConfig.deliveryServerUrl` to be set.
|
|
19660
|
+
*/
|
|
19661
|
+
async renderAndDeliver(options) {
|
|
19662
|
+
var _a;
|
|
19663
|
+
const base = (_a = this.config.deliveryServerUrl) == null ? void 0 : _a.replace(/\/+$/, "");
|
|
19664
|
+
if (!base) {
|
|
19665
|
+
throw new Error("renderAndDeliver: RendererConfig.deliveryServerUrl is required");
|
|
19666
|
+
}
|
|
19667
|
+
const { templateId, formSchemaId, sectionState, themeId, watermark, project, recipient, channels, scale } = options;
|
|
19668
|
+
if (!project) throw new Error('renderAndDeliver: project is required (e.g. "biomaker", "pixldocs")');
|
|
19669
|
+
if (!(recipient == null ? void 0 : recipient.email)) throw new Error("renderAndDeliver: recipient.email is required");
|
|
19670
|
+
const body = {
|
|
19671
|
+
template_id: templateId,
|
|
19672
|
+
form_schema_id: formSchemaId,
|
|
19673
|
+
data: { version: 2, sectionState },
|
|
19674
|
+
project,
|
|
19675
|
+
recipient,
|
|
19676
|
+
channels: channels || ["email"]
|
|
19677
|
+
};
|
|
19678
|
+
if (themeId) body.theme = themeId;
|
|
19679
|
+
if (typeof watermark === "boolean") body.watermark = watermark;
|
|
19680
|
+
if (typeof scale === "number") body.scale = scale;
|
|
19681
|
+
const res = await fetch(`${base}/v1/render-and-deliver`, {
|
|
19682
|
+
method: "POST",
|
|
19683
|
+
headers: { "Content-Type": "application/json" },
|
|
19684
|
+
body: JSON.stringify(body)
|
|
19685
|
+
});
|
|
19686
|
+
if (!res.ok) {
|
|
19687
|
+
const errText = await res.text().catch(() => "");
|
|
19688
|
+
throw new Error(`renderAndDeliver failed: ${res.status} ${errText.slice(0, 300)}`);
|
|
19689
|
+
}
|
|
19690
|
+
return await res.json();
|
|
19691
|
+
}
|
|
19605
19692
|
async renderById(templateId, formData, options) {
|
|
19606
19693
|
const resolved = await resolveTemplateData({
|
|
19607
19694
|
templateId,
|
|
@@ -19733,7 +19820,7 @@ class PixldocsRenderer {
|
|
|
19733
19820
|
await this.waitForCanvasScene(container, cloned, i);
|
|
19734
19821
|
}
|
|
19735
19822
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
19736
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
19823
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D5bhT-57.js");
|
|
19737
19824
|
const prepared = preparePagesForExport(
|
|
19738
19825
|
cloned.pages,
|
|
19739
19826
|
canvasWidth,
|
|
@@ -21923,7 +22010,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
21923
22010
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
21924
22011
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
21925
22012
|
try {
|
|
21926
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
22013
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-D5bhT-57.js");
|
|
21927
22014
|
try {
|
|
21928
22015
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
21929
22016
|
} catch {
|
|
@@ -22323,4 +22410,4 @@ export {
|
|
|
22323
22410
|
buildTeaserBlurFlatKeys as y,
|
|
22324
22411
|
collectFontDescriptorsFromConfig as z
|
|
22325
22412
|
};
|
|
22326
|
-
//# sourceMappingURL=index-
|
|
22413
|
+
//# sourceMappingURL=index-KtRZhEPi.js.map
|