pixel-forge
Version:
A comprehensive generator for social media previews, favicons, and visual assets across all platforms
182 lines (181 loc) • 8.37 kB
JavaScript
"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;