@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
|
@@ -6919,13 +6919,7 @@ function readShadowStrength(element) {
|
|
|
6919
6919
|
return typeof raw === "number" && Number.isFinite(raw) ? Math.max(0, Math.min(100, raw)) : 100;
|
|
6920
6920
|
}
|
|
6921
6921
|
function resolveShadowSourceSpread(element) {
|
|
6922
|
-
|
|
6923
|
-
const blur = Math.max(0, Number(element.textShadowBlur ?? 0) || 0);
|
|
6924
|
-
const fontSize = Math.max(1, Number(element.fontSize ?? 16) || 16);
|
|
6925
|
-
if (blur <= 2) return 0;
|
|
6926
|
-
const blurRamp = Math.min(1, (blur - 2) / 4);
|
|
6927
|
-
const t = Math.max(0, (strength - 35) / 65);
|
|
6928
|
-
return Math.min(8, blur * 0.16, fontSize * 0.08) * t * t * blurRamp;
|
|
6922
|
+
return 0;
|
|
6929
6923
|
}
|
|
6930
6924
|
function resolveShadowAlpha(element) {
|
|
6931
6925
|
const s = readShadowStrength(element);
|
|
@@ -6948,7 +6942,7 @@ function applyTextShadow(textbox, element) {
|
|
|
6948
6942
|
}
|
|
6949
6943
|
obj.__pdShadowAlpha = canonicalShadow ? resolveShadowAlpha(element) : 1;
|
|
6950
6944
|
obj.__pdShadowBaseColor = canonicalShadow ? String(element.textShadowColor || "") : void 0;
|
|
6951
|
-
obj.__pdShadowSourceSpread = canonicalShadow ? resolveShadowSourceSpread(
|
|
6945
|
+
obj.__pdShadowSourceSpread = canonicalShadow ? resolveShadowSourceSpread() : 0;
|
|
6952
6946
|
textbox.set("shadow", canonicalShadow ?? null);
|
|
6953
6947
|
}
|
|
6954
6948
|
function applyAlphaMultiplier(c, mult) {
|
|
@@ -7232,8 +7226,6 @@ function applyTextBackground(obj, cfg) {
|
|
|
7232
7226
|
}
|
|
7233
7227
|
}
|
|
7234
7228
|
const suppressShadowOnText = bg && bg.shadowAffectsText === false;
|
|
7235
|
-
const dropShadowSpread = Math.max(0, Number(this.__pdShadowSourceSpread) || 0);
|
|
7236
|
-
const dropShadowActive = dropShadowSpread > 0 && !!this.shadow && !suppressShadowOnText && !blockShadowActive && !lineShadowActive;
|
|
7237
7229
|
if (suppressShadowOnText) {
|
|
7238
7230
|
ctx.save();
|
|
7239
7231
|
ctx.shadowColor = "transparent";
|
|
@@ -7242,44 +7234,6 @@ function applyTextBackground(obj, cfg) {
|
|
|
7242
7234
|
ctx.shadowOffsetY = 0;
|
|
7243
7235
|
originalRender(ctx);
|
|
7244
7236
|
ctx.restore();
|
|
7245
|
-
} else if (dropShadowActive) {
|
|
7246
|
-
const self = this;
|
|
7247
|
-
const shadow = self.shadow;
|
|
7248
|
-
const shadowColor = String((shadow == null ? void 0 : shadow.color) || this.__pdShadowBaseColor || "rgba(0,0,0,1)");
|
|
7249
|
-
const shadowBlur = Math.max(0, Number((shadow == null ? void 0 : shadow.blur) ?? 0) || 0);
|
|
7250
|
-
const shadowOffsetX = Number((shadow == null ? void 0 : shadow.offsetX) ?? 0) || 0;
|
|
7251
|
-
const shadowOffsetY = Number((shadow == null ? void 0 : shadow.offsetY) ?? 0) || 0;
|
|
7252
|
-
const origFill = self.fill;
|
|
7253
|
-
const origStroke = self.stroke;
|
|
7254
|
-
const origStrokeWidth = self.strokeWidth;
|
|
7255
|
-
const origStyles = self.styles;
|
|
7256
|
-
const origShadow = self.shadow;
|
|
7257
|
-
try {
|
|
7258
|
-
ctx.save();
|
|
7259
|
-
self.shadow = null;
|
|
7260
|
-
self.fill = shadowColor;
|
|
7261
|
-
self.styles = {};
|
|
7262
|
-
self.stroke = shadowColor;
|
|
7263
|
-
self.strokeWidth = dropShadowSpread;
|
|
7264
|
-
ctx.translate(shadowOffsetX, shadowOffsetY);
|
|
7265
|
-
if (shadowBlur > 0) ctx.filter = `blur(${shadowBlur / 2}px)`;
|
|
7266
|
-
ctx.lineJoin = "round";
|
|
7267
|
-
ctx.lineCap = "round";
|
|
7268
|
-
originalRender(ctx);
|
|
7269
|
-
ctx.restore();
|
|
7270
|
-
self.fill = origFill;
|
|
7271
|
-
self.stroke = origStroke;
|
|
7272
|
-
self.strokeWidth = origStrokeWidth;
|
|
7273
|
-
self.styles = origStyles;
|
|
7274
|
-
self.shadow = null;
|
|
7275
|
-
originalRender(ctx);
|
|
7276
|
-
} finally {
|
|
7277
|
-
self.fill = origFill;
|
|
7278
|
-
self.stroke = origStroke;
|
|
7279
|
-
self.strokeWidth = origStrokeWidth;
|
|
7280
|
-
self.styles = origStyles;
|
|
7281
|
-
self.shadow = origShadow;
|
|
7282
|
-
}
|
|
7283
7237
|
} else {
|
|
7284
7238
|
originalRender(ctx);
|
|
7285
7239
|
}
|
|
@@ -7361,7 +7315,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7361
7315
|
const oy = Number(shadow.offsetY ?? 0) || 0;
|
|
7362
7316
|
const blur = Math.max(0, Number(shadow.blur ?? 0));
|
|
7363
7317
|
const shadowColor = String(shadow.color);
|
|
7364
|
-
const sourceSpread =
|
|
7318
|
+
const sourceSpread = 0;
|
|
7365
7319
|
const pad = Math.max(16, Math.ceil((blur + sourceSpread) * 4) + Math.ceil(Math.max(Math.abs(ox), Math.abs(oy))) + 8);
|
|
7366
7320
|
const shadowBounds = unionBounds([
|
|
7367
7321
|
...rects,
|
|
@@ -17412,7 +17366,14 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17412
17366
|
const minEntries = page.minEntries != null ? Math.max(0, page.minEntries) : 1;
|
|
17413
17367
|
let entryCount;
|
|
17414
17368
|
if (Array.isArray(entries)) {
|
|
17415
|
-
|
|
17369
|
+
const realEntries = entries.filter((entry) => {
|
|
17370
|
+
if (!isRecord(entry)) return false;
|
|
17371
|
+
return Object.keys(entry).some(
|
|
17372
|
+
(k) => k !== ENTRY_ID_KEY && k !== ENTRY_NAME_KEY
|
|
17373
|
+
);
|
|
17374
|
+
});
|
|
17375
|
+
const count = minEntries === 0 ? realEntries.length : Math.max(1, realEntries.length);
|
|
17376
|
+
entryCount = count;
|
|
17416
17377
|
} else {
|
|
17417
17378
|
entryCount = minEntries === 0 ? 0 : minEntries;
|
|
17418
17379
|
}
|
|
@@ -17423,6 +17384,25 @@ function buildRepeatablePagesInputForApply(schema, sectionState) {
|
|
|
17423
17384
|
};
|
|
17424
17385
|
});
|
|
17425
17386
|
}
|
|
17387
|
+
function sanitizeSectionStateAgainstSchema(state, schema) {
|
|
17388
|
+
if (!state) return {};
|
|
17389
|
+
if (!schema) return { ...state };
|
|
17390
|
+
const known = /* @__PURE__ */ new Set();
|
|
17391
|
+
for (const s of schema.sections ?? []) known.add(s.id);
|
|
17392
|
+
for (const p of schema.repeatablePages ?? []) known.add(p.id);
|
|
17393
|
+
const out = {};
|
|
17394
|
+
for (const [key, value] of Object.entries(state)) {
|
|
17395
|
+
if (known.has(key)) {
|
|
17396
|
+
out[key] = value;
|
|
17397
|
+
continue;
|
|
17398
|
+
}
|
|
17399
|
+
const compositeMatch = /^(.+?)_(\d+)_(.+)$/.exec(key);
|
|
17400
|
+
if (compositeMatch && known.has(compositeMatch[1]) && known.has(compositeMatch[3])) {
|
|
17401
|
+
out[key] = value;
|
|
17402
|
+
}
|
|
17403
|
+
}
|
|
17404
|
+
return out;
|
|
17405
|
+
}
|
|
17426
17406
|
async function fetchRow(supabaseUrl, anonKey, table, id) {
|
|
17427
17407
|
const url = `${supabaseUrl}/rest/v1/${table}?id=eq.${id}&select=*`;
|
|
17428
17408
|
const res = await fetch(url, {
|
|
@@ -17655,7 +17635,8 @@ async function resolveFromForm(options) {
|
|
|
17655
17635
|
let mergedSectionState = { ...sectionState };
|
|
17656
17636
|
const templateDefaultData = templateRow.default_data;
|
|
17657
17637
|
if (templateDefaultData && isDefaultDataV2(templateDefaultData)) {
|
|
17658
|
-
const
|
|
17638
|
+
const rawDefaults = templateDefaultData.sectionState;
|
|
17639
|
+
const defaults = sanitizeSectionStateAgainstSchema(rawDefaults, formSchema);
|
|
17659
17640
|
for (const key of Object.keys(defaults)) {
|
|
17660
17641
|
if (!(key in mergedSectionState)) {
|
|
17661
17642
|
mergedSectionState[key] = defaults[key];
|
|
@@ -17664,6 +17645,7 @@ async function resolveFromForm(options) {
|
|
|
17664
17645
|
}
|
|
17665
17646
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, templateDefaultMetaSectionState, inferredSections);
|
|
17666
17647
|
mergedSectionState = mergeRepeatableEntryMeta(mergedSectionState, defaultFormMetaSectionState, inferredSections);
|
|
17648
|
+
mergedSectionState = sanitizeSectionStateAgainstSchema(mergedSectionState, formSchema);
|
|
17667
17649
|
const flatFormData = flattenSectionStateToFormData(mergedSectionState, inferredSections);
|
|
17668
17650
|
const dynamicFields = templateConfig.dynamicFields || [];
|
|
17669
17651
|
const mappings = [];
|
|
@@ -19103,9 +19085,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19103
19085
|
}
|
|
19104
19086
|
return svgString;
|
|
19105
19087
|
}
|
|
19106
|
-
const resolvedPackageVersion = "0.5.
|
|
19088
|
+
const resolvedPackageVersion = "0.5.219";
|
|
19107
19089
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19108
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
19090
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.219";
|
|
19109
19091
|
const roundParityValue = (value) => {
|
|
19110
19092
|
if (typeof value !== "number") return value;
|
|
19111
19093
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -19666,6 +19648,58 @@ class PixldocsRenderer {
|
|
|
19666
19648
|
compressionQuality
|
|
19667
19649
|
});
|
|
19668
19650
|
}
|
|
19651
|
+
/**
|
|
19652
|
+
* Render the template AND deliver the resulting PDF to the user — currently
|
|
19653
|
+
* via email (SendGrid). The PDF is rendered server-side on EC2, uploaded to
|
|
19654
|
+
* S3 (returned as `pdfUrl` for download fallback), and emailed with the PDF
|
|
19655
|
+
* attached.
|
|
19656
|
+
*
|
|
19657
|
+
* Every delivery is logged in the `delivery_log` table for audit + admin
|
|
19658
|
+
* resend. The same `pdfUrl` is returned to the caller so the host app can
|
|
19659
|
+
* also offer a "Download" button on the success screen.
|
|
19660
|
+
*
|
|
19661
|
+
* ```ts
|
|
19662
|
+
* const result = await renderer.renderAndDeliver({
|
|
19663
|
+
* templateId, formSchemaId, sectionState,
|
|
19664
|
+
* project: 'biomaker',
|
|
19665
|
+
* recipient: { email: 'user@example.com', name: 'Anya' },
|
|
19666
|
+
* });
|
|
19667
|
+
* // → { jobId, pdfUrl, deliveries: [{ channel: 'email', status: 'sent' }] }
|
|
19668
|
+
* ```
|
|
19669
|
+
*
|
|
19670
|
+
* Requires `RendererConfig.deliveryServerUrl` to be set.
|
|
19671
|
+
*/
|
|
19672
|
+
async renderAndDeliver(options) {
|
|
19673
|
+
var _a;
|
|
19674
|
+
const base = (_a = this.config.deliveryServerUrl) == null ? void 0 : _a.replace(/\/+$/, "");
|
|
19675
|
+
if (!base) {
|
|
19676
|
+
throw new Error("renderAndDeliver: RendererConfig.deliveryServerUrl is required");
|
|
19677
|
+
}
|
|
19678
|
+
const { templateId, formSchemaId, sectionState, themeId, watermark, project, recipient, channels, scale } = options;
|
|
19679
|
+
if (!project) throw new Error('renderAndDeliver: project is required (e.g. "biomaker", "pixldocs")');
|
|
19680
|
+
if (!(recipient == null ? void 0 : recipient.email)) throw new Error("renderAndDeliver: recipient.email is required");
|
|
19681
|
+
const body = {
|
|
19682
|
+
template_id: templateId,
|
|
19683
|
+
form_schema_id: formSchemaId,
|
|
19684
|
+
data: { version: 2, sectionState },
|
|
19685
|
+
project,
|
|
19686
|
+
recipient,
|
|
19687
|
+
channels: channels || ["email"]
|
|
19688
|
+
};
|
|
19689
|
+
if (themeId) body.theme = themeId;
|
|
19690
|
+
if (typeof watermark === "boolean") body.watermark = watermark;
|
|
19691
|
+
if (typeof scale === "number") body.scale = scale;
|
|
19692
|
+
const res = await fetch(`${base}/v1/render-and-deliver`, {
|
|
19693
|
+
method: "POST",
|
|
19694
|
+
headers: { "Content-Type": "application/json" },
|
|
19695
|
+
body: JSON.stringify(body)
|
|
19696
|
+
});
|
|
19697
|
+
if (!res.ok) {
|
|
19698
|
+
const errText = await res.text().catch(() => "");
|
|
19699
|
+
throw new Error(`renderAndDeliver failed: ${res.status} ${errText.slice(0, 300)}`);
|
|
19700
|
+
}
|
|
19701
|
+
return await res.json();
|
|
19702
|
+
}
|
|
19669
19703
|
async renderById(templateId, formData, options) {
|
|
19670
19704
|
const resolved = await resolveTemplateData({
|
|
19671
19705
|
templateId,
|
|
@@ -19797,7 +19831,7 @@ class PixldocsRenderer {
|
|
|
19797
19831
|
await this.waitForCanvasScene(container, cloned, i);
|
|
19798
19832
|
}
|
|
19799
19833
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
19800
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
19834
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-CwyiHDGD.cjs"));
|
|
19801
19835
|
const prepared = preparePagesForExport(
|
|
19802
19836
|
cloned.pages,
|
|
19803
19837
|
canvasWidth,
|
|
@@ -21739,7 +21773,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
21739
21773
|
const by = parseFloat(marker.getAttribute("data-by") || "0");
|
|
21740
21774
|
const bw = parseFloat(marker.getAttribute("data-bw") || "0");
|
|
21741
21775
|
const bh = parseFloat(marker.getAttribute("data-bh") || "0");
|
|
21742
|
-
const spread =
|
|
21776
|
+
const spread = 0;
|
|
21743
21777
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
21744
21778
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
21745
21779
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
@@ -21987,7 +22021,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
21987
22021
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
21988
22022
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
21989
22023
|
try {
|
|
21990
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
22024
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-CwyiHDGD.cjs"));
|
|
21991
22025
|
try {
|
|
21992
22026
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
21993
22027
|
} catch {
|
|
@@ -22384,4 +22418,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
22384
22418
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
22385
22419
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
22386
22420
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
22387
|
-
//# sourceMappingURL=index-
|
|
22421
|
+
//# sourceMappingURL=index-CBB2UdwF.cjs.map
|