UNPKG

@appsemble/node-utils

Version:

NodeJS utilities used by Appsemble internally.

118 lines (116 loc) 5.38 kB
import { createRequire } from 'node:module'; import { baseTheme } from '@appsemble/lang-sdk'; import { bulmaVersion, logger } from '@appsemble/node-utils'; import { renderSync } from 'sass'; import stripBom from 'strip-bom'; const require = createRequire(import.meta.url); const bulmaPath = require.resolve('bulma/bulma.sass').replaceAll('\\', '/'); const functionPath = require.resolve('bulma/sass/utilities/functions.sass').replaceAll('\\', '/'); const checkRadioPath = require .resolve('bulma-checkradio/src/sass/index.sass') .replaceAll('\\', '/'); const bulmaSliderPath = require.resolve('bulma-slider/src/sass/index.sass').replaceAll('\\', '/'); const bulmaSwitchPath = require.resolve('bulma-switch/src/sass/index.sass').replaceAll('\\', '/'); function getQueryParameter(value) { return Array.isArray(value) ? value[0] : value; } /** * Process SASS styles based on given parameters. * * @param theme The theme object to turn into a SASS file. * @returns SASS string containing the base Appsemble style augmented by user parameters. */ function processStyle(theme) { const fontSource = theme.fontSource || baseTheme.font.source; const fontFamily = theme.fontFamily || baseTheme.font.family; let googleFontsImport = ''; if (fontSource === 'google') { const googleFontsUrl = new URL('https://fonts.googleapis.com/css'); googleFontsUrl.searchParams.set('display', 'swap'); googleFontsUrl.searchParams.set('family', fontFamily); googleFontsImport = `@import url(${googleFontsUrl});`; } return ` @charset "utf-8"; ${googleFontsImport} $family-sans-serif: '${fontFamily}', sans-serif !default; $primary: ${theme.primaryColor || baseTheme.primaryColor}; $link: ${theme.linkColor || baseTheme.linkColor}; $info: ${theme.infoColor || baseTheme.infoColor}; $success: ${theme.successColor || baseTheme.successColor}; $warning: ${theme.warningColor || baseTheme.warningColor}; $danger: ${theme.dangerColor || baseTheme.dangerColor}; $themeColor: ${theme.themeColor || baseTheme.themeColor}; $splashColor: ${theme.splashColor || baseTheme.splashColor}; @import "${functionPath}"; $themeColor-invert: findColorInvert($themeColor); $splashColor-invert: findColorInvert($splashColor); @import "${bulmaPath}"; @import "${checkRadioPath}"; @import "${bulmaSliderPath}"; @import "${bulmaSwitchPath}"; // Syntax: https://sass-lang.com/documentation/breaking-changes/css-vars :root { --primary-color: #{$primary}; --link-color: #{$link}; --success-color: #{$success}; --info-color: #{$info}; --warning-color: #{$warning}; --danger-color: #{$danger}; --theme-color: #{$themeColor}; --splash-color: #{$splashColor}; --primary-color-invert: #{$primary-invert}; --link-color-invert: #{$link-invert}; --success-color-invert: #{$success-invert}; --info-color-invert: #{$info-invert}; --warning-color-invert: #{$warning-invert}; --danger-color-invert: #{$danger-invert}; --theme-color-invert: #{$themeColor-invert}; --splash-color-invert: #{$splashColor-invert}; }`; } export function createBulmaHandler({ createTheme, getTheme }) { return async (ctx) => { const { query } = ctx; const theme = { bulmaVersion, primaryColor: (getQueryParameter(query.primaryColor) || baseTheme.primaryColor).toLowerCase(), linkColor: (getQueryParameter(query.linkColor) || baseTheme.linkColor).toLowerCase(), successColor: (getQueryParameter(query.successColor) || baseTheme.successColor).toLowerCase(), infoColor: (getQueryParameter(query.infoColor) || baseTheme.infoColor).toLowerCase(), warningColor: (getQueryParameter(query.warningColor) || baseTheme.warningColor).toLowerCase(), dangerColor: (getQueryParameter(query.dangerColor) || baseTheme.dangerColor).toLowerCase(), themeColor: (getQueryParameter(query.themeColor) || baseTheme.themeColor).toLowerCase(), splashColor: (getQueryParameter(query.splashColor) || baseTheme.splashColor).toLowerCase(), fontFamily: getQueryParameter(query.fontFamily) || baseTheme.font.family, // @ts-expect-error 2322 null is not assignable to type (strictNullChecks) fontSource: getQueryParameter(query.fontSource) || baseTheme.font.source, }; const result = await getTheme({ theme }); let css = result?.css; if (!css) { css = stripBom(String(renderSync({ data: processStyle(theme), outputStyle: 'compressed', logger: { debug(message) { logger.silly(message); }, warn(message, { deprecation }) { if (!deprecation) { logger.verbose(message); } }, }, }).css)); } ctx.body = css; ctx.type = 'text/css'; ctx.set('Cache-Control', 'max-age=31536000,immutable'); if (!result) { // This is not awaited on purpose. createTheme({ ...theme, css }); } }; } //# sourceMappingURL=bulmaHandler.js.map