UNPKG

@posthog/wizard

Version:

The PostHog wizard helps you to configure your project

325 lines 10.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DjangoProjectType = void 0; exports.getDjangoVersionBucket = getDjangoVersionBucket; exports.getDjangoVersion = getDjangoVersion; exports.getDjangoProjectType = getDjangoProjectType; exports.getDjangoProjectTypeName = getDjangoProjectTypeName; exports.findDjangoSettingsFile = findDjangoSettingsFile; exports.findDjangoUrlsFile = findDjangoUrlsFile; const semver_1 = require("semver"); const fast_glob_1 = __importDefault(require("fast-glob")); const clack_1 = __importDefault(require("../utils/clack")); const fs = __importStar(require("node:fs")); const path = __importStar(require("node:path")); var DjangoProjectType; (function (DjangoProjectType) { DjangoProjectType["STANDARD"] = "standard"; DjangoProjectType["DRF"] = "drf"; DjangoProjectType["WAGTAIL"] = "wagtail"; DjangoProjectType["CHANNELS"] = "channels"; })(DjangoProjectType || (exports.DjangoProjectType = DjangoProjectType = {})); const IGNORE_PATTERNS = [ '**/node_modules/**', '**/dist/**', '**/build/**', '**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**', '**/__pycache__/**', '**/migrations/**', ]; /** * Get Django version bucket for analytics */ function getDjangoVersionBucket(version) { if (!version) { return 'none'; } try { const minVer = (0, semver_1.minVersion)(version); if (!minVer) { return 'invalid'; } const majorVersion = (0, semver_1.major)(minVer); if (majorVersion >= 3) { return `${majorVersion}.x`; } return `<3.0.0`; } catch { return 'unknown'; } } /** * Extract Django version from requirements files or pyproject.toml */ async function getDjangoVersion(options) { const { installDir } = options; // Check requirements files const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'], { cwd: installDir, ignore: IGNORE_PATTERNS, }); for (const reqFile of requirementsFiles) { try { const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8'); // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0) const requirementsMatch = content.match(/[Dd]jango[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/); if (requirementsMatch) { return requirementsMatch[1]; } // Try to extract from pyproject.toml format const pyprojectMatch = content.match(/[Dd]jango["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/); if (pyprojectMatch) { return pyprojectMatch[1]; } } catch { // Skip files that can't be read continue; } } return undefined; } /** * Check if Django REST Framework is installed */ async function hasDRF({ installDir, }) { const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], { cwd: installDir, ignore: IGNORE_PATTERNS, }); for (const reqFile of requirementsFiles) { try { const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8'); if (content.includes('djangorestframework')) { return true; } } catch { continue; } } // Also check INSTALLED_APPS in settings const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', { cwd: installDir, ignore: IGNORE_PATTERNS, }); for (const settingsFile of settingsFiles) { try { const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8'); if (content.includes('rest_framework')) { return true; } } catch { continue; } } return false; } /** * Check if Wagtail is installed */ async function hasWagtail({ installDir, }) { const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], { cwd: installDir, ignore: IGNORE_PATTERNS, }); for (const reqFile of requirementsFiles) { try { const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8'); if (content.includes('wagtail')) { return true; } } catch { continue; } } return false; } /** * Check if Django Channels is installed */ async function hasChannels({ installDir, }) { const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], { cwd: installDir, ignore: IGNORE_PATTERNS, }); for (const reqFile of requirementsFiles) { try { const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8'); if (content.includes('channels')) { return true; } } catch { continue; } } return false; } /** * Detect Django project type */ async function getDjangoProjectType(options) { const { installDir } = options; // Check for Wagtail first (CMS) if (await hasWagtail({ installDir })) { clack_1.default.log.info('Detected Django with Wagtail CMS'); return DjangoProjectType.WAGTAIL; } // Check for Django REST Framework if (await hasDRF({ installDir })) { clack_1.default.log.info('Detected Django REST Framework project'); return DjangoProjectType.DRF; } // Check for Django Channels if (await hasChannels({ installDir })) { clack_1.default.log.info('Detected Django Channels project'); return DjangoProjectType.CHANNELS; } // Default to standard Django clack_1.default.log.info('Detected standard Django project'); return DjangoProjectType.STANDARD; } /** * Get human-readable name for Django project type */ function getDjangoProjectTypeName(projectType) { switch (projectType) { case DjangoProjectType.STANDARD: return 'Standard Django'; case DjangoProjectType.DRF: return 'Django REST Framework'; case DjangoProjectType.WAGTAIL: return 'Wagtail CMS'; case DjangoProjectType.CHANNELS: return 'Django Channels'; } } /** * Find the main Django settings file */ async function findDjangoSettingsFile(options) { const { installDir } = options; // Look for settings.py files const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', { cwd: installDir, ignore: IGNORE_PATTERNS, }); if (settingsFiles.length === 0) { // Try settings/__init__.py for split settings const splitSettingsFiles = await (0, fast_glob_1.default)('**/settings/__init__.py', { cwd: installDir, ignore: IGNORE_PATTERNS, }); if (splitSettingsFiles.length > 0) { return splitSettingsFiles[0]; } return undefined; } // If multiple settings files, prefer the one next to manage.py or in root if (settingsFiles.length === 1) { return settingsFiles[0]; } // Try to find the main settings file by looking for ROOT_URLCONF for (const settingsFile of settingsFiles) { try { const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8'); if (content.includes('ROOT_URLCONF')) { return settingsFile; } } catch { continue; } } // Default to first found return settingsFiles[0]; } /** * Find the main Django urls.py file */ async function findDjangoUrlsFile(options) { const { installDir } = options; // First, try to find the root urls.py referenced in settings const settingsFile = await findDjangoSettingsFile(options); if (settingsFile) { try { const settingsContent = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8'); const urlconfMatch = settingsContent.match(/ROOT_URLCONF\s*=\s*['"]([^'"]+)['"]/); if (urlconfMatch) { const urlconfPath = urlconfMatch[1].replace(/\./g, '/') + '.py'; const fullPath = path.join(installDir, urlconfPath); if (fs.existsSync(fullPath)) { return urlconfPath; } } } catch { // Fall through to glob search } } // Fallback to glob search const urlsFiles = await (0, fast_glob_1.default)('**/urls.py', { cwd: installDir, ignore: [...IGNORE_PATTERNS, '**/admin/**'], }); if (urlsFiles.length === 0) { return undefined; } // Prefer urls.py files that contain urlpatterns for (const urlsFile of urlsFiles) { try { const content = fs.readFileSync(path.join(installDir, urlsFile), 'utf-8'); if (content.includes('urlpatterns')) { return urlsFile; } } catch { continue; } } return urlsFiles[0]; } //# sourceMappingURL=utils.js.map