UNPKG

@appsemble/node-utils

Version:

NodeJS utilities used by Appsemble internally.

46 lines 1.87 kB
import { createHash } from 'node:crypto'; import { readFile } from 'node:fs/promises'; import { compareStrings } from '@appsemble/utils'; import mustache from 'mustache'; /** * Render settings as an HTML script tag. * * @param settings The settings to render. This must be a JSON serializable object. * @param statements Custom JavaScript statements to append. * @returns A tuple of the digest and the HTML script tag. The digest should be added to the CSP * `script-src`. */ export function createSettings(settings, statements = []) { const script = [`window.settings=${JSON.stringify(settings)}`, ...statements].join(';'); const hash = createHash('sha256').update(script, 'utf8').digest('base64'); return [`'sha256-${hash}'`, `<script>${script}</script>`]; } export async function render(ctx, filename, data) { if (process.env.NODE_ENV === 'test') { ctx.body = JSON.stringify({ filename, data }); } else { const template = await (process.env.NODE_ENV === 'production' ? readFile(new URL(`../../dist/${filename}`, import.meta.url), 'utf8') : ctx.fs.promises.readFile(`/${filename}`, 'utf8')); ctx.body = mustache.render(template, data); } ctx.type = 'html'; } /** * Convert a CSP key / values pair object into a real content security policy string. * * Any falsy values will be excluded. * * @param csp The CSP object to convert * @returns The CSP object as a string */ export function makeCSP(csp) { return Object.entries(csp) .map(([key, values]) => [key, values.filter((val) => val !== false && val != null)]) .filter(([, values]) => values?.length) .sort(([a], [b]) => a.localeCompare(b)) .map(([key, values]) => `${key} ${[...new Set(values)].sort(compareStrings).join(' ')}`) .join('; '); } //# sourceMappingURL=render.js.map