import { markdown, space, YAML } from "$sb/syscalls.ts"; import { loadPageObject, replaceTemplateVars } from "../template/template.ts"; import { CodeWidgetContent, PageMeta } from "$sb/types.ts"; import { renderTemplate } from "../template/plug_api.ts"; import { renderToText } from "$sb/lib/tree.ts"; import { rewritePageRefs, rewritePageRefsInString } from "$sb/lib/resolve.ts"; import { performQuery } from "./query.ts"; import { parseQuery } from "$sb/lib/parse-query.ts"; type TemplateConfig = { // Pull the template from a page page?: string; // Or use a string directly template?: string; // To feed data into the template you can either use a concrete value value?: any; // Or a query query?: string; // If true, don't render the template, just use it as-is raw?: boolean; }; export async function widget( bodyText: string, pageName: string, ): Promise { const pageMeta: PageMeta = await loadPageObject(pageName); try { const config: TemplateConfig = await YAML.parse(bodyText); let templateText = config.template || ""; let templatePage = config.page; if (templatePage) { // Rewrite federation page references templatePage = rewritePageRefsInString(templatePage, pageName); if (templatePage.startsWith("[[")) { templatePage = templatePage.slice(2, -2); } if (!templatePage) { throw new Error("No template page specified"); } templateText = await space.readPage(templatePage); } let value: any; if (config.value) { value = JSON.parse( await replaceTemplateVars(JSON.stringify(config.value), pageMeta), ); } if (config.query) { const parsedQuery = await parseQuery( await replaceTemplateVars(config.query, pageMeta), ); value = await performQuery(parsedQuery, pageMeta); } let { text: rendered } = config.raw ? { text: templateText } : await renderTemplate( templateText, pageMeta, value, ); if (templatePage) { const parsedMarkdown = await markdown.parseMarkdown(rendered); rewritePageRefs(parsedMarkdown, templatePage); rendered = renderToText(parsedMarkdown); } return { markdown: rendered, buttons: [{ description: "Edit", svg: ``, invokeFunction: "query.editButton", }, { description: "Reload", svg: ``, invokeFunction: "query.refreshAllWidgets", }], }; } catch (e: any) { return { markdown: `**Error:** ${e.message}`, }; } }