UNPKG

webapp-astro-pwa

Version:

A ready-to-use Astro component library for adding Progressive Web App (PWA) support to your Astro projects. This package provides drop-in components and utilities for manifest injection, service worker registration, install prompts, and more. Includes a w

157 lines (142 loc) 5.25 kB
import { exec } from "child_process"; import { fileURLToPath } from "url"; import path from "path"; import fs from "fs"; import type { Config } from "../types"; /** * Returns the absolute path to 'pwa.config.json' located in the grandparent directory of the current file. * @param fileName - The name of the file to search for (currently unused, always returns 'pwa.config.json'). * @returns The absolute path as a string, or undefined if not found. */ function getPWAConfigPathFromGrandparent(): string | undefined { const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const parentDir = path.dirname(__dirname); const grandParentDir = path.dirname(parentDir); return path.join(grandParentDir, "pwa.config.json"); } /** * Runs a shell command asynchronously and logs stdout, stderr, or errors to the console. * @param command - The shell command to execute. */ function runShellCommand(command: string) { exec(command, (error: Error | null, stdout: string, stderr: string) => { if (error) { console.error(`Error: ${error.message}`); return; } console.log(`stdout: ${stdout}`); }); } /** * Reads and parses a JSON configuration file from the given file path. * @param filePath - The path to the JSON file. * @returns The parsed JSON object. */ function getConfigJSON(filePath: string) { const pwaConfigFile = fs.readFileSync(filePath, "utf8"); return JSON.parse(pwaConfigFile); } /** * Edits the given PWA configuration object by updating its properties with values from the provided config object. * Only properties defined in config will be updated. * @param pwaConfigJSON - The original PWA configuration object. * @param config - The configuration object with new values. * @returns The updated configuration object. */ function updatePWAConfig(pwaConfigJSON: Config, config: Config): Config { if (!config) return pwaConfigJSON; const pwa = { ...pwaConfigJSON }; const allowedKeys = [ "notificationAutoRequestPermission", "applicationServerKey", "saveSubscriptionPath", "fcmServiceAccountKey", "isInstallBtnVisible", "isFirebaseMessaging", "notificationBtn", "createManifest", "firebaseConfig", "disableDevLogs", "manifestPath", "notification", "forceUpdate", "cacheAssets", "isManifest", "AUTH_PASS", "AUTH_USER", "manifest", "vapidKey", "strategy", "scripts", "icons", "meta", ]; allowedKeys.forEach((key) => { if (Object.prototype.hasOwnProperty.call(config, key)) { (pwa as Record<string, unknown>)[key] = config[key as keyof Config]; } }); return pwa; } /** * Checks if any properties between the provided config and the PWA config JSON differ. * @param config - The configuration object to compare. * @param pwaConfigJSON - The existing PWA configuration object. * @returns True if any property differs, false otherwise. */ function checkIsPWAConfigChanged(config: Config, pwaConfigJSON: Config): boolean { if (!config || Object.entries(config).length === 0) return false; if (!pwaConfigJSON) return true; // Handle undefined pwaConfigJSON const pwaConfigJSONEntries = Object.entries(pwaConfigJSON); const configEntries = Object.entries(config); if (pwaConfigJSONEntries.length !== configEntries.length) return true; // Use .some to check if any property differs const hasChanges = pwaConfigJSONEntries.some(([key, value]) => { const pwaConfigJSONValue = JSON.stringify(value).trim(); const configValue = JSON.stringify(config[key as keyof Config]).trim(); return pwaConfigJSONValue !== configValue; }); return hasChanges; } /** * Creates a manifest file at the specified path if all required properties are present in the config. * Logs errors if required properties are missing. * @param config - The configuration object containing manifestPath, isManifest, and manifest. */ function generateManifestFile(config: Config) { if (!config) { console.error("No config provided"); return; } const { manifestPath, isManifest, manifest } = config; if (!manifestPath) console.log("Please provide a path for the manifest file"); if (!isManifest) console.log("Please set the isManifest property to true for the manifest file to be generated"); if (!manifest) console.log( "Please provide a JSON for manifest in configuration in manifest properties for file to be generated" ); if (!manifestPath || !isManifest || !manifest) return; console.log("manifest file generated to the path: ", manifestPath); fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)); } /** * Checks if a file exists in the root directory of the project. * @param filePath - The relative path to the file from the root directory. * @returns True if the file exists, false otherwise. */ function checkIsFileExistsInRoot(filePath: string): boolean { const rootPath = process.cwd(); const pathToFIle = `${rootPath}/${filePath}`; return fs.existsSync(pathToFIle); } export { checkIsFileExistsInRoot, getPWAConfigPathFromGrandparent, runShellCommand, getConfigJSON, updatePWAConfig, checkIsPWAConfigChanged, generateManifestFile, };