UNPKG

pixel-forge

Version:

A comprehensive generator for social media previews, favicons, and visual assets across all platforms

182 lines (181 loc) 8.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebSEOGenerator = void 0; const path_1 = __importDefault(require("path")); const image_processor_1 = require("../../core/image-processor"); class WebSEOGenerator { constructor(sourceImage, config) { this.config = config; this.sourceImage = sourceImage; } /** * Generate essential SEO images for web applications */ async generate(options = {}) { const { title = this.config.socialPreview?.title || this.config.appName, description = this.config.socialPreview?.description || this.config.description || '', template = this.config.socialPreview?.template || 'basic', includeOpenGraph = true, includeTwitter = true, includeGeneric = true, outputFormat = 'both' } = options; // Generate generic OpenGraph image (works everywhere) if (includeGeneric) { await this.generateGenericOpenGraph({ title, description, template, outputFormat }); } // Generate specific OpenGraph image if (includeOpenGraph) { await this.generateOpenGraphImage({ title, description, template, outputFormat }); } // Generate Twitter card image if (includeTwitter) { await this.generateTwitterCardImage({ title, description, template, outputFormat }); } } /** * Generate generic og-image that works across all platforms */ async generateGenericOpenGraph(options) { const { title, description, template, outputFormat } = options; const { width, height } = image_processor_1.ImageSizes.social.standard; const processor = new image_processor_1.ImageProcessor(this.sourceImage); // Create social preview with template processor.createSocialPreview({ width, height, title, description, template: template, background: this.config.backgroundColor }); // Save in requested format(s) if (outputFormat === 'png' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'og-image.png'); await processor.save(outputPath, { format: 'png', quality: this.config.output.quality }); } if (outputFormat === 'jpeg' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'og-image.jpg'); await processor.save(outputPath, { format: 'jpeg', quality: this.config.output.quality }); } } /** * Generate OpenGraph-specific image */ async generateOpenGraphImage(options) { const { title, description, template, outputFormat } = options; const { width, height } = image_processor_1.ImageSizes.social.facebook; // Use Facebook dimensions for OpenGraph const processor = new image_processor_1.ImageProcessor(this.sourceImage); processor.createSocialPreview({ width, height, title, description, template: template, background: this.config.backgroundColor }); // Save in requested format(s) if (outputFormat === 'png' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'opengraph.png'); await processor.save(outputPath, { format: 'png', quality: this.config.output.quality }); } if (outputFormat === 'jpeg' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'opengraph.jpg'); await processor.save(outputPath, { format: 'jpeg', quality: this.config.output.quality }); } } /** * Generate Twitter card image */ async generateTwitterCardImage(options) { const { title, description, template, outputFormat } = options; const { width, height } = image_processor_1.ImageSizes.social.twitter; const processor = new image_processor_1.ImageProcessor(this.sourceImage); processor.createSocialPreview({ width, height, title, description, template: template, background: this.config.backgroundColor }); // Save in requested format(s) if (outputFormat === 'png' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'twitter-image.png'); await processor.save(outputPath, { format: 'png', quality: this.config.output.quality }); } if (outputFormat === 'jpeg' || outputFormat === 'both') { const outputPath = path_1.default.join(this.config.output.path, 'twitter-image.jpg'); await processor.save(outputPath, { format: 'jpeg', quality: this.config.output.quality }); } } /** * Get HTML meta tags for SEO images */ getMetaTags(options = {}) { const { format = 'png' } = options; const { prefix = '/' } = this.config.output; const extension = format === 'jpeg' ? 'jpg' : 'png'; return [ // Generic OpenGraph (works for Facebook, LinkedIn, most platforms) `<meta property="og:image" content="${prefix}og-image.${extension}" />`, `<meta property="og:image:width" content="${image_processor_1.ImageSizes.social.standard.width}" />`, `<meta property="og:image:height" content="${image_processor_1.ImageSizes.social.standard.height}" />`, `<meta property="og:image:type" content="image/${format === 'jpeg' ? 'jpeg' : 'png'}" />`, `<meta property="og:title" content="${this.config.appName}" />`, `<meta property="og:description" content="${this.config.description || ''}" />`, `<meta property="og:type" content="website" />`, // Twitter Card `<meta name="twitter:card" content="summary_large_image" />`, `<meta name="twitter:image" content="${prefix}twitter-image.${extension}" />`, `<meta name="twitter:title" content="${this.config.appName}" />`, `<meta name="twitter:description" content="${this.config.description || ''}" />`, // Additional SEO `<meta name="description" content="${this.config.description || ''}" />`, `<meta name="keywords" content="${this.config.appName}" />`, `<meta name="author" content="${this.config.appName}" />`, ]; } /** * Get Next.js metadata configuration */ getNextMetadata(options = {}) { const { format = 'png' } = options; const { prefix = '/' } = this.config.output; const extension = format === 'jpeg' ? 'jpg' : 'png'; return { title: this.config.appName, description: this.config.description, openGraph: { title: this.config.appName, description: this.config.description, type: 'website', images: [ { url: `${prefix}og-image.${extension}`, width: image_processor_1.ImageSizes.social.standard.width, height: image_processor_1.ImageSizes.social.standard.height, alt: this.config.appName, } ], }, twitter: { card: 'summary_large_image', title: this.config.appName, description: this.config.description, images: [`${prefix}twitter-image.${extension}`], }, }; } /** * Get list of generated files */ getGeneratedFiles(options = {}) { const { format = 'both' } = options; const files = []; if (format === 'png' || format === 'both') { files.push('og-image.png', 'opengraph.png', 'twitter-image.png'); } if (format === 'jpeg' || format === 'both') { files.push('og-image.jpg', 'opengraph.jpg', 'twitter-image.jpg'); } return files; } } exports.WebSEOGenerator = WebSEOGenerator;