"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const cors_1 = __importDefault(require("cors")); const dotenv_1 = __importDefault(require("dotenv")); const minio_1 = require("./utils/minio"); const image_storage_1 = require("./utils/image-storage"); const logger_1 = require("./services/logger"); const proxyTestQueue_1 = require("./services/proxyTestQueue"); dotenv_1.default.config(); const app = (0, express_1.default)(); const PORT = process.env.PORT || 3010; app.use((0, cors_1.default)()); app.use(express_1.default.json()); // Serve static images when MinIO is not configured const LOCAL_IMAGES_PATH = process.env.LOCAL_IMAGES_PATH || '/app/public/images'; app.use('/images', express_1.default.static(LOCAL_IMAGES_PATH)); // Serve static downloads (plugin files, etc.) const LOCAL_DOWNLOADS_PATH = process.env.LOCAL_DOWNLOADS_PATH || '/app/public/downloads'; app.use('/downloads', express_1.default.static(LOCAL_DOWNLOADS_PATH)); app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // Endpoint to check server's outbound IP (for proxy whitelist setup) app.get('/outbound-ip', async (req, res) => { try { const axios = require('axios'); const response = await axios.get('https://api.ipify.org?format=json', { timeout: 10000 }); res.json({ outbound_ip: response.data.ip }); } catch (error) { res.status(500).json({ error: error.message }); } }); const auth_1 = __importDefault(require("./routes/auth")); const dashboard_1 = __importDefault(require("./routes/dashboard")); const stores_1 = __importDefault(require("./routes/stores")); const dispensaries_1 = __importDefault(require("./routes/dispensaries")); const changes_1 = __importDefault(require("./routes/changes")); const categories_1 = __importDefault(require("./routes/categories")); const products_1 = __importDefault(require("./routes/products")); const campaigns_1 = __importDefault(require("./routes/campaigns")); const analytics_1 = __importDefault(require("./routes/analytics")); const settings_1 = __importDefault(require("./routes/settings")); const proxies_1 = __importDefault(require("./routes/proxies")); const logs_1 = __importDefault(require("./routes/logs")); const scraper_monitor_1 = __importDefault(require("./routes/scraper-monitor")); const api_tokens_1 = __importDefault(require("./routes/api-tokens")); const api_permissions_1 = __importDefault(require("./routes/api-permissions")); const parallel_scrape_1 = __importDefault(require("./routes/parallel-scrape")); const schedule_1 = __importDefault(require("./routes/schedule")); const crawler_sandbox_1 = __importDefault(require("./routes/crawler-sandbox")); const version_1 = __importDefault(require("./routes/version")); const public_api_1 = __importDefault(require("./routes/public-api")); const dutchie_az_1 = require("./dutchie-az"); const apiTokenTracker_1 = require("./middleware/apiTokenTracker"); const crawl_scheduler_1 = require("./services/crawl-scheduler"); const wordpressPermissions_1 = require("./middleware/wordpressPermissions"); // Apply WordPress permissions validation first (sets req.apiToken) app.use(wordpressPermissions_1.validateWordPressPermissions); // Apply API tracking middleware globally app.use(apiTokenTracker_1.trackApiUsage); app.use(apiTokenTracker_1.checkRateLimit); app.use('/api/auth', auth_1.default); app.use('/api/dashboard', dashboard_1.default); app.use('/api/stores', stores_1.default); app.use('/api/dispensaries', dispensaries_1.default); app.use('/api/changes', changes_1.default); app.use('/api/categories', categories_1.default); app.use('/api/products', products_1.default); app.use('/api/campaigns', campaigns_1.default); app.use('/api/analytics', analytics_1.default); app.use('/api/settings', settings_1.default); app.use('/api/proxies', proxies_1.default); app.use('/api/logs', logs_1.default); app.use('/api/scraper-monitor', scraper_monitor_1.default); app.use('/api/api-tokens', api_tokens_1.default); app.use('/api/api-permissions', api_permissions_1.default); app.use('/api/parallel-scrape', parallel_scrape_1.default); app.use('/api/schedule', schedule_1.default); app.use('/api/crawler-sandbox', crawler_sandbox_1.default); app.use('/api/version', version_1.default); // Vendor-agnostic AZ data pipeline routes (new public surface) app.use('/api/az', dutchie_az_1.dutchieAZRouter); // Legacy alias (kept temporarily for backward compatibility) app.use('/api/dutchie-az', dutchie_az_1.dutchieAZRouter); // Public API v1 - External consumer endpoints (WordPress, etc.) // Uses dutchie_az data pipeline with per-dispensary API key auth app.use('/api/v1', public_api_1.default); async function startServer() { try { logger_1.logger.info('system', 'Starting server...'); await (0, minio_1.initializeMinio)(); await (0, image_storage_1.initializeImageStorage)(); logger_1.logger.info('system', (0, minio_1.isMinioEnabled)() ? 'MinIO storage initialized' : 'Local filesystem storage initialized'); // Clean up any orphaned proxy test jobs from previous server runs await (0, proxyTestQueue_1.cleanupOrphanedJobs)(); // Start the crawl scheduler (checks every minute for jobs to run) (0, crawl_scheduler_1.startCrawlScheduler)(); logger_1.logger.info('system', 'Crawl scheduler started'); // Start the Dutchie AZ scheduler (enqueues jobs for workers) await (0, dutchie_az_1.initializeDefaultSchedules)(); (0, dutchie_az_1.startScheduler)(); logger_1.logger.info('system', 'Dutchie AZ scheduler started'); app.listen(PORT, () => { logger_1.logger.info('system', `Server running on port ${PORT}`); console.log(`🚀 Server running on port ${PORT}`); }); } catch (error) { logger_1.logger.error('system', `Failed to start server: ${error}`); console.error('Failed to start server:', error); process.exit(1); } } startServer();