@posthog/wizard
Version:
The PostHog wizard helps you to configure your project
325 lines • 10.9 kB
JavaScript
"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