UNPKG

@salla.sa/ecommerce-events-base

Version:

Base types and utilities for Salla ecommerce event tracking

123 lines (118 loc) 4.68 kB
// src/ecommerce-event-discover.ts import { readdir, readFile } from "fs/promises"; import { join, resolve } from "path"; function AutoRegistryEventsPlugin() { return { name: "AutoRegistryEventsPlugin", // Add configResolved hook to run earlier configResolved(config) { console.log("\u{1F527} Config resolved, mode:", config.command); }, // Add buildStart hook async buildStart() { console.log("\u{1F680} BuildStart hook triggered"); await generateRegistryFile(); }, // Add configureServer hook for dev mode configureServer(server) { console.log("\u{1F527} Configure server hook triggered"); generateRegistryFile().catch(console.error); }, // Add resolveId hook to handle the import resolveId(id, importer) { if (id === "./auto-listeners-registry" && importer?.includes("src/index.ts")) { console.log("\u{1F50D} Resolving auto-listeners-registry import"); const registryPath = resolve(process.cwd(), "src/auto-listeners-registry.ts"); return registryPath; } } }; } async function generateRegistryFile() { console.log("\u{1F50D} Discovering event listeners..."); const listenersDir = resolve(process.cwd(), "src/listeners"); const listeners = await discoverListeners(listenersDir); console.log(`\u{1F4E6} Found ${listeners.length} event listeners`); const registryCode = generateAutoRegistry(listeners); const registryPath = resolve(process.cwd(), "src/auto-listeners-registry.ts"); const fs = await import("fs/promises"); await fs.writeFile(registryPath, registryCode); console.log("\u2705 Auto-registry file generated at:", registryPath); } async function discoverListeners(listenersDir) { const listeners = []; try { const files = await readdir(listenersDir); const tsFiles = files.filter((file) => file.endsWith(".ts") && !file.endsWith(".d.ts")); for (const file of tsFiles) { const filePath = join(listenersDir, file); const content = await readFile(filePath, "utf-8"); const eventNameMatch = content.match(/export const eventName = (EcommerceEvents\.\w+);/); const hasDefaultExport = content.includes("export default (payload:"); if (eventNameMatch && hasDefaultExport) { if (hasActualLogic(content)) { const eventName = eventNameMatch[1]; const importPath = `./listeners/${file.replace(".ts", "")}`; const fileName = file.replace(".ts", ""); listeners.push({ eventName, importPath, fileName }); } else { console.log(`\u23ED\uFE0F Skipping listener ${file} - no meaningful logic detected`); } } } } catch (error) { console.warn("Warning: Could not discover listeners:", error); } return listeners; } function hasActualLogic(content) { const defaultExportMatch = content.match(/export default \(payload:[^)]+\):[^{]*{([^}]*)}/s); if (!defaultExportMatch) { return false; } const functionBody = defaultExportMatch[1]; const cleanBody = functionBody.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim(); if (!cleanBody) { return false; } const consoleLogRegex = /console\.(log|warn|error|info|debug)\s*\([^)]*\)\s*;?/g; const bodyWithoutConsoleLogs = cleanBody.replace(consoleLogRegex, "").trim(); if (!bodyWithoutConsoleLogs) { return false; } const placeholderPatterns = [ /add\s+your\s+custom\s+tracking\s+logic\s+here/i, /todo/i, /implement\s+your\s+logic/i, /your\s+code\s+here/i ]; const hasOnlyPlaceholders = placeholderPatterns.some( (pattern) => pattern.test(bodyWithoutConsoleLogs) && bodyWithoutConsoleLogs.replace(pattern, "").trim() === "" ); return !hasOnlyPlaceholders; } function generateAutoRegistry(listeners) { const toCamelCase = (str) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); const imports = listeners.map((listener) => { const camelCaseName = toCamelCase(listener.fileName); return `import ${camelCaseName}Handler, { eventName as ${camelCaseName}EventName } from '${listener.importPath}';`; }).join("\n"); const registrations = listeners.map((listener) => { const camelCaseName = toCamelCase(listener.fileName); return `listeners.set(${camelCaseName}EventName, ${camelCaseName}Handler);`; }).join("\n"); return `// Auto-generated listeners registry - DO NOT EDIT MANUALLY // This file is generated by the Vite listeners plugin ${imports} const listeners: Map<string, (payload: any) => void> = new Map(); ${registrations} export { listeners }; `; } export { AutoRegistryEventsPlugin };