@pixldocs/canvas-renderer 0.5.217 → 0.5.219
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-CDrMSTDa.cjs → index-CBB2UdwF.cjs} +91 -57
- package/dist/index-CBB2UdwF.cjs.map +1 -0
- package/dist/{index-Ci5YA_Ps.js → index-DbUPI6zs.js} +91 -57
- package/dist/index-DbUPI6zs.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +76 -0
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-B8uqWQoW.cjs → vectorPdfExport-CwyiHDGD.cjs} +5 -5
- package/dist/vectorPdfExport-CwyiHDGD.cjs.map +1 -0
- package/dist/{vectorPdfExport-DJR9lwsV.js → vectorPdfExport-Dejgf_PM.js} +5 -5
- package/dist/vectorPdfExport-Dejgf_PM.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-CDrMSTDa.cjs.map +0 -1
- package/dist/index-Ci5YA_Ps.js.map +0 -1
- package/dist/vectorPdfExport-B8uqWQoW.cjs.map +0 -1
- package/dist/vectorPdfExport-DJR9lwsV.js.map +0 -1
|
@@ -6901,13 +6901,7 @@ function readShadowStrength(element) {
|
|
|
6901
6901
|
return typeof raw === "number" && Number.isFinite(raw) ? Math.max(0, Math.min(100, raw)) : 100;
|
|
6902
6902
|
}
|
|
6903
6903
|
function resolveShadowSourceSpread(element) {
|
|
6904
|
-
|
|
6905
|
-
const blur = Math.max(0, Number(element.textShadowBlur ?? 0) || 0);
|
|
6906
|
-
const fontSize = Math.max(1, Number(element.fontSize ?? 16) || 16);
|
|
6907
|
-
if (blur <= 2) return 0;
|
|
6908
|
-
const blurRamp = Math.min(1, (blur - 2) / 4);
|
|
6909
|
-
const t = Math.max(0, (strength - 35) / 65);
|
|
6910
|
-
return Math.min(8, blur * 0.16, fontSize * 0.08) * t * t * blurRamp;
|
|
6904
|
+
return 0;
|
|
6911
6905
|
}
|
|
6912
6906
|
function resolveShadowAlpha(element) {
|
|
6913
6907
|
const s = readShadowStrength(element);
|
|
@@ -6930,7 +6924,7 @@ function applyTextShadow(textbox, element) {
|
|
|
6930
6924
|
}
|
|
6931
6925
|
obj.__pdShadowAlpha = canonicalShadow ? resolveShadowAlpha(element) : 1;
|
|
6932
6926
|
obj.__pdShadowBaseColor = canonicalShadow ? String(element.textShadowColor || "") : void 0;
|
|
6933
|
-
obj.__pdShadowSourceSpread = canonicalShadow ? resolveShadowSourceSpread(
|
|
6927
|
+
obj.__pdShadowSourceSpread = canonicalShadow ? resolveShadowSourceSpread() : 0;
|
|
6934
6928
|
textbox.set("shadow", canonicalShadow ?? null);
|
|
6935
6929
|
}
|
|
6936
6930
|
function applyAlphaMultiplier(c, mult) {
|
|
@@ -7214,8 +7208,6 @@ function applyTextBackground(obj, cfg) {
|
|
|
7214
7208
|
}
|
|
7215
7209
|
}
|
|
7216
7210
|
const suppressShadowOnText = bg && bg.shadowAffectsText === false;
|
|
7217
|
-
const dropShadowSpread = Math.max(0, Number(this.__pdShadowSourceSpread) || 0);
|
|
7218
|
-
const dropShadowActive = dropShadowSpread > 0 && !!this.shadow && !suppressShadowOnText && !blockShadowActive && !lineShadowActive;
|
|
7219
7211
|
if (suppressShadowOnText) {
|
|
7220
7212
|
ctx.save();
|
|
7221
7213
|
ctx.shadowColor = "transparent";
|
|
@@ -7224,44 +7216,6 @@ function applyTextBackground(obj, cfg) {
|
|
|
7224
7216
|
ctx.shadowOffsetY = 0;
|
|
7225
7217
|
originalRender(ctx);
|
|
7226
7218
|
ctx.restore();
|
|
7227
|
-
} else if (dropShadowActive) {
|
|
7228
|
-
const self = this;
|
|
7229
|
-
const shadow = self.shadow;
|
|
7230
|
-
const shadowColor = String((shadow == null ? void 0 : shadow.color) || this.__pdShadowBaseColor || "rgba(0,0,0,1)");
|
|
7231
|
-
const shadowBlur = Math.max(0, Number((shadow == null ? void 0 : shadow.blur) ?? 0) || 0);
|
|
7232
|
-
const shadowOffsetX = Number((shadow == null ? void 0 : shadow.offsetX) ?? 0) || 0;
|
|
7233
|
-
const shadowOffsetY = Number((shadow == null ? void 0 : shadow.offsetY) ?? 0) || 0;
|
|
7234
|
-
const origFill = self.fill;
|
|
7235
|
-
const origStroke = self.stroke;
|
|
7236
|
-
const origStrokeWidth = self.strokeWidth;
|
|
7237
|
-
const origStyles = self.styles;
|
|
7238
|
-
const origShadow = self.shadow;
|
|
7239
|
-
try {
|
|
7240
|
-
ctx.save();
|
|
7241
|
-
self.shadow = null;
|
|
7242
|
-
self.fill = shadowColor;
|
|
7243
|
-
self.styles = {};
|
|
7244
|
-
self.stroke = shadowColor;
|
|
7245
|
-
self.strokeWidth = dropShadowSpread;
|
|
7246
|
-
ctx.translate(shadowOffsetX, shadowOffsetY);
|
|
7247
|
-
if (shadowBlur > 0) ctx.filter = `blur(${shadowBlur / 2}px)`;
|
|
7248
|
-
ctx.lineJoin = "round";
|
|
7249
|
-
ctx.lineCap = "round";
|
|
7250
|
-
originalRender(ctx);
|
|
7251
|
-
ctx.restore();
|
|
7252
|
-
self.fill = origFill;
|
|
7253
|
-
self.stroke = origStroke;
|
|
7254
|
-
self.strokeWidth = origStrokeWidth;
|
|
7255
|
-
self.styles = origStyles;
|
|
7256
|
-
self.shadow = null;
|
|
7257
|
-
originalRender(ctx);
|
|
7258
|
-
} finally {
|
|
7259
|
-
self.fill = origFill;
|
|
7260
|
-
self.stroke = origStroke;
|
|
7261
|
-
self.strokeWidth = origStrokeWidth;
|
|
7262
|
-
self.styles = origStyles;
|
|
7263
|
-
self.shadow = origShadow;
|
|
7264
|
-
}
|
|
7265
7219
|
} else {
|
|
7266
7220
|
originalRender(ctx);
|
|
7267
7221
|
}
|
|
@@ -7343,7 +7297,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7343
7297
|
const oy = Number(shadow.offsetY ?? 0) || 0;
|
|
7344
7298
|
const blur = Math.max(0, Number(shadow.blur ?? 0));
|
|
7345
7299
|
const shadowColor = String(shadow.color);
|
|
7346
|
-
const sourceSpread =
|
|
7300
|
+
const sourceSpread = 0;
|
|
7347
7301
|
const pad = Math.max(16, Math.ceil((blur + sourceSpread) * 4) + Math.ceil(Math.max(Math.abs(ox), Math.abs(oy))) + 8);
|
|
7348
7302
|
const shadowBounds = unionBounds([
|
|
7349
7303
|
...rects,
|
|
@@ -17394,7 +17348,14 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17394
17348
|
const minEntries = page.minEntries != null ? Math.max(0, page.minEntries) : 1;
|
|
17395
17349
|
let entryCount;
|
|
17396
17350
|
if (Array.isArray(entries)) {
|
|
17397
|
-
|
|
17351
|
+
const realEntries = entries.filter((entry) => {
|
|
17352
|
+
if (!isRecord(entry)) return false;
|
|
17353
|
+
return Object.keys(entry).some(
|
|
17354
|
+
(k) => k !== ENTRY_ID_KEY && k !== ENTRY_NAME_KEY
|
|
17355
|
+
);
|
|
17356
|
+
});
|
|
17357
|
+
const count = minEntries === 0 ? realEntries.length : Math.max(1, realEntries.length);
|
|
17358
|
+
entryCount = count;
|
|
17398
17359
|
} else {
|
|
17399
17360
|
entryCount = minEntries === 0 ? 0 : minEntries;
|
|
17400
17361
|
}
|
|
@@ -17405,6 +17366,25 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17405
17366
|
};
|
|
17406
17367
|
});
|
|
17407
17368
|
}
|
|
17369
|
+
function sanitizeSectionStateAgainstSchema(state, schema) {
|
|
17370
|
+
if (!state) return {};
|
|
17371
|
+
if (!schema) return { ...state };
|
|
17372
|
+
const known = /* @__PURE__ */ new Set();
|
|
17373
|
+
for (const s of schema.sections ?? []) known.add(s.id);
|
|
17374
|
+
for (const p of schema.repeatablePages ?? []) known.add(p.id);
|
|
17375
|
+
const out = {};
|
|
17376
|
+
for (const [key, value] of Object.entries(state)) {
|
|
17377
|
+
if (known.has(key)) {
|
|
17378
|
+
out[key] = value;
|
|
17379
|
+
continue;
|
|
17380
|
+
}
|
|
17381
|
+
const compositeMatch = /^(.+?)_(\d+)_(.+)$/.exec(key);
|
|
17382
|
+
if (compositeMatch && known.has(compositeMatch[1]) && known.has(compositeMatch[3])) {
|
|
17383
|
+
out[key] = value;
|
|
17384
|
+
}
|
|
17385
|
+
}
|
|
17386
|
+
return out;
|
|
17387
|
+
}
|
|
17408
17388
|
async function fetchRow(supabaseUrl, anonKey, table, id) {
|
|
17409
17389
|
const url = `${supabaseUrl}/rest/v1/${table}?id=eq.${id}&select=*`;
|
|
17410
17390
|
const res = await fetch(url, {
|
|
@@ -17637,7 +17617,8 @@ async function resolveFromForm(options) {
|
|
|
17637
17617
|
let mergedSectionState = { ...sectionState };
|
|
17638
17618
|
const templateDefaultData = templateRow.default_data;
|
|
17639
17619
|
if (templateDefaultData && isDefaultDataV2(templateDefaultData)) {
|
|
17640
|
-
const
|
|
17620
|
+
const rawDefaults = templateDefaultData.sectionState;
|
|
17621
|
+
const defaults = sanitizeSectionStateAgainstSchema(rawDefaults, formSchema);
|
|
17641
17622
|
for (const key of Object.keys(defaults)) {
|
|
17642
17623
|
if (!(key in mergedSectionState)) {
|
|
17643
17624
|
mergedSectionState[key] = defaults[key];
|
|
@@ -17646,6 +17627,7 @@ async function resolveFromForm(options) {
|
|
|
17646
17627
|
}
|
|
17647
17628
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, templateDefaultMetaSectionState, inferredSections);
|
|
17648
17629
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, defaultFormMetaSectionState, inferredSections);
|
|
17630
|
+
mergedSectionState = sanitizeSectionStateAgainstSchema(mergedSectionState, formSchema);
|
|
17649
17631
|
const flatFormData = flattenSectionStateToFormData(mergedSectionState, inferredSections);
|
|
17650
17632
|
const dynamicFields = templateConfig.dynamicFields || [];
|
|
17651
17633
|
const mappings = [];
|
|
@@ -19085,9 +19067,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19085
19067
|
}
|
|
19086
19068
|
return svgString;
|
|
19087
19069
|
}
|
|
19088
|
-
const resolvedPackageVersion = "0.5.
|
|
19070
|
+
const resolvedPackageVersion = "0.5.219";
|
|
19089
19071
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19090
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
19072
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.219";
|
|
19091
19073
|
const roundParityValue = (value) => {
|
|
19092
19074
|
if (typeof value !== "number") return value;
|
|
19093
19075
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -19648,6 +19630,58 @@ class PixldocsRenderer {
|
|
|
19648
19630
|
compressionQuality
|
|
19649
19631
|
});
|
|
19650
19632
|
}
|
|
19633
|
+
/**
|
|
19634
|
+
* Render the template AND deliver the resulting PDF to the user — currently
|
|
19635
|
+
* via email (SendGrid). The PDF is rendered server-side on EC2, uploaded to
|
|
19636
|
+
* S3 (returned as `pdfUrl` for download fallback), and emailed with the PDF
|
|
19637
|
+
* attached.
|
|
19638
|
+
*
|
|
19639
|
+
* Every delivery is logged in the `delivery_log` table for audit + admin
|
|
19640
|
+
* resend. The same `pdfUrl` is returned to the caller so the host app can
|
|
19641
|
+
* also offer a "Download" button on the success screen.
|
|
19642
|
+
*
|
|
19643
|
+
* ```ts
|
|
19644
|
+
* const result = await renderer.renderAndDeliver({
|
|
19645
|
+
* templateId, formSchemaId, sectionState,
|
|
19646
|
+
* project: 'biomaker',
|
|
19647
|
+
* recipient: { email: 'user@example.com', name: 'Anya' },
|
|
19648
|
+
* });
|
|
19649
|
+
* // → { jobId, pdfUrl, deliveries: [{ channel: 'email', status: 'sent' }] }
|
|
19650
|
+
* ```
|
|
19651
|
+
*
|
|
19652
|
+
* Requires `RendererConfig.deliveryServerUrl` to be set.
|
|
19653
|
+
*/
|
|
19654
|
+
async renderAndDeliver(options) {
|
|
19655
|
+
var _a;
|
|
19656
|
+
const base = (_a = this.config.deliveryServerUrl) == null ? void 0 : _a.replace(/\/+$/, "");
|
|
19657
|
+
if (!base) {
|
|
19658
|
+
throw new Error("renderAndDeliver: RendererConfig.deliveryServerUrl is required");
|
|
19659
|
+
}
|
|
19660
|
+
const { templateId, formSchemaId, sectionState, themeId, watermark, project, recipient, channels, scale } = options;
|
|
19661
|
+
if (!project) throw new Error('renderAndDeliver: project is required (e.g. "biomaker", "pixldocs")');
|
|
19662
|
+
if (!(recipient == null ? void 0 : recipient.email)) throw new Error("renderAndDeliver: recipient.email is required");
|
|
19663
|
+
const body = {
|
|
19664
|
+
template_id: templateId,
|
|
19665
|
+
form_schema_id: formSchemaId,
|
|
19666
|
+
data: { version: 2, sectionState },
|
|
19667
|
+
project,
|
|
19668
|
+
recipient,
|
|
19669
|
+
channels: channels || ["email"]
|
|
19670
|
+
};
|
|
19671
|
+
if (themeId) body.theme = themeId;
|
|
19672
|
+
if (typeof watermark === "boolean") body.watermark = watermark;
|
|
19673
|
+
if (typeof scale === "number") body.scale = scale;
|
|
19674
|
+
const res = await fetch(`${base}/v1/render-and-deliver`, {
|
|
19675
|
+
method: "POST",
|
|
19676
|
+
headers: { "Content-Type": "application/json" },
|
|
19677
|
+
body: JSON.stringify(body)
|
|
19678
|
+
});
|
|
19679
|
+
if (!res.ok) {
|
|
19680
|
+
const errText = await res.text().catch(() => "");
|
|
19681
|
+
throw new Error(`renderAndDeliver failed: ${res.status} ${errText.slice(0, 300)}`);
|
|
19682
|
+
}
|
|
19683
|
+
return await res.json();
|
|
19684
|
+
}
|
|
19651
19685
|
async renderById(templateId, formData, options) {
|
|
19652
19686
|
const resolved = await resolveTemplateData({
|
|
19653
19687
|
templateId,
|
|
@@ -19779,7 +19813,7 @@ class PixldocsRenderer {
|
|
|
19779
19813
|
await this.waitForCanvasScene(container, cloned, i);
|
|
19780
19814
|
}
|
|
19781
19815
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
19782
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
19816
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Dejgf_PM.js");
|
|
19783
19817
|
const prepared = preparePagesForExport(
|
|
19784
19818
|
cloned.pages,
|
|
19785
19819
|
canvasWidth,
|
|
@@ -21721,7 +21755,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
21721
21755
|
const by = parseFloat(marker.getAttribute("data-by") || "0");
|
|
21722
21756
|
const bw = parseFloat(marker.getAttribute("data-bw") || "0");
|
|
21723
21757
|
const bh = parseFloat(marker.getAttribute("data-bh") || "0");
|
|
21724
|
-
const spread =
|
|
21758
|
+
const spread = 0;
|
|
21725
21759
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
21726
21760
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
21727
21761
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
@@ -21969,7 +22003,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
21969
22003
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
21970
22004
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
21971
22005
|
try {
|
|
21972
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
22006
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Dejgf_PM.js");
|
|
21973
22007
|
try {
|
|
21974
22008
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
21975
22009
|
} catch {
|
|
@@ -22369,4 +22403,4 @@ export {
|
|
|
22369
22403
|
buildTeaserBlurFlatKeys as y,
|
|
22370
22404
|
collectFontDescriptorsFromConfig as z
|
|
22371
22405
|
};
|
|
22372
|
-
//# sourceMappingURL=index-
|
|
22406
|
+
//# sourceMappingURL=index-DbUPI6zs.js.map
|