UNPKG

qraft

Version:

A powerful CLI tool to qraft structured project setups from GitHub template repositories

265 lines • 13.4 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.MetadataPrompter = void 0; const chalk_1 = __importDefault(require("chalk")); const readline = __importStar(require("readline")); class MetadataPrompter { constructor() { this.rl = readline.createInterface({ input: process.stdin, output: process.stdout }); } async promptForMetadata(detectedDefaults, options = {}) { const { interactive = true, skipOptional = false, acceptDefaults = false } = options; if (!interactive || acceptDefaults) { return this.useDefaults(detectedDefaults); } console.log(chalk_1.default.cyan('\nšŸ”§ Interactive Metadata Configuration')); console.log(chalk_1.default.gray('Press Enter to accept defaults, or type new values\n')); const metadata = {}; const userModified = []; const skipped = []; try { // Required fields metadata.name = await this.promptField('Box Name', detectedDefaults.name, true, 'A unique name for your box (e.g., react-typescript-starter)'); if (metadata.name !== detectedDefaults.name) userModified.push('name'); metadata.description = await this.promptField('Description', detectedDefaults.description, false, 'Brief description of what this box provides'); if (metadata.description !== detectedDefaults.description) userModified.push('description'); metadata.language = await this.promptField('Primary Language', detectedDefaults.language, true, 'Main programming language (e.g., TypeScript, JavaScript, Python)'); if (metadata.language !== detectedDefaults.language) userModified.push('language'); // Framework (optional but important) if (detectedDefaults.framework && detectedDefaults.framework !== 'none') { metadata.framework = await this.promptField('Framework', detectedDefaults.framework, false, 'Framework or library used (e.g., React, Vue, Express)'); if (metadata.framework !== detectedDefaults.framework) userModified.push('framework'); } // Tags const defaultTags = detectedDefaults.tags?.join(', ') || ''; const tagsInput = await this.promptField('Tags', defaultTags, false, 'Comma-separated tags (e.g., frontend, typescript, react)'); if (tagsInput) { metadata.tags = tagsInput.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0); if (JSON.stringify(metadata.tags) !== JSON.stringify(detectedDefaults.tags)) { userModified.push('tags'); } } // Optional fields (only if not skipping) if (!skipOptional) { console.log(chalk_1.default.yellow('\nšŸ“‹ Optional Information (press Enter to skip)')); metadata.version = await this.promptField('Version', detectedDefaults.version || '1.0.0', false, 'Semantic version (e.g., 1.0.0)'); if (metadata.version !== (detectedDefaults.version || '1.0.0')) userModified.push('version'); metadata.author = await this.promptField('Author', detectedDefaults.author, false, 'Author name or organization'); if (metadata.author !== detectedDefaults.author) userModified.push('author'); metadata.license = await this.promptField('License', detectedDefaults.license || 'MIT', false, 'License type (e.g., MIT, Apache-2.0, GPL-3.0)'); if (metadata.license !== (detectedDefaults.license || 'MIT')) userModified.push('license'); metadata.repository = await this.promptField('Repository URL', detectedDefaults.repository, false, 'Git repository URL (e.g., https://github.com/user/repo)'); if (metadata.repository !== detectedDefaults.repository) userModified.push('repository'); metadata.homepage = await this.promptField('Homepage URL', detectedDefaults.homepage, false, 'Project homepage or documentation URL'); if (metadata.homepage !== detectedDefaults.homepage) userModified.push('homepage'); const keywordsInput = await this.promptField('Keywords', detectedDefaults.keywords?.join(', ') || '', false, 'Search keywords (comma-separated)'); if (keywordsInput) { metadata.keywords = keywordsInput.split(',').map(kw => kw.trim()).filter(kw => kw.length > 0); if (JSON.stringify(metadata.keywords) !== JSON.stringify(detectedDefaults.keywords)) { userModified.push('keywords'); } } const isPrivate = await this.promptBoolean('Private Box', false, 'Should this box be private? (y/N)'); metadata.private = isPrivate; if (isPrivate) userModified.push('private'); } return { metadata, userModified, skipped }; } finally { this.close(); } } async promptField(label, defaultValue, required = false, hint) { const displayDefault = defaultValue ? chalk_1.default.gray(`(${defaultValue})`) : ''; const requiredMark = required ? chalk_1.default.red('*') : ''; const hintText = hint ? chalk_1.default.gray(`\n ${hint}`) : ''; while (true) { const answer = await this.question(`${chalk_1.default.cyan(label)}${requiredMark} ${displayDefault}: ${hintText}\n> `); const value = answer.trim() || defaultValue || ''; if (required && !value) { console.log(chalk_1.default.red(`āŒ ${label} is required`)); continue; } return value; } } async promptBoolean(label, defaultValue, prompt) { const answer = await this.question(`${chalk_1.default.cyan(label)} ${prompt}: `); const input = answer.trim().toLowerCase(); if (!input) return defaultValue; return input === 'y' || input === 'yes' || input === 'true'; } question(prompt) { return new Promise((resolve) => { this.rl.question(prompt, (answer) => { resolve(answer); }); }); } useDefaults(detectedDefaults) { const metadata = { name: detectedDefaults.name, description: detectedDefaults.description, language: detectedDefaults.language, framework: detectedDefaults.framework !== 'none' ? detectedDefaults.framework : undefined, tags: detectedDefaults.tags, version: detectedDefaults.version || '1.0.0', author: detectedDefaults.author, license: detectedDefaults.license || 'MIT', repository: detectedDefaults.repository, homepage: detectedDefaults.homepage, keywords: detectedDefaults.keywords, private: false }; return { metadata, userModified: [], skipped: [] }; } async confirmMetadata(metadata) { console.log(chalk_1.default.cyan('\nšŸ“‹ Metadata Summary:')); console.log(chalk_1.default.gray('─'.repeat(50))); if (metadata.name) console.log(`${chalk_1.default.yellow('Name:')} ${metadata.name}`); if (metadata.description) console.log(`${chalk_1.default.yellow('Description:')} ${metadata.description}`); if (metadata.language) console.log(`${chalk_1.default.yellow('Language:')} ${metadata.language}`); if (metadata.framework) console.log(`${chalk_1.default.yellow('Framework:')} ${metadata.framework}`); if (metadata.tags?.length) console.log(`${chalk_1.default.yellow('Tags:')} ${metadata.tags.join(', ')}`); if (metadata.version) console.log(`${chalk_1.default.yellow('Version:')} ${metadata.version}`); if (metadata.author) console.log(`${chalk_1.default.yellow('Author:')} ${metadata.author}`); if (metadata.license) console.log(`${chalk_1.default.yellow('License:')} ${metadata.license}`); if (metadata.repository) console.log(`${chalk_1.default.yellow('Repository:')} ${metadata.repository}`); if (metadata.homepage) console.log(`${chalk_1.default.yellow('Homepage:')} ${metadata.homepage}`); if (metadata.keywords?.length) console.log(`${chalk_1.default.yellow('Keywords:')} ${metadata.keywords.join(', ')}`); if (metadata.private) console.log(`${chalk_1.default.yellow('Private:')} Yes`); console.log(chalk_1.default.gray('─'.repeat(50))); const answer = await this.question(chalk_1.default.white('Does this look correct? (Y/n): ')); const confirmed = !answer.trim() || answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes'; this.close(); return confirmed; } close() { this.rl.close(); } // Validate metadata fields static validateMetadata(metadata) { const errors = []; // Required fields if (!metadata.name || metadata.name.trim().length === 0) { errors.push('Box name is required'); } else if (!/^[a-z0-9-_]+$/i.test(metadata.name)) { errors.push('Box name can only contain letters, numbers, hyphens, and underscores'); } if (!metadata.language || metadata.language.trim().length === 0) { errors.push('Primary language is required'); } // Optional field validation if (metadata.version && !/^\d+\.\d+\.\d+/.test(metadata.version)) { errors.push('Version should follow semantic versioning (e.g., 1.0.0)'); } if (metadata.repository && !metadata.repository.startsWith('http')) { errors.push('Repository URL should start with http:// or https://'); } if (metadata.homepage && !metadata.homepage.startsWith('http')) { errors.push('Homepage URL should start with http:// or https://'); } if (metadata.tags && metadata.tags.length > 20) { errors.push('Maximum 20 tags allowed'); } if (metadata.keywords && metadata.keywords.length > 50) { errors.push('Maximum 50 keywords allowed'); } return { valid: errors.length === 0, errors }; } // Generate metadata suggestions based on detected defaults static generateSuggestions(detectedDefaults) { const suggestions = []; if (detectedDefaults.hasTests) { suggestions.push('Consider adding "testing" to your tags'); } if (detectedDefaults.hasDocs) { suggestions.push('Consider adding "documentation" to your tags'); } if (detectedDefaults.packageManager) { suggestions.push(`Detected ${detectedDefaults.packageManager} - consider adding to keywords`); } if (detectedDefaults.framework && detectedDefaults.framework !== 'none') { suggestions.push(`Framework detected: ${detectedDefaults.framework} - ensure it's in your tags`); } if (!detectedDefaults.description) { suggestions.push('Consider adding a description to help users understand your box'); } if (!detectedDefaults.license) { suggestions.push('Consider specifying a license (MIT is common for open source)'); } return suggestions; } } exports.MetadataPrompter = MetadataPrompter; //# sourceMappingURL=metadataPrompts.js.map