@exabytellc/utils
Version:
EB react utils to make everything a little easier!
192 lines (182 loc) • 6.85 kB
JavaScript
import buildFilePlugin from "./buildFilePlugin.js";
import path from "path";
/**
* Vite Plugin to generate a web app manifest (`manifest.json`).
*
* @param {Object} options - Configuration options for the manifest.
* @param {string} [options.name="My App"] - Full name of the app.
* @param {string} [options.shortTitle="My App"] - Short name for the app.
* @param {string} [options.description="My App Description"] - Description of the app.
* @param {string} [options.themeColor="#ffffff"] - Theme color for the app.
* @param {string} [options.backgroundColor="#000000"] - Background color for the app.
* @param {string} [options.display="standalone"] - Display mode (e.g., standalone, fullscreen).
* @param {string} [options.orientation="any"] - Orientation of the app.
* @param {string} [options.scope="/"] - Scope of the app.
* @param {string} [options.startUrl="/"] - Start URL of the app.
* @param {string} [options.lang="en"] - Language of the app.
* @param {string} [options.dir="ltr"] - Text direction (ltr or rtl).
* @param {string[]} [options.categories=["app"]] - Categories for the app.
* @param {boolean} [options.preferRelatedApps=false] - Whether to suggest related apps.
* @param {Array} [options.relatedApps=[]] - List of related apps.
* @param {Array} [options.shortcuts=[]] - App shortcuts.
* @param {Array} [options.screenshots=[]] - App screenshots.
* @param {string} [options.iarcRatingId=""] - IARC rating ID.
* @param {Array} [options.icons=[]] - Icons for the app.
* @returns {Object} Vite plugin configuration for generating `manifest.json`.
*/
export default function generateManifestPlugin({
name = "My App",
shortTitle = "My App",
description = "My App Description",
themeColor = "#ffffff",
backgroundColor = "#000000",
display = "standalone",
orientation = "any",
scope = "/",
startUrl = "/",
lang = "en",
dir = "ltr",
categories = ["app"],
preferRelatedApps = false,
relatedApps = [],
shortcuts = [],
screenshots = [],
iarcRatingId = "",
icons = [], // Now using helper function
} = {}) {
return buildFilePlugin(
"vite-generate-manifest-plugin",
{
filename: "manifest.json",
content: (config) =>
JSON.stringify(
{
name,
short_name: shortTitle,
description,
theme_color: themeColor,
background_color: backgroundColor,
display,
orientation,
scope,
start_url: startUrl || config.base,
lang,
dir,
categories,
prefer_related_applications: preferRelatedApps,
related_applications: relatedApps,
icons: icons.map(({ src, sizes, type }) => ({
src,
sizes,
type: type ?? getFileType(src),
})),
shortcuts: shortcuts ?? [],
screenshots: screenshots.map(({ src, sizes, type }) => ({
src,
sizes,
type: type ?? getFileType(src),
})),
iarc_rating_id: iarcRatingId,
},
null,
2
),
}
);
/**
* Get the MIME type for a given file extension.
*
* @param {string} filePath - File path or URL.
* @returns {string} Corresponding MIME type.
*/
function getFileType(filePath) {
const ext = path.extname(filePath).toLowerCase();
const typeMap = {
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".ico": "image/x-icon",
".svg": "image/svg+xml",
};
return typeMap[ext] || "image/png"; // Default to PNG if unknown
}
}
// ✅ Helper Functions
/**
* Generate a related Android app entry.
*
* @param {Object} options - Android app details.
* @param {string} options.url - App URL.
* @param {string} options.id - App ID.
* @returns {Object} Related Android app entry.
*/
export function manifestRelatedAndroidApp({ url, id }) {
return { platform: "play", url, id };
}
/**
* Generate a related iOS app entry.
*
* @param {Object} options - iOS app details.
* @param {string} options.url - App URL.
* @param {string} options.id - App ID.
* @returns {Object} Related iOS app entry.
*/
export function manifestRelatedIOSApp({ url, id }) {
return { platform: "itunes", url, id };
}
/**
* Generate an icon entry for the manifest.
*
* @param {string} src - Image source URL.
* @param {string} sizes - Image size (e.g., "192x192").
* @param {string} type - MIME type (optional).
* @returns {Object} Manifest icon entry.
*/
export function manifestIcon(src, sizes, type) {
return { src, sizes, type };
}
/**
* Generate a shortcut entry for the manifest.
*
* @param {string} name - Shortcut name.
* @param {string} short_name - Shortened name.
* @param {string} description - Shortcut description.
* @param {string} url - URL for the shortcut.
* @param {string} [iconSrc] - Optional icon source.
* @returns {Object} Manifest shortcut entry.
*/
export function manifestShortcut(name, short_name, description, url, iconSrc) {
return {
name,
short_name,
description,
url,
icons: iconSrc ? [{ src: iconSrc, sizes: "192x192" }] : undefined,
};
}
/**
* Generate a screenshot entry for the manifest.
*
* @param {string} src - Screenshot source URL.
* @param {string} [sizes="1080x1920"] - Image size.
* @param {string} type - MIME type (optional).
* @returns {Object} Manifest screenshot entry.
*/
export function manifestScreenshot(src, sizes = "1080x1920", type) {
return { src, sizes, type };
}
/**
* Generate an IARC rating ID for the manifest.
*
* @param {string} [rating="general"] - Rating level ("general", "teen", "mature").
* @returns {string} IARC rating ID.
*/
export function manifestIarcRating(rating = "general") {
const ratings = {
general: "e5fa894b-35d8-4b99-9088-3de86b3a6f7b",
teen: "1b8a6e58-d05b-4f75-8e7b-5d95db93b640",
mature: "2c5a0ef4-a6ef-42d9-9e30-bb65fc28d77b",
};
return ratings[rating] || ratings.general;
}