UNPKG

@salla.sa/ecommerce-events-base

Version:

Base types and utilities for Salla ecommerce event tracking

160 lines (153 loc) 6.44 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/plugin.ts var plugin_exports = {}; __export(plugin_exports, { AutoRegistryEventsPlugin: () => AutoRegistryEventsPlugin }); module.exports = __toCommonJS(plugin_exports); // src/ecommerce-event-discover.ts var import_promises = require("fs/promises"); var import_path = require("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 = (0, import_path.resolve)(process.cwd(), "src/auto-listeners-registry.ts"); return registryPath; } } }; } async function generateRegistryFile() { console.log("\u{1F50D} Discovering event listeners..."); const listenersDir = (0, import_path.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 = (0, import_path.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 (0, import_promises.readdir)(listenersDir); const tsFiles = files.filter((file) => file.endsWith(".ts") && !file.endsWith(".d.ts")); for (const file of tsFiles) { const filePath = (0, import_path.join)(listenersDir, file); const content = await (0, import_promises.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 }; `; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { AutoRegistryEventsPlugin });