UNPKG

faj-cli

Version:

FAJ - A powerful CLI resume builder with AI enhancement and multi-format export

157 lines 7.19 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.CDNFontLoader = void 0; const fs = __importStar(require("fs/promises")); const path = __importStar(require("path")); const https = __importStar(require("node:https")); const Logger_1 = require("../../utils/Logger"); class CDNFontLoader { logger; cacheDir; // Using reliable font sources - these are the actual OTF files from Google fontUrls = { // Direct links to Noto Sans SC from Google Fonts GitHub 'noto-sc-regular': 'https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf', 'noto-sc-bold': 'https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Bold.otf', // Alternative: smaller subset versions with better number rendering 'noto-sc-subset-regular': 'https://github.com/googlefonts/noto-cjk/raw/main/Sans/Variable/OTF/Subset/NotoSansCJKsc-VF.otf', 'noto-sc-subset-bold': 'https://github.com/googlefonts/noto-cjk/raw/main/Sans/SubsetOTF/SC/NotoSansSC-Bold.otf' }; constructor() { this.logger = new Logger_1.Logger('CDNFontLoader'); this.cacheDir = path.join(process.cwd(), '.font-cache'); } async loadFonts() { // Ensure cache directory exists try { await fs.access(this.cacheDir); } catch { await fs.mkdir(this.cacheDir, { recursive: true }); } // Check for cached fonts first const regularCachePath = path.join(this.cacheDir, 'noto-sc-regular.otf'); const boldCachePath = path.join(this.cacheDir, 'noto-sc-bold.otf'); let regularFont; let boldFont; try { // Try to load from cache regularFont = await fs.readFile(regularCachePath); boldFont = await fs.readFile(boldCachePath); this.logger.info('Using cached CDN fonts'); } catch { // Download from CDN this.logger.info('Downloading optimized fonts from CDN...'); try { // Try to use full fonts for better number rendering this.logger.info('Downloading fonts with better number support...'); try { // First try the full CJK font for better rendering regularFont = await this.downloadFont(this.fontUrls['noto-sc-regular']); boldFont = await this.downloadFont(this.fontUrls['noto-sc-bold']); this.logger.info('Using full CJK fonts for better rendering'); } catch (fullError) { // Fallback to subset if full fonts fail this.logger.info('Full fonts failed, using subset fonts...'); regularFont = await this.downloadFont(this.fontUrls['noto-sc-subset-regular']); boldFont = await this.downloadFont(this.fontUrls['noto-sc-subset-bold']); } // Cache them for future use await fs.writeFile(regularCachePath, regularFont); await fs.writeFile(boldCachePath, boldFont); this.logger.success('Fonts downloaded and cached successfully'); // Log file sizes const regularSize = Math.round(regularFont.length / 1024 / 1024 * 10) / 10; const boldSize = Math.round(boldFont.length / 1024 / 1024 * 10) / 10; this.logger.info(`Font sizes: Regular ${regularSize}MB, Bold ${boldSize}MB`); } catch (error) { this.logger.error('Failed to download fonts from CDN', error); throw new Error('Unable to load CJK fonts. Please check your internet connection.'); } } return { regular: regularFont, bold: boldFont }; } downloadFont(url) { return new Promise((resolve, reject) => { const chunks = []; https.get(url, (response) => { // Handle redirects if (response.statusCode === 301 || response.statusCode === 302) { const redirectUrl = response.headers.location; if (redirectUrl) { this.downloadFont(redirectUrl).then(resolve).catch(reject); return; } } if (response.statusCode !== 200) { reject(new Error(`Failed to download font: HTTP ${response.statusCode}`)); return; } const totalSize = parseInt(response.headers['content-length'] || '0', 10); let downloadedSize = 0; response.on('data', (chunk) => { chunks.push(chunk); downloadedSize += chunk.length; // Show download progress if (totalSize > 0) { const progress = Math.round((downloadedSize / totalSize) * 100); if (progress % 20 === 0) { this.logger.debug(`Download progress: ${progress}%`); } } }); response.on('end', () => { resolve(Buffer.concat(chunks)); }); response.on('error', reject); }).on('error', reject); }); } async clearCache() { try { await fs.rm(this.cacheDir, { recursive: true, force: true }); this.logger.info('Font cache cleared'); } catch (error) { this.logger.error('Failed to clear cache', error); } } } exports.CDNFontLoader = CDNFontLoader; //# sourceMappingURL=CDNFontLoader.js.map