@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
|
@@ -13644,7 +13644,9 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13644
13644
|
function convert(defs, parentId) {
|
|
13645
13645
|
var _a, _b;
|
|
13646
13646
|
for (const def of defs) {
|
|
13647
|
-
|
|
13647
|
+
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
13648
|
+
const defFields = def.fields ?? def.entryFields ?? [];
|
|
13649
|
+
if (isRepeatable) {
|
|
13648
13650
|
const rawPrefix = def.templateKeyPrefix || def.label.toLowerCase().replace(/\s+/g, "_");
|
|
13649
13651
|
const labelPrefix = rawPrefix.startsWith("field_") ? rawPrefix : `field_${rawPrefix}`;
|
|
13650
13652
|
const treeNodeId = repeatableNodeMap == null ? void 0 : repeatableNodeMap.get(def.label.trim().toLowerCase());
|
|
@@ -13658,7 +13660,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13658
13660
|
templateKeyPrefix: prefix,
|
|
13659
13661
|
minEntries,
|
|
13660
13662
|
maxEntries: def.maxEntries,
|
|
13661
|
-
entryFields:
|
|
13663
|
+
entryFields: defFields.map((f, i) => ({
|
|
13662
13664
|
key: f.key,
|
|
13663
13665
|
label: f.label,
|
|
13664
13666
|
type: mapFormDefFieldType(f.type),
|
|
@@ -13683,7 +13685,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
13683
13685
|
label: def.label,
|
|
13684
13686
|
order: def.order ?? 0,
|
|
13685
13687
|
type: "single",
|
|
13686
|
-
fields:
|
|
13688
|
+
fields: defFields.map((f, i) => ({
|
|
13687
13689
|
key: f.key,
|
|
13688
13690
|
label: f.label,
|
|
13689
13691
|
type: mapFormDefFieldType(f.type),
|
|
@@ -17294,7 +17296,7 @@ function repeatablePageToSection(page) {
|
|
|
17294
17296
|
label: page.label,
|
|
17295
17297
|
description: page.description,
|
|
17296
17298
|
order: typeof page.order === "number" ? page.order + 1e4 : 1e4,
|
|
17297
|
-
fields: page.fields,
|
|
17299
|
+
fields: page.fields ?? page.entryFields ?? [],
|
|
17298
17300
|
repeatable: true,
|
|
17299
17301
|
minEntries: page.minEntries,
|
|
17300
17302
|
maxEntries: page.maxEntries,
|
|
@@ -17366,7 +17368,14 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17366
17368
|
const minEntries = page.minEntries != null ? Math.max(0, page.minEntries) : 1;
|
|
17367
17369
|
let entryCount;
|
|
17368
17370
|
if (Array.isArray(entries)) {
|
|
17369
|
-
|
|
17371
|
+
const realEntries = entries.filter((entry) => {
|
|
17372
|
+
if (!isRecord(entry)) return false;
|
|
17373
|
+
return Object.keys(entry).some(
|
|
17374
|
+
(k) => k !== ENTRY_ID_KEY && k !== ENTRY_NAME_KEY
|
|
17375
|
+
);
|
|
17376
|
+
});
|
|
17377
|
+
const count = minEntries === 0 ? realEntries.length : Math.max(1, realEntries.length);
|
|
17378
|
+
entryCount = count;
|
|
17370
17379
|
} else {
|
|
17371
17380
|
entryCount = minEntries === 0 ? 0 : minEntries;
|
|
17372
17381
|
}
|
|
@@ -17377,6 +17386,25 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17377
17386
|
};
|
|
17378
17387
|
});
|
|
17379
17388
|
}
|
|
17389
|
+
function sanitizeSectionStateAgainstSchema(state, schema) {
|
|
17390
|
+
if (!state) return {};
|
|
17391
|
+
if (!schema) return { ...state };
|
|
17392
|
+
const known = /* @__PURE__ */ new Set();
|
|
17393
|
+
for (const s of schema.sections ?? []) known.add(s.id);
|
|
17394
|
+
for (const p of schema.repeatablePages ?? []) known.add(p.id);
|
|
17395
|
+
const out = {};
|
|
17396
|
+
for (const [key, value] of Object.entries(state)) {
|
|
17397
|
+
if (known.has(key)) {
|
|
17398
|
+
out[key] = value;
|
|
17399
|
+
continue;
|
|
17400
|
+
}
|
|
17401
|
+
const compositeMatch = /^(.+?)_(\d+)_(.+)$/.exec(key);
|
|
17402
|
+
if (compositeMatch && known.has(compositeMatch[1]) && known.has(compositeMatch[3])) {
|
|
17403
|
+
out[key] = value;
|
|
17404
|
+
}
|
|
17405
|
+
}
|
|
17406
|
+
return out;
|
|
17407
|
+
}
|
|
17380
17408
|
async function fetchRow(supabaseUrl, anonKey, table, id) {
|
|
17381
17409
|
const url = `${supabaseUrl}/rest/v1/${table}?id=eq.${id}&select=*`;
|
|
17382
17410
|
const res = await fetch(url, {
|
|
@@ -17609,7 +17637,8 @@ async function resolveFromForm(options) {
|
|
|
17609
17637
|
let mergedSectionState = { ...sectionState };
|
|
17610
17638
|
const templateDefaultData = templateRow.default_data;
|
|
17611
17639
|
if (templateDefaultData && isDefaultDataV2(templateDefaultData)) {
|
|
17612
|
-
const
|
|
17640
|
+
const rawDefaults = templateDefaultData.sectionState;
|
|
17641
|
+
const defaults = sanitizeSectionStateAgainstSchema(rawDefaults, formSchema);
|
|
17613
17642
|
for (const key of Object.keys(defaults)) {
|
|
17614
17643
|
if (!(key in mergedSectionState)) {
|
|
17615
17644
|
mergedSectionState[key] = defaults[key];
|
|
@@ -17618,6 +17647,7 @@ async function resolveFromForm(options) {
|
|
|
17618
17647
|
}
|
|
17619
17648
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, templateDefaultMetaSectionState, inferredSections);
|
|
17620
17649
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, defaultFormMetaSectionState, inferredSections);
|
|
17650
|
+
mergedSectionState = sanitizeSectionStateAgainstSchema(mergedSectionState, formSchema);
|
|
17621
17651
|
const flatFormData = flattenSectionStateToFormData(mergedSectionState, inferredSections);
|
|
17622
17652
|
const dynamicFields = templateConfig.dynamicFields || [];
|
|
17623
17653
|
const mappings = [];
|
|
@@ -17636,7 +17666,8 @@ async function resolveFromForm(options) {
|
|
|
17636
17666
|
(repeatableFromSchema ?? []).map((r) => [baseId(r.nodeId), r])
|
|
17637
17667
|
);
|
|
17638
17668
|
const topLevelRepeatables = inferredSections.filter((s) => s.type === "repeatable" && !s.parentId).map((s) => {
|
|
17639
|
-
const
|
|
17669
|
+
const rawEntries = mergedSectionState[s.id];
|
|
17670
|
+
const entries = Array.isArray(rawEntries) ? rawEntries : [];
|
|
17640
17671
|
const nodeId = s.treeNodeId ?? s.id;
|
|
17641
17672
|
const schemaRepeatable = repeatableFromSchemaByBase.get(baseId(nodeId));
|
|
17642
17673
|
const entryMeta = entries.map((e) => getRepeatableEntryMeta(e, s));
|
|
@@ -17648,11 +17679,13 @@ async function resolveFromForm(options) {
|
|
|
17648
17679
|
const parentId = s.parentId;
|
|
17649
17680
|
const parentSection = inferredSections.find((ps) => ps.id === parentId);
|
|
17650
17681
|
const parentNodeId = parentSection ? parentSection.treeNodeId ?? parentSection.id : parentId;
|
|
17651
|
-
const
|
|
17682
|
+
const rawParentEntries = mergedSectionState[parentId];
|
|
17683
|
+
const parentEntries = Array.isArray(rawParentEntries) ? rawParentEntries : [];
|
|
17652
17684
|
const nestedEntryMeta = {};
|
|
17653
17685
|
const merged = [];
|
|
17654
17686
|
for (let pi = 0; pi < parentEntries.length; pi++) {
|
|
17655
|
-
const
|
|
17687
|
+
const rawChildEntries = mergedSectionState[`${parentId}_${pi}_${s.id}`];
|
|
17688
|
+
const childEntries = Array.isArray(rawChildEntries) ? rawChildEntries : [];
|
|
17656
17689
|
const meta = childEntries.map((e) => getRepeatableEntryMeta(e, s));
|
|
17657
17690
|
nestedEntryMeta[`${baseId(parentNodeId)}_${pi + 1}_${baseId(nodeId)}`] = meta;
|
|
17658
17691
|
merged.push(...meta);
|
|
@@ -17692,13 +17725,15 @@ async function resolveFromForm(options) {
|
|
|
17692
17725
|
if (s.type !== "repeatable") continue;
|
|
17693
17726
|
const parentId = s.parentId;
|
|
17694
17727
|
if (parentId == null) continue;
|
|
17695
|
-
const
|
|
17728
|
+
const rawParentEntries2 = mergedSectionState[parentId];
|
|
17729
|
+
const parentEntries = Array.isArray(rawParentEntries2) ? rawParentEntries2 : [];
|
|
17696
17730
|
const parentSection = inferredSections.find((ps) => ps.id === parentId);
|
|
17697
17731
|
const parentTreeNodeId = parentSection ? parentSection.treeNodeId ?? parentSection.id : parentId;
|
|
17698
17732
|
const childTreeNodeId = s.treeNodeId ?? s.id;
|
|
17699
17733
|
for (let pi = 0; pi < parentEntries.length; pi++) {
|
|
17700
17734
|
const compositeKey = `${parentId}_${pi}_${s.id}`;
|
|
17701
|
-
const
|
|
17735
|
+
const rawEntries2 = mergedSectionState[compositeKey];
|
|
17736
|
+
const entries = Array.isArray(rawEntries2) ? rawEntries2 : [];
|
|
17702
17737
|
const nestedKey = `${baseId(parentTreeNodeId)}_${pi + 1}_${baseId(childTreeNodeId)}`;
|
|
17703
17738
|
repeatableNestedEntryCounts[nestedKey] = Math.max(1, entries.length);
|
|
17704
17739
|
}
|
|
@@ -19057,9 +19092,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19057
19092
|
}
|
|
19058
19093
|
return svgString;
|
|
19059
19094
|
}
|
|
19060
|
-
const resolvedPackageVersion = "0.5.
|
|
19095
|
+
const resolvedPackageVersion = "0.5.220";
|
|
19061
19096
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19062
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
19097
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.220";
|
|
19063
19098
|
const roundParityValue = (value) => {
|
|
19064
19099
|
if (typeof value !== "number") return value;
|
|
19065
19100
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -19620,6 +19655,58 @@ class PixldocsRenderer {
|
|
|
19620
19655
|
compressionQuality
|
|
19621
19656
|
});
|
|
19622
19657
|
}
|
|
19658
|
+
/**
|
|
19659
|
+
* Render the template AND deliver the resulting PDF to the user — currently
|
|
19660
|
+
* via email (SendGrid). The PDF is rendered server-side on EC2, uploaded to
|
|
19661
|
+
* S3 (returned as `pdfUrl` for download fallback), and emailed with the PDF
|
|
19662
|
+
* attached.
|
|
19663
|
+
*
|
|
19664
|
+
* Every delivery is logged in the `delivery_log` table for audit + admin
|
|
19665
|
+
* resend. The same `pdfUrl` is returned to the caller so the host app can
|
|
19666
|
+
* also offer a "Download" button on the success screen.
|
|
19667
|
+
*
|
|
19668
|
+
* ```ts
|
|
19669
|
+
* const result = await renderer.renderAndDeliver({
|
|
19670
|
+
* templateId, formSchemaId, sectionState,
|
|
19671
|
+
* project: 'biomaker',
|
|
19672
|
+
* recipient: { email: 'user@example.com', name: 'Anya' },
|
|
19673
|
+
* });
|
|
19674
|
+
* // → { jobId, pdfUrl, deliveries: [{ channel: 'email', status: 'sent' }] }
|
|
19675
|
+
* ```
|
|
19676
|
+
*
|
|
19677
|
+
* Requires `RendererConfig.deliveryServerUrl` to be set.
|
|
19678
|
+
*/
|
|
19679
|
+
async renderAndDeliver(options) {
|
|
19680
|
+
var _a;
|
|
19681
|
+
const base = (_a = this.config.deliveryServerUrl) == null ? void 0 : _a.replace(/\/+$/, "");
|
|
19682
|
+
if (!base) {
|
|
19683
|
+
throw new Error("renderAndDeliver: RendererConfig.deliveryServerUrl is required");
|
|
19684
|
+
}
|
|
19685
|
+
const { templateId, formSchemaId, sectionState, themeId, watermark, project, recipient, channels, scale } = options;
|
|
19686
|
+
if (!project) throw new Error('renderAndDeliver: project is required (e.g. "biomaker", "pixldocs")');
|
|
19687
|
+
if (!(recipient == null ? void 0 : recipient.email)) throw new Error("renderAndDeliver: recipient.email is required");
|
|
19688
|
+
const body = {
|
|
19689
|
+
template_id: templateId,
|
|
19690
|
+
form_schema_id: formSchemaId,
|
|
19691
|
+
data: { version: 2, sectionState },
|
|
19692
|
+
project,
|
|
19693
|
+
recipient,
|
|
19694
|
+
channels: channels || ["email"]
|
|
19695
|
+
};
|
|
19696
|
+
if (themeId) body.theme = themeId;
|
|
19697
|
+
if (typeof watermark === "boolean") body.watermark = watermark;
|
|
19698
|
+
if (typeof scale === "number") body.scale = scale;
|
|
19699
|
+
const res = await fetch(`${base}/v1/render-and-deliver`, {
|
|
19700
|
+
method: "POST",
|
|
19701
|
+
headers: { "Content-Type": "application/json" },
|
|
19702
|
+
body: JSON.stringify(body)
|
|
19703
|
+
});
|
|
19704
|
+
if (!res.ok) {
|
|
19705
|
+
const errText = await res.text().catch(() => "");
|
|
19706
|
+
throw new Error(`renderAndDeliver failed: ${res.status} ${errText.slice(0, 300)}`);
|
|
19707
|
+
}
|
|
19708
|
+
return await res.json();
|
|
19709
|
+
}
|
|
19623
19710
|
async renderById(templateId, formData, options) {
|
|
19624
19711
|
const resolved = await resolveTemplateData({
|
|
19625
19712
|
templateId,
|
|
@@ -19751,7 +19838,7 @@ class PixldocsRenderer {
|
|
|
19751
19838
|
await this.waitForCanvasScene(container, cloned, i);
|
|
19752
19839
|
}
|
|
19753
19840
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
19754
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
19841
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-UBFTDrVt.cjs"));
|
|
19755
19842
|
const prepared = preparePagesForExport(
|
|
19756
19843
|
cloned.pages,
|
|
19757
19844
|
canvasWidth,
|
|
@@ -21941,7 +22028,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
21941
22028
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
21942
22029
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
21943
22030
|
try {
|
|
21944
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
22031
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-UBFTDrVt.cjs"));
|
|
21945
22032
|
try {
|
|
21946
22033
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
21947
22034
|
} catch {
|
|
@@ -22338,4 +22425,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
22338
22425
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
22339
22426
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
22340
22427
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
22341
|
-
//# sourceMappingURL=index-
|
|
22428
|
+
//# sourceMappingURL=index-DRHaeOxK.cjs.map
|