UNPKG

purgetss

Version:

A package that simplifies mobile app creation for Titanium developers.

405 lines (367 loc) 12.9 kB
/* eslint-disable camelcase, semi */ import fs from 'fs' import path from 'path' import { fileURLToPath } from 'url' import chalk from 'chalk' import _ from 'lodash' import { logger } from '../../shared/logger.js' import { makeSureFolderExists, alloyProject, classicProject } from '../../shared/utils.js' // Get current directory info const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const projectRoot = path.resolve(__dirname, '../../../') const cwd = process.cwd() // Folder paths const projectsFontsFolder = `${cwd}/app/assets/fonts` const projectsLibFolder = `${cwd}/app/lib` const classicProjectLibFolder = `${cwd}/Resources/lib` const projectsPurgeTSSFolder = `${cwd}/purgetss` // eslint-disable-next-line camelcase const projectsPurge_TSS_Styles_Folder = `${cwd}/purgetss/styles` // Source paths // eslint-disable-next-line camelcase const srcFonts_Folder = path.resolve(projectRoot, './assets/fonts') const srcLibFA = path.resolve(projectRoot, './dist/fontawesome.js') const srcLibMI = path.resolve(projectRoot, './dist/materialicons.js') const srcLibMS = path.resolve(projectRoot, './dist/materialsymbols.js') const srcLibF7 = path.resolve(projectRoot, './dist/framework7icons.js') // Font Awesome paths // eslint-disable-next-line camelcase const srcFA_Beta_CSSFile = `${cwd}/purgetss/fontawesome-beta/css/all.css` // eslint-disable-next-line camelcase const srcFA_Pro_CSS = `${cwd}/node_modules/@fortawesome/fontawesome-pro/css/all.css` // eslint-disable-next-line camelcase const srcFA_Beta_Web_Fonts_Folder = `${cwd}/purgetss/fontawesome-beta/webfonts/` // eslint-disable-next-line camelcase const srcFA_Pro_Web_Fonts_Folder = `${cwd}/node_modules/@fortawesome/fontawesome-pro/webfonts/` // eslint-disable-next-line camelcase const srcFA_ProFontFamilies = { 'fa-brands-400.ttf': 'FontAwesome7Brands-Regular.ttf', 'fa-brands-400.woff2': 'FontAwesome7Brands-Regular.woff2', 'fa-regular-400.ttf': 'FontAwesome7Pro-Regular.ttf', 'fa-regular-400.woff2': 'FontAwesome7Pro-Regular.woff2', 'fa-solid-900.ttf': 'FontAwesome7Pro-Solid.ttf', 'fa-solid-900.woff2': 'FontAwesome7Pro-Solid.woff2' } // eslint-disable-next-line camelcase const srcFA_Beta_FontFamilies = { 'fa-brands-400.ttf': 'FontAwesome7Brands-Regular.ttf', 'fa-brands-400.woff2': 'FontAwesome7Brands-Regular.woff2', 'fa-regular-400.ttf': 'FontAwesome7Beta-Regular.ttf', 'fa-regular-400.woff2': 'FontAwesome7Beta-Regular.woff2', 'fa-solid-900.ttf': 'FontAwesome7Beta-Solid.ttf', 'fa-solid-900.woff2': 'FontAwesome7Beta-Solid.woff2' } // TSS file paths const srcFontAwesomeTSSFile = path.resolve(projectRoot, './dist/fontawesome.tss') const srcFramework7FontTSSFile = path.resolve(projectRoot, './dist/framework7icons.tss') const srcMaterialIconsTSSFile = path.resolve(projectRoot, './dist/materialicons.tss') const srcMaterialSymbolsTSSFile = path.resolve(projectRoot, './dist/materialsymbols.tss') /** * Callback function for file operations * @param {Error} err - Error object if operation failed */ function callback(err) { if (err) throw err } /** * Copy a file from source to destination in fonts folder * @param {string} src - Source file path * @param {string} dest - Destination filename * @returns {boolean} - True if file exists and was copied */ function copyFile(src, dest) { if (fs.existsSync(src)) { fs.copyFile(src, `${projectsFontsFolder}/${dest}`, callback) return true } return false } /** * Copy Font Awesome Free fonts to project */ function copyFreeFonts() { fs.copyFile(srcFonts_Folder + '/FontAwesome7Brands-Regular.ttf', projectsFontsFolder + '/FontAwesome7Brands-Regular.ttf', callback) fs.copyFile(srcFonts_Folder + '/FontAwesome7Free-Regular.ttf', projectsFontsFolder + '/FontAwesome7Free-Regular.ttf', callback) fs.copyFile(srcFonts_Folder + '/FontAwesome7Free-Solid.ttf', projectsFontsFolder + '/FontAwesome7Free-Solid.ttf', callback) logger.item(chalk.green('Font Awesome Free')) } /** * Copy Font Awesome Pro fonts to project * @param {Object} fontFamilies - Mapping of source to destination font names * @param {string} webFonts - Path to web fonts folder */ function copyProFonts(fontFamilies, webFonts) { _.each(fontFamilies, (dest, src) => { if (copyFile(`${webFonts}/${src}`, dest)) { logger.item(`${dest} copied to ${chalk.yellow('./app/assets/fonts')}`) } }) } /** * Copy Material Icons fonts to project */ function copyMaterialIconsFonts() { // Material Icons Font const fontFamilies = [ 'MaterialIcons-Regular.ttf', 'MaterialIconsOutlined-Regular.otf', 'MaterialIconsRound-Regular.otf', 'MaterialIconsSharp-Regular.otf', 'MaterialIconsTwoTone-Regular.otf' ] _.each(fontFamilies, familyName => { copyFile(`${srcFonts_Folder}/${familyName}`, familyName) }) logger.item(chalk.green('Material Icons')) } /** * Copy Material Symbols fonts to project */ function copyMaterialSymbolsFonts() { // Material Symbols Icons Font const fontFamilies = [ 'MaterialSymbolsOutlined-Regular.ttf', 'MaterialSymbolsRounded-Regular.ttf', 'MaterialSymbolsSharp-Regular.ttf' ] _.each(fontFamilies, familyName => { copyFile(`${srcFonts_Folder}/${familyName}`, familyName) }) logger.item(chalk.green('Material Symbols')) } /** * Copy Framework7 Icons font to project */ function copyFramework7IconsFonts() { // Framework7 Font copyFile(srcFonts_Folder + '/Framework7-Icons.ttf', 'Framework7-Icons.ttf') logger.item(chalk.green('Framework 7')) } /** * Build Font Awesome JS module (imported from fonts.js) * This is a placeholder - actual implementation should be imported from fonts module */ function buildFontAwesomeJS() { // This function should be imported from the fonts module // For now, just log that it would be called logger.item(chalk.yellow('Font Awesome JS module would be built')) } /** * Copy font files based on vendor * @param {string} vendor - Font vendor (fa, mi, ms, f7) */ function copyFont(vendor) { makeSureFolderExists(projectsFontsFolder) switch (vendor) { case 'fa': case 'fontawesome': if (fs.existsSync(srcFA_Beta_CSSFile)) { copyProFonts(srcFA_Beta_FontFamilies, srcFA_Beta_Web_Fonts_Folder) } else if (fs.existsSync(srcFA_Pro_CSS)) { copyProFonts(srcFA_ProFontFamilies, srcFA_Pro_Web_Fonts_Folder) } else { copyFreeFonts() } break case 'mi': case 'materialicons': copyMaterialIconsFonts() break case 'ms': case 'materialsymbol': copyMaterialSymbolsFonts() break case 'f7': case 'framework7': copyFramework7IconsFonts() break } } /** * Copy font library modules based on vendor * @param {string} vendor - Font vendor (fa, mi, ms, f7) */ function copyFontLibrary(vendor) { switch (vendor) { case 'fa': case 'fontawesome': if (fs.existsSync(srcFA_Beta_CSSFile) || fs.existsSync(srcFA_Pro_CSS)) { buildFontAwesomeJS() } else { fs.copyFileSync(srcLibFA, projectsLibFolder + '/fontawesome.js') logger.item(chalk.yellow('fontawesome.js')) } break case 'mi': case 'materialicons': fs.copyFileSync(srcLibMI, projectsLibFolder + '/materialicons.js') logger.item(chalk.yellow('materialicons.js')) break case 'ms': case 'materialsymbol': fs.copyFileSync(srcLibMS, projectsLibFolder + '/materialsymbols.js') logger.item(chalk.yellow('materialsymbols.js')) break case 'f7': case 'framework7': fs.copyFileSync(srcLibF7, projectsLibFolder + '/framework7icons.js') logger.item(chalk.yellow('framework7icons.js')) break } } /** * Copy font style files based on vendor * @param {string} vendor - Font vendor (fa, mi, ms, f7) */ function copyFontStyle(vendor) { switch (vendor) { case 'fa': case 'fontawesome': if (fs.existsSync(srcFA_Beta_CSSFile) || fs.existsSync(srcFA_Pro_CSS)) { buildFontAwesomeJS() } else { fs.copyFileSync(srcFontAwesomeTSSFile, projectsPurge_TSS_Styles_Folder + '/fontawesome.tss') logger.item(chalk.yellow('fontawesome.tss')) } break case 'mi': case 'materialicons': fs.copyFileSync(srcMaterialIconsTSSFile, projectsPurge_TSS_Styles_Folder + '/materialicons.tss') logger.item(chalk.yellow('materialicons.tss')) break case 'ms': case 'materialsymbol': fs.copyFileSync(srcMaterialSymbolsTSSFile, projectsPurge_TSS_Styles_Folder + '/materialsymbols.tss') logger.item(chalk.yellow('materialsymbols.tss')) break case 'f7': case 'framework7': fs.copyFileSync(srcFramework7FontTSSFile, projectsPurge_TSS_Styles_Folder + '/framework7icons.tss') logger.item(chalk.yellow('framework7icons.tss')) break } } /** * Copy font libraries to project lib folder * @param {Object} options - Command options */ function copyFontLibraries(options) { if (alloyProject()) { makeSureFolderExists(projectsLibFolder) if (options.vendor && typeof options.vendor === 'string') { // Clean vendor string - remove leading = and spaces const cleanVendor = options.vendor.replace(/^=/, '').replace(/ /g, '') const selected = _.uniq(cleanVendor.split(',')) _.each(selected, vendor => { copyFontLibrary(vendor) }) } else { copyFontLibrary('fa') copyFontLibrary('mi') copyFontLibrary('ms') copyFontLibrary('f7') } } } /** * Copy font styles to project styles folder * @param {Object} options - Command options */ function copyFontStyles(options) { if (alloyProject()) { makeSureFolderExists(projectsPurgeTSSFolder) makeSureFolderExists(projectsPurge_TSS_Styles_Folder) if (options.vendor && typeof options.vendor === 'string') { // Clean vendor string - remove leading = and spaces const cleanVendor = options.vendor.replace(/^=/, '').replace(/ /g, '') const selected = _.uniq(cleanVendor.split(',')) _.each(selected, vendor => { copyFontStyle(vendor) }) } else { copyFontStyle('fa') copyFontStyle('mi') copyFontStyle('ms') copyFontStyle('f7') } } } /** * Main command: Copy icon fonts to project * @param {Object} options - Command options * @param {string} options.vendor - Specific vendors to copy (comma-separated) * @param {boolean} options.module - Copy corresponding JS modules * @param {boolean} options.styles - Copy corresponding TSS styles * @returns {Promise<boolean>} - Success status */ export async function copyFonts(options = {}) { try { if (!alloyProject()) { return false } makeSureFolderExists(projectsFontsFolder) if (options.vendor && typeof options.vendor === 'string') { // Clean vendor string - remove leading = and spaces const cleanVendor = options.vendor.replace(/^=/, '').replace(/ /g, '') const selected = _.uniq(cleanVendor.split(',')) logger.info('Copying Icon Fonts...') _.each(selected, vendor => { copyFont(vendor) }) } else { logger.info('Copying Fonts to', chalk.yellow('./app/assets/fonts'), 'folder') copyFont('fa') copyFont('mi') copyFont('ms') copyFont('f7') } if (options.module) { console.log() logger.info('Copying Modules to', chalk.yellow('./app/lib'), 'folder') copyFontLibraries(options) } if (options.styles) { console.log() logger.info('Copying Styles to', chalk.yellow('./purgetss/styles'), 'folder') copyFontStyles(options) } return true } catch (error) { logger.error('Error in copyFonts:', error.message) return false } } /** * Copy PurgeTSS UI module to project * @returns {Promise<boolean>} - Success status */ export async function copyModulesLibrary() { try { const srcPurgeTSSLibrary = path.resolve(projectRoot, './dist/purgetss.ui.js') if (alloyProject(true)) { makeSureFolderExists(projectsLibFolder) fs.copyFileSync(srcPurgeTSSLibrary, projectsLibFolder + '/purgetss.ui.js') logger.info(chalk.yellow('purgetss.ui'), 'module copied to', chalk.yellow('./app/lib'), 'folder') return true } else if (classicProject(true)) { makeSureFolderExists(classicProjectLibFolder) fs.copyFileSync(srcPurgeTSSLibrary, classicProjectLibFolder + '/purgetss.ui.js') logger.info(chalk.yellow('purgetss.ui'), 'module copied to', chalk.yellow('./Resources/lib'), 'folder') return true } else { logger.block( `Please make sure you are running ${chalk.green('purgetss')} within an Alloy or Classic Project.`, `For more information, visit ${chalk.green('https://purgetss.com')}` ) return false } } catch (error) { logger.error('Error in copyModulesLibrary:', error.message) return false } }