UNPKG

@posthog/wizard

Version:

The PostHog wizard helps you to configure your project

177 lines 7.28 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GLOBAL_IGNORE_PATTERN = void 0; exports.getAllFilesInProject = getAllFilesInProject; exports.getDotGitignore = getDotGitignore; exports.updateFile = updateFile; exports.getFilesToChange = getFilesToChange; exports.generateFileContent = generateFileContent; exports.generateFileChangesForIntegration = generateFileChangesForIntegration; exports.getRelevantFilesForIntegration = getRelevantFilesForIntegration; const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const clack_1 = __importDefault(require("./clack")); const zod_1 = __importDefault(require("zod")); const query_1 = require("./query"); const fast_glob_1 = __importDefault(require("fast-glob")); const analytics_1 = require("./analytics"); const clack_utils_1 = require("./clack-utils"); const config_1 = require("../lib/config"); const prompts_1 = require("../lib/prompts"); exports.GLOBAL_IGNORE_PATTERN = [ 'node_modules', 'dist', 'build', 'public', 'static', '.git', '.next', ]; async function getAllFilesInProject(dir) { let results = []; const entries = await fs_1.default.promises.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path_1.default.join(dir, entry.name); if (exports.GLOBAL_IGNORE_PATTERN.some((pattern) => fullPath.includes(pattern))) { continue; } if (entry.isDirectory()) { // Recursively get files from subdirectories const subDirFiles = await getAllFilesInProject(fullPath); results = results.concat(subDirFiles); } else { results.push(fullPath); } } return results; } function getDotGitignore({ installDir, }) { const gitignorePath = path_1.default.join(installDir, '.gitignore'); const gitignoreExists = fs_1.default.existsSync(gitignorePath); if (gitignoreExists) { return gitignorePath; } return undefined; } async function updateFile(change, { installDir }) { const dir = path_1.default.dirname(path_1.default.join(installDir, change.filePath)); await fs_1.default.promises.mkdir(dir, { recursive: true }); await fs_1.default.promises.writeFile(path_1.default.join(installDir, change.filePath), change.newContent); } async function getFilesToChange({ integration, relevantFiles, documentation, wizardHash, cloudRegion, }) { const filterFilesSpinner = clack_1.default.spinner(); filterFilesSpinner.start('Selecting files to change...'); const filterFilesResponseSchmea = zod_1.default.object({ files: zod_1.default.array(zod_1.default.string()), }); const prompt = await prompts_1.baseFilterFilesPromptTemplate.format({ documentation, file_list: relevantFiles.join('\n'), integration_name: integration, integration_rules: config_1.INTEGRATION_CONFIG[integration].filterFilesRules, }); const filterFilesResponse = await (0, query_1.query)({ message: prompt, schema: filterFilesResponseSchmea, wizardHash, region: cloudRegion, }); const filesToChange = filterFilesResponse.files; filterFilesSpinner.stop(`Found ${filesToChange.length} files to change`); analytics_1.analytics.capture('wizard interaction', { action: 'detected files to change', integration, files: filesToChange, }); return filesToChange; } async function generateFileContent({ prompt, wizardHash, cloudRegion, }) { const response = await (0, query_1.query)({ message: prompt, schema: zod_1.default.object({ newContent: zod_1.default.string(), }), wizardHash: wizardHash, region: cloudRegion, }); return response.newContent; } async function generateFileChangesForIntegration({ integration, filesToChange, wizardHash, documentation, installDir, cloudRegion, }) { const changes = []; for (const filePath of filesToChange) { const fileChangeSpinner = clack_1.default.spinner(); analytics_1.analytics.capture('wizard interaction', { action: 'processing file', integration, file: filePath, }); try { let oldContent = undefined; try { oldContent = await fs_1.default.promises.readFile(path_1.default.join(installDir, filePath), 'utf8'); } catch (readError) { if (readError.code !== 'ENOENT') { await (0, clack_utils_1.abort)(`Error reading file ${filePath}`); continue; } } fileChangeSpinner.start(`${oldContent ? 'Updating' : 'Creating'} file ${filePath}`); const unchangedFiles = filesToChange.filter((filePath) => !changes.some((change) => change.filePath === filePath)); const prompt = await prompts_1.baseGenerateFileChangesPromptTemplate.format({ file_content: oldContent, file_path: filePath, documentation, integration_name: config_1.INTEGRATION_CONFIG[integration].name, integration_rules: config_1.INTEGRATION_CONFIG[integration].generateFilesRules, changed_files: changes .map((change) => `${change.filePath}\n${change.newContent}`) .join('\n'), unchanged_files: unchangedFiles, }); const newContent = await generateFileContent({ prompt, wizardHash, cloudRegion, }); if (newContent !== oldContent) { await updateFile({ filePath, oldContent, newContent }, { installDir }); changes.push({ filePath, oldContent, newContent }); } fileChangeSpinner.stop(`${oldContent ? 'Updated' : 'Created'} file ${filePath}`); analytics_1.analytics.capture('wizard interaction', { action: 'processed file', integration, file: filePath, }); } catch (error) { await (0, clack_utils_1.abort)(`Error processing file ${filePath}`); } } analytics_1.analytics.capture('wizard interaction', { action: 'completed file changes', integration, files: filesToChange, }); return changes; } async function getRelevantFilesForIntegration({ installDir, integration, }) { const filterPatterns = config_1.INTEGRATION_CONFIG[integration].filterPatterns; const ignorePatterns = config_1.INTEGRATION_CONFIG[integration].ignorePatterns; const filteredFiles = await (0, fast_glob_1.default)(filterPatterns, { cwd: installDir, ignore: ignorePatterns, }); analytics_1.analytics.capture('wizard interaction', { action: 'detected relevant files', integration, number_of_files: filteredFiles.length, }); return filteredFiles; } //# sourceMappingURL=file-utils.js.map