UNPKG

@underpostnet/underpost

Version:
162 lines (146 loc) 7.89 kB
import { favicons } from 'favicons'; // TODO: search alternatives // import textToImage from 'text-to-image'; import { loggerFactory } from './logger.js'; import fs from 'fs-extra'; import { getCapVariableName, s4 } from '../client/components/core/CommonJs.js'; import { FileFactory } from '../api/file/file.service.js'; import { svg, png, png3x } from 'font-awesome-assets'; const logger = loggerFactory(import.meta); const faBase64Png = (faId = 'check', width = 100, height = 100, color = '#209e00') => { const b64Src = png3x(faId, color, width, height); return b64Src.split('src="data:image/png;base64,')[1].split('"')[0]; }; const defaultBaseTextImgOptions = { debug: true, fontFamily: 'Arial', fontWeight: 'bold', bgColor: 'black', textColor: 'white', debugFilename: 'src/client/public/text-image.png', verticalAlign: 'center', textAlign: 'center', }; const defaultBaseTextImgOptionsSizes = { '70x70': { maxWidth: 70, customHeight: 70, fontSize: 25, margin: 10, }, '100x100': { maxWidth: 100, customHeight: 100, fontSize: 30, margin: 12, }, '100x300': { maxWidth: 300, customHeight: 100, fontSize: 30, margin: 12, }, '1200x1200': { maxWidth: 1200, customHeight: 1200, fontSize: 500, margin: 50, }, }; const buildTextImg = async (text = 'APP', options, size = '1200x1200') => { options = { ...defaultBaseTextImgOptions, ...defaultBaseTextImgOptionsSizes[size], ...options }; // await textToImage.generate(text, options); }; const getBufferPngText = async ({ text, textColor, bgColor, size, debugFilename }) => { if (!text) text = 'Hello World!'; if (!textColor) textColor = '#000000'; if (!bgColor) bgColor = '#ffffff'; if (!size) size = '100x300'; if (!debugFilename) debugFilename = `./${s4()}${s4()}${s4()}.png`; await buildTextImg(text, { textColor, bgColor, size, debugFilename }, size); if (!fs.existsSync(debugFilename)) return Buffer.alloc(0); // Return empty buffer if file not found const bufferImage = fs.readFileSync(debugFilename); fs.removeSync(debugFilename); return bufferImage; }; const buildIcons = async ({ publicClientId, metadata: { title, description, keywords, author, thumbnail, themeColor }, }) => { const source = `src/client/public/${publicClientId}/assets/logo/base-icon.png`; // Source image(s). `string`, `buffer` or array of `string` const configuration = { path: '/', // Path for overriding default icons path. `string` appName: title ? title : null, // Your application's name. `string` appShortName: title ? title : null, // Your application's short_name. `string`. Optional. If not set, appName will be used appDescription: description ? description : null, // Your application's description. `string` developerName: author ? author : null, // Your (or your developer's) name. `string` developerURL: author ? author : null, // Your (or your developer's) URL. `string` cacheBustingQueryParam: null, // Query parameter added to all URLs that acts as a cache busting system. `string | null` dir: 'auto', // Primary text direction for name, short_name, and description lang: 'en-US', // Primary language for name and short_name background: themeColor ? themeColor : '#fff', // Background colour for flattened icons. `string` theme_color: themeColor ? themeColor : '#fff', // Theme color user for example in Android's task switcher. `string` appleStatusBarStyle: 'black-translucent', // Style for Apple status bar: "black-translucent", "default", "black". `string` display: 'standalone', // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string` orientation: 'any', // Default orientation: "any", "natural", "portrait" or "landscape". `string` scope: '/', // set of URLs that the browser considers within your app start_url: '/?homescreen=1', // Start URL when launching the application from a device. `string` preferRelatedApplications: false, // Should the browser prompt the user to install the native companion app. `boolean` relatedApplications: undefined, // Information about the native companion apps. This will only be used if `preferRelatedApplications` is `true`. `Array<{ id: string, url: string, platform: string }>` version: '1.0', // Your application's version string. `string` pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art. Only supported in offline mode. loadManifestWithCredentials: true, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean` manifestMaskable: true, // Maskable source image(s) for manifest.json. "true" to use default source. More information at https://web.dev/maskable-icon/. `boolean`, `string`, `buffer` or array of `string` icons: { // Platform Options: // - offset - offset in percentage // - background: // * false - use default // * true - force use default, e.g. set background for Android icons // * color - set background for the specified icons // android: true, // Create Android homescreen icon. `boolean` or `{ offset, background }` or an array of sources appleIcon: true, // Create Apple touch icons. `boolean` or `{ offset, background }` or an array of sources appleStartup: true, // Create Apple startup images. `boolean` or `{ offset, background }` or an array of sources favicons: true, // Create regular favicons. `boolean` or `{ offset, background }` or an array of sources windows: true, // Create Windows 8 tile icons. `boolean` or `{ offset, background }` or an array of sources yandex: true, // Create Yandex browser icon. `boolean` or `{ offset, background }` or an array of sources }, shortcuts: [ // Your applications's Shortcuts (see: https://developer.mozilla.org/docs/Web/Manifest/shortcuts) // Array of shortcut objects: // { // name: 'View your Inbox', // The name of the shortcut. `string` // short_name: 'inbox', // optionally, falls back to name. `string` // description: 'View your inbox messages', // optionally, not used in any implemention yet. `string` // url: '/inbox', // The URL this shortcut should lead to. `string` // icon: 'test/inbox_shortcut.png', // source image(s) for that shortcut. `string`, `buffer` or array of `string` // }, // more shortcuts objects ], }; try { const response = await favicons(source, configuration); // console.log(response.images); // Array of { name: string, contents: <buffer> } // console.log(response.files); // Array of { name: string, contents: <string> } // console.log(response.html); // Array of strings (html elements) for (const image of response.images) fs.writeFileSync(`./src/client/public/${publicClientId}/${image.name}`, image.contents); for (const file of response.files) fs.writeFileSync(`./src/client/public/${publicClientId}/${file.name}`, file.contents, 'utf8'); const ssrPath = `./src/client/ssr/head/Pwa${getCapVariableName(publicClientId)}.js`; if (!fs.existsSync(ssrPath)) fs.writeFileSync(ssrPath, 'SrrComponent = () => html`' + response.html.join(`\n`) + '`;', 'utf8'); } catch (error) { logger.error(error.message); // Error description e.g. "An unknown error has occurred" } }; const getDefaultProfileImageId = async (File) => { const faId = 'user'; const tmpFilePath = `./tmp/${faId}-${s4() + s4()}.svg`; fs.writeFileSync(tmpFilePath, svg(faId, '#f5f5f5d1'), 'utf8'); const file = await new File(FileFactory.svg(fs.readFileSync(tmpFilePath), `${faId}.svg`)).save(); fs.removeSync(tmpFilePath); return file._id; }; export { buildIcons, buildTextImg, defaultBaseTextImgOptions, faBase64Png, getBufferPngText, getDefaultProfileImageId };