- Added `previewConfigKey` metadata to multiple scripts including fetch-binary, fetch-html, fetch-http, fetch-rss-feed, fingerprint, get-secret, jsonata, ntfy, render-template, and send-email, improving configuration visibility. - Updated the `FieldHelp` and `ScriptCard` components to utilize the new preview configuration, enhancing the user interface for displaying script metadata. - Refactored `TriggerCard` and `WorkflowTestPanel` components to support expanded views, improving user interaction and accessibility of configuration details. - Enhanced the `WorkflowVisualEditor` to manage test panel visibility more effectively. This update improves the overall user experience by providing clearer context and configuration options for scripts and workflows.
128 lines
3.3 KiB
JavaScript
128 lines
3.3 KiB
JavaScript
import Mustache from "mustache";
|
|
|
|
/**
|
|
* @param {string} html
|
|
*/
|
|
function htmlToText(html) {
|
|
return html
|
|
.replace(/<style[\s\S]*?<\/style>/gi, "")
|
|
.replace(/<script[\s\S]*?<\/script>/gi, "")
|
|
.replace(/<br\s*\/?>/gi, "\n")
|
|
.replace(/<\/(p|div|h[1-6]|li|tr)>/gi, "\n")
|
|
.replace(/<li[^>]*>/gi, "- ")
|
|
.replace(/<[^>]+>/g, "")
|
|
.replace(/ /g, " ")
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, "'")
|
|
.replace(/\n{3,}/g, "\n\n")
|
|
.trim();
|
|
}
|
|
|
|
/**
|
|
* @param {unknown} partialsConfig
|
|
*/
|
|
async function loadPartials(partialsConfig) {
|
|
/** @type {Record<string, string>} */
|
|
const partials = {};
|
|
if (partialsConfig == null) return partials;
|
|
if (typeof partialsConfig !== "object" || Array.isArray(partialsConfig)) {
|
|
throw new Error("config.partials must be an object");
|
|
}
|
|
|
|
for (const [partialName, pageName] of Object.entries(
|
|
/** @type {Record<string, unknown>} */ (partialsConfig),
|
|
)) {
|
|
if (typeof pageName !== "string" || pageName.length === 0) {
|
|
throw new Error(`config.partials.${partialName} must be a template page name`);
|
|
}
|
|
partials[partialName] = await $responses.getTemplate(pageName);
|
|
}
|
|
return partials;
|
|
}
|
|
|
|
async function renderTemplate(ctx) {
|
|
const templateName = ctx.config?.template;
|
|
if (typeof templateName !== "string" || templateName.length === 0) {
|
|
throw new Error("config.template is required");
|
|
}
|
|
|
|
const vars = ctx.data?.vars ?? ctx.data;
|
|
if (vars == null || typeof vars !== "object" || Array.isArray(vars)) {
|
|
throw new Error("data.vars must be an object");
|
|
}
|
|
|
|
const template = await $responses.getTemplate(templateName);
|
|
const partials = await loadPartials(ctx.config?.partials);
|
|
|
|
log.info(
|
|
{
|
|
template: templateName,
|
|
partials: Object.keys(partials),
|
|
varKeys: Object.keys(vars),
|
|
},
|
|
"render-template: rendering mustache template",
|
|
);
|
|
|
|
const html = Mustache.render(template, vars, partials);
|
|
const text = htmlToText(html);
|
|
|
|
return {
|
|
html,
|
|
text,
|
|
template: templateName,
|
|
};
|
|
}
|
|
|
|
renderTemplate.meta = {
|
|
description:
|
|
"Render an HTML template from Responses (kind: template) with Mustache and return html + plain-text fallback",
|
|
previewConfigKey: "template",
|
|
config: {
|
|
template: {
|
|
type: "string",
|
|
required: true,
|
|
description: "Responses page name with kind=template",
|
|
},
|
|
partials: {
|
|
type: "object",
|
|
required: false,
|
|
description: "Map of partial name to template page name (e.g. { item: email-item })",
|
|
},
|
|
},
|
|
input: {
|
|
vars: {
|
|
type: "object",
|
|
required: true,
|
|
description: "Mustache view data (title, items, etc.)",
|
|
},
|
|
},
|
|
output: {
|
|
html: { type: "string", description: "Rendered HTML" },
|
|
text: { type: "string", description: "Plain-text fallback stripped from HTML" },
|
|
template: { type: "string", description: "Template page name used" },
|
|
},
|
|
example: {
|
|
data: {
|
|
vars: {
|
|
title: "Daily digest",
|
|
message: "Latest items from your feed.",
|
|
items: [
|
|
{
|
|
title: "Example post",
|
|
link: "https://example.com/post",
|
|
summary: "A short summary.",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
config: {
|
|
template: "email-default",
|
|
},
|
|
},
|
|
};
|
|
|
|
export default renderTemplate;
|