create-vextro 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -172,7 +172,7 @@ var ExtensionGenerator = class {
|
|
|
172
172
|
const s = spinner("Creating base Vite + React + TS project...");
|
|
173
173
|
s.start();
|
|
174
174
|
try {
|
|
175
|
-
execSync(`npm create
|
|
175
|
+
execSync(`npm exec --yes -- create-vite@latest ${this.config.name} --template react-ts`, {
|
|
176
176
|
cwd: path2.dirname(this.config.targetDir),
|
|
177
177
|
stdio: "pipe",
|
|
178
178
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -424,7 +424,7 @@ async function handleCreate(projectName, options) {
|
|
|
424
424
|
// package.json
|
|
425
425
|
var package_default = {
|
|
426
426
|
name: "create-vextro",
|
|
427
|
-
version: "0.1.
|
|
427
|
+
version: "0.1.2",
|
|
428
428
|
description: "Scaffold modern browser extensions (Chrome, Edge, Firefox) with Vite + React + Tailwind",
|
|
429
429
|
type: "module",
|
|
430
430
|
bin: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/index.ts","../src/constants.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/validator.ts","../src/generators/extension.ts","../package.json","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createCommand } from './commands/create.js';\nimport { setVerbose } from './utils/logger.js';\nimport pkg from '../package.json' with { type: 'json' };\n\nconst CLI_VERSION = pkg.version || '0.1.0';\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name('create-vextro')\n .description('Scaffold modern browser extensions with Vite + React + Tailwind')\n .version(CLI_VERSION)\n .option('--verbose', 'Enable verbose output')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.verbose) {\n setVerbose(true);\n }\n });\n\n program.addCommand(createCommand(), { isDefault: true });\n\n return program;\n}\n","import { Command } from 'commander';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { promptProjectName, promptBrowser } from '../prompts/index.js';\nimport { ExtensionGenerator } from '../generators/extension.js';\nimport {\n validateProjectName,\n validateDirectory,\n error,\n success,\n newLine,\n banner,\n} from '../utils/index.js';\nimport { BROWSERS } from '../constants.js';\nimport type { CreateOptions, ProjectConfig, BrowserTarget } from '../types/index.js';\n\nexport function createCommand(): Command {\n const cmd = new Command('create')\n .description('Create a new browser extension project')\n .argument('[project-name]', 'Name of the extension project')\n .option('--chrome', 'Target Chrome / Edge (default)')\n .option('--firefox', 'Target Firefox')\n .option('--force', 'Overwrite existing directory')\n .action(async (projectName: string | undefined, options: CreateOptions) => {\n try {\n await handleCreate(projectName, options);\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n return cmd;\n}\n\nfunction resolveBrowserFromFlags(options: CreateOptions): BrowserTarget | null {\n if (options.chrome) return 'chrome';\n if (options.firefox) return 'firefox';\n return null;\n}\n\nasync function handleCreate(\n projectName: string | undefined,\n options: CreateOptions,\n): Promise<void> {\n // If no project name given as arg, prompt for it\n if (!projectName) {\n projectName = await promptProjectName();\n }\n\n // Validate the project name\n const nameValidation = validateProjectName(projectName);\n if (nameValidation !== true) {\n throw new Error(nameValidation);\n }\n\n // Resolve browser target\n let browser = resolveBrowserFromFlags(options);\n if (!browser) {\n browser = await promptBrowser();\n }\n\n const targetDir = path.resolve(process.cwd(), projectName);\n\n // Check if directory already exists\n if (!options.force) {\n const dirValidation = await validateDirectory(targetDir);\n if (dirValidation !== true) {\n throw new Error(dirValidation);\n }\n } else if (await fs.pathExists(targetDir)) {\n await fs.remove(targetDir);\n }\n\n const config: ProjectConfig = {\n name: projectName,\n targetDir,\n browser,\n };\n\n const browserMeta = BROWSERS[browser];\n\n newLine();\n banner(`🚀 Creating Vextro Extension for ${browserMeta.displayName} — \"${config.name}\"...`);\n newLine();\n\n // Handle SIGINT — clean up partial directory\n const cleanup = async () => {\n newLine();\n error('Interrupted! Cleaning up...');\n try {\n if (await fs.pathExists(targetDir)) {\n await fs.remove(targetDir);\n }\n } catch {\n // best-effort cleanup\n }\n process.exit(1);\n };\n process.on('SIGINT', cleanup);\n\n const generator = new ExtensionGenerator(config);\n await generator.generate();\n\n // Remove SIGINT handler after success\n process.removeListener('SIGINT', cleanup);\n\n newLine();\n success(\n `Vextro project \"${config.name}\" created successfully for ${browserMeta.displayName}! 🎉`,\n );\n newLine();\n console.log('Next steps:');\n console.log(` cd ${config.name}`);\n console.log(' npm run dev');\n newLine();\n\n if (browser === 'chrome') {\n console.log('Load extension:');\n console.log(' 1. Open chrome://extensions (or edge://extensions)');\n console.log(' 2. Enable \"Developer mode\"');\n console.log(' 3. Click \"Load unpacked\" → select the dist/ folder');\n } else if (browser === 'firefox') {\n console.log('Load extension:');\n console.log(' 1. Open about:debugging#/runtime/this-firefox');\n console.log(' 2. Click \"Load Temporary Add-on\"');\n console.log(' 3. Select any file in the dist/ folder');\n }\n\n newLine();\n console.log('Happy coding! 🚀');\n newLine();\n}\n","import inquirer from 'inquirer';\nimport { DEFAULT_PROJECT_NAME, BROWSERS } from '../constants.js';\nimport { validateProjectName } from '../utils/index.js';\nimport type { BrowserTarget } from '../types/index.js';\n\nexport async function promptProjectName(): Promise<string> {\n const { projectName } = await inquirer.prompt([\n {\n name: 'projectName',\n message: 'Enter your extension project name:',\n default: DEFAULT_PROJECT_NAME,\n validate: (input: string) => {\n const result = validateProjectName(input);\n return result === true ? true : result;\n },\n },\n ]);\n return projectName;\n}\n\nexport async function promptBrowser(): Promise<BrowserTarget> {\n const { browser } = await inquirer.prompt([\n {\n type: 'list',\n name: 'browser',\n message: 'Select target browser:',\n choices: Object.entries(BROWSERS).map(([value, meta]) => ({\n name: `${meta.displayName} — ${meta.description}`,\n value,\n })),\n default: 'chrome',\n },\n ]);\n return browser;\n}\n","import type { BrowserTarget } from './types/index.js';\n\nexport const PACKAGE_NAME = 'create-vextro';\nexport const BRAND_NAME = 'Vextro';\n\nexport const VALID_PROJECT_NAME = /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\nexport const DEFAULT_PROJECT_NAME = 'my-extension';\nexport const DEFAULT_BROWSER: BrowserTarget = 'chrome';\n\nexport const FILES_TO_REMOVE = [\n 'src/App.tsx',\n 'src/main.tsx',\n 'src/index.css',\n 'src/App.css',\n 'src/assets',\n 'index.html',\n];\n\nexport const BROWSERS: Record<BrowserTarget, { displayName: string; description: string }> = {\n chrome: {\n displayName: 'Chrome / Edge',\n description: 'Google Chrome & Microsoft Edge (Chromium-based, uses CRXJS)',\n },\n firefox: {\n displayName: 'Firefox',\n description: 'Mozilla Firefox (uses vite-plugin-web-extension)',\n },\n};\n\nexport const CHROME_DEV_DEPS = [\n '@types/chrome',\n '@types/node',\n '@crxjs/vite-plugin',\n 'tailwindcss',\n '@tailwindcss/vite',\n];\n\nexport const FIREFOX_DEV_DEPS = [\n '@types/chrome',\n '@types/node',\n 'vite-plugin-web-extension',\n 'tailwindcss',\n '@tailwindcss/vite',\n];\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\n\nlet verbose = false;\n\nexport function setVerbose(value: boolean): void {\n verbose = value;\n}\n\nexport function info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n}\n\nexport function success(message: string): void {\n console.log(chalk.green('✔'), message);\n}\n\nexport function warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n}\n\nexport function error(message: string): void {\n console.log(chalk.red('✖'), message);\n}\n\nexport function debug(message: string): void {\n if (verbose) {\n console.log(chalk.gray('⬥'), chalk.gray(message));\n }\n}\n\nexport function spinner(text: string): Ora {\n return ora({ text, color: 'cyan' });\n}\n\nexport function newLine(): void {\n console.log();\n}\n\nexport function banner(text: string): void {\n console.log(chalk.bold.cyan(text));\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport function getTemplatesDir(): string {\n // When bundled with tsup, __dirname is dist/ → go up 1 level to project root\n // When running unbundled (vitest), __dirname is src/utils/ → go up 2 levels to project root\n const isBundled =\n __dirname.replace(/\\\\/g, '/').endsWith('/dist') ||\n __dirname.replace(/\\\\/g, '/').includes('/dist/');\n const projectRoot = isBundled\n ? path.resolve(__dirname, '..')\n : path.resolve(__dirname, '..', '..');\n return path.resolve(projectRoot, 'src', 'templates');\n}\n\nexport async function createDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(dirPath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n","import { VALID_PROJECT_NAME } from '../constants.js';\nimport { directoryExists } from './file.js';\n\nexport function validateProjectName(name: string): string | true {\n if (!name || name.trim().length === 0) {\n return 'Project name is required.';\n }\n\n if (!VALID_PROJECT_NAME.test(name)) {\n return 'Project name must be a valid npm package name (lowercase, no spaces, can use hyphens and dots).';\n }\n\n if (name.length > 214) {\n return 'Project name must be less than 214 characters.';\n }\n\n return true;\n}\n\nexport async function validateDirectory(dirPath: string): Promise<string | true> {\n if (await directoryExists(dirPath)) {\n return `Directory \"${dirPath}\" already exists. Use --force to overwrite.`;\n }\n return true;\n}\n\nexport function checkNodeVersion(minMajor: number = 20): string | true {\n const version = process.version;\n const major = parseInt(version.slice(1).split('.')[0], 10);\n\n if (major < minMajor) {\n return `Node.js ${minMajor}+ is required. You are using ${version}.`;\n }\n\n return true;\n}\n","import path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport fs from 'fs-extra';\nimport { getTemplatesDir, spinner, success, debug } from '../utils/index.js';\nimport { FILES_TO_REMOVE, CHROME_DEV_DEPS, FIREFOX_DEV_DEPS } from '../constants.js';\nimport type { ProjectConfig } from '../types/index.js';\n\nexport class ExtensionGenerator {\n private config: ProjectConfig;\n private templatesDir: string;\n\n constructor(config: ProjectConfig) {\n this.config = config;\n this.templatesDir = getTemplatesDir();\n }\n\n async generate(): Promise<void> {\n await this.scaffoldVite();\n await this.installBaseDeps();\n await this.cleanViteDefaults();\n await this.copySharedFiles();\n await this.copyBrowserFiles();\n await this.overrideConfigs();\n await this.patchTsConfig();\n await this.injectProjectName();\n await this.installExtensionDeps();\n }\n\n private async scaffoldVite(): Promise<void> {\n const s = spinner('Creating base Vite + React + TS project...');\n s.start();\n try {\n execSync(`npm create vite@latest ${this.config.name} -- --template react-ts`, {\n cwd: path.dirname(this.config.targetDir),\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success('Created base Vite + React + TS project');\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to scaffold Vite project: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private async installBaseDeps(): Promise<void> {\n const s = spinner('Installing base dependencies...');\n s.start();\n try {\n execSync('npm install', {\n cwd: this.config.targetDir,\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success('Installed base dependencies');\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to install dependencies: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private async cleanViteDefaults(): Promise<void> {\n const s = spinner('Removing default Vite template files...');\n s.start();\n\n for (const file of FILES_TO_REMOVE) {\n const fullPath = path.join(this.config.targetDir, file);\n if (await fs.pathExists(fullPath)) {\n await fs.remove(fullPath);\n debug(`Removed: ${file}`);\n }\n }\n\n const publicPath = path.join(this.config.targetDir, 'public');\n if (await fs.pathExists(publicPath)) {\n await fs.emptyDir(publicPath);\n }\n\n s.stop();\n success('Cleaned default Vite template files');\n }\n\n private async copySharedFiles(): Promise<void> {\n const s = spinner('Copying shared extension files...');\n s.start();\n\n const sharedDir = path.join(this.templatesDir, 'shared');\n\n // Copy shared src files (popup, options, utils, styles)\n const sharedSrcDir = path.join(sharedDir, 'src');\n if (await fs.pathExists(sharedSrcDir)) {\n await fs.copy(sharedSrcDir, path.join(this.config.targetDir, 'src'));\n }\n\n // Copy shared public files (icons)\n const sharedPublicDir = path.join(sharedDir, 'public');\n if (await fs.pathExists(sharedPublicDir)) {\n await fs.copy(sharedPublicDir, path.join(this.config.targetDir, 'public'));\n }\n\n s.stop();\n success('Copied shared extension files');\n }\n\n private async copyBrowserFiles(): Promise<void> {\n const s = spinner(`Copying ${this.config.browser} browser files...`);\n s.start();\n\n const browserDir = path.join(this.templatesDir, this.config.browser);\n\n // Copy browser-specific src files (manifest, background, content)\n const browserSrcDir = path.join(browserDir, 'src');\n if (await fs.pathExists(browserSrcDir)) {\n await fs.copy(browserSrcDir, path.join(this.config.targetDir, 'src'), {\n overwrite: true,\n });\n }\n\n s.stop();\n success(`Copied ${this.config.browser} browser files`);\n }\n\n private async overrideConfigs(): Promise<void> {\n const s = spinner('Overriding config files...');\n s.start();\n\n const browserDir = path.join(this.templatesDir, this.config.browser);\n const viteConfigFrom = path.join(browserDir, 'vite.config.ts');\n const viteConfigTo = path.join(this.config.targetDir, 'vite.config.ts');\n\n if (await fs.pathExists(viteConfigFrom)) {\n await fs.copy(viteConfigFrom, viteConfigTo, { overwrite: true });\n debug('Overrode: vite.config.ts');\n }\n\n s.stop();\n success('Overrode config files');\n }\n\n private async patchTsConfig(): Promise<void> {\n const s = spinner('Patching tsconfig for extension types...');\n s.start();\n\n const tsconfigAppPath = path.join(this.config.targetDir, 'tsconfig.app.json');\n\n if (await fs.pathExists(tsconfigAppPath)) {\n let content = await fs.readFile(tsconfigAppPath, 'utf-8');\n\n // Both Chrome and Firefox use @types/chrome (Firefox MV3 supports chrome.* namespace)\n const typeToAdd = 'chrome';\n\n // Inject the type into the \"types\" array using string replacement\n // This preserves comments and formatting in the JSONC file\n content = content.replace(\n /(\"types\"\\s*:\\s*\\[)([\\s\\S]*?)(\\])/,\n (match, prefix, existing, suffix) => {\n const trimmed = existing.trim();\n if (trimmed.includes(`\"${typeToAdd}\"`)) return match; // already present\n if (trimmed.length === 0) {\n return `${prefix}\"${typeToAdd}\"${suffix}`;\n }\n return `${prefix}${existing.trimEnd()}, \"${typeToAdd}\"${suffix}`;\n },\n );\n\n await fs.writeFile(tsconfigAppPath, content, 'utf-8');\n debug(`Patched tsconfig.app.json with type: ${typeToAdd}`);\n }\n\n s.stop();\n success('Patched tsconfig for extension types');\n }\n\n private async injectProjectName(): Promise<void> {\n const s = spinner('Injecting project name...');\n s.start();\n\n if (this.config.browser === 'chrome') {\n // Chrome uses manifest.ts\n const manifestPath = path.join(this.config.targetDir, 'src', 'manifest.ts');\n if (await fs.pathExists(manifestPath)) {\n let manifest = await fs.readFile(manifestPath, 'utf-8');\n manifest = manifest.replace(/__EXT_NAME__/g, this.config.name);\n await fs.writeFile(manifestPath, manifest, 'utf-8');\n }\n } else if (this.config.browser === 'firefox') {\n // Firefox uses manifest.json\n const manifestPath = path.join(this.config.targetDir, 'src', 'manifest.json');\n if (await fs.pathExists(manifestPath)) {\n let manifest = await fs.readFile(manifestPath, 'utf-8');\n manifest = manifest.replace(/__EXT_NAME__/g, this.config.name);\n await fs.writeFile(manifestPath, manifest, 'utf-8');\n }\n }\n\n // Update package.json name\n const pkgPath = path.join(this.config.targetDir, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n let pkg = await fs.readFile(pkgPath, 'utf-8');\n pkg = pkg.replace(/\"__EXT_NAME__\"/g, `\"${this.config.name}\"`);\n await fs.writeFile(pkgPath, pkg, 'utf-8');\n }\n\n s.stop();\n success('Injected project name');\n }\n\n private async installExtensionDeps(): Promise<void> {\n const deps = this.config.browser === 'firefox' ? FIREFOX_DEV_DEPS : CHROME_DEV_DEPS;\n\n const s = spinner(`Installing ${this.config.browser} extension dev dependencies...`);\n s.start();\n try {\n execSync(`npm install --save-dev ${deps.join(' ')}`, {\n cwd: this.config.targetDir,\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success(`Installed ${this.config.browser} extension dev dependencies`);\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to install extension dependencies: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n","{\n \"name\": \"create-vextro\",\n \"version\": \"0.1.1\",\n \"description\": \"Scaffold modern browser extensions (Chrome, Edge, Firefox) with Vite + React + Tailwind\",\n \"type\": \"module\",\n \"bin\": {\n \"create-vextro\": \"./dist/index.js\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src/\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"prepublishOnly\": \"npm run build && npm test\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"fs-extra\": \"^11.2.0\",\n \"inquirer\": \"^9.2.8\",\n \"ora\": \"^8.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^20.0.0\",\n \"eslint\": \"^9.0.0\",\n \"prettier\": \"^3.3.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.5.0\",\n \"typescript-eslint\": \"^8.0.0\",\n \"vitest\": \"^2.0.0\"\n },\n \"files\": [\n \"dist\",\n \"src/templates\"\n ],\n \"keywords\": [\n \"vite\",\n \"chrome-extension\",\n \"firefox-extension\",\n \"browser-extension\",\n \"vite-plugin\",\n \"react\",\n \"tailwind\",\n \"crxjs\",\n \"manifest-v3\",\n \"scaffold\",\n \"cli\",\n \"generator\",\n \"starter-kit\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/CodeCanvasCollective/vextro.git\"\n },\n \"author\": \"Lasantha <lasanthaslakmal@gmail.com>\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/CodeCanvasCollective/vextro/issues\"\n },\n \"homepage\": \"https://github.com/CodeCanvasCollective/vextro#readme\"\n}\n","import { createCli } from './cli.js';\n\nconst program = createCli();\nprogram.parse();\n"],"mappings":"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","names":["Command","path","fs","__filename","__dirname","path","fs","path","fs","path","fs","program","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/index.ts","../src/constants.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/validator.ts","../src/generators/extension.ts","../package.json","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createCommand } from './commands/create.js';\nimport { setVerbose } from './utils/logger.js';\nimport pkg from '../package.json' with { type: 'json' };\n\nconst CLI_VERSION = pkg.version || '0.1.0';\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name('create-vextro')\n .description('Scaffold modern browser extensions with Vite + React + Tailwind')\n .version(CLI_VERSION)\n .option('--verbose', 'Enable verbose output')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.verbose) {\n setVerbose(true);\n }\n });\n\n program.addCommand(createCommand(), { isDefault: true });\n\n return program;\n}\n","import { Command } from 'commander';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { promptProjectName, promptBrowser } from '../prompts/index.js';\nimport { ExtensionGenerator } from '../generators/extension.js';\nimport {\n validateProjectName,\n validateDirectory,\n error,\n success,\n newLine,\n banner,\n} from '../utils/index.js';\nimport { BROWSERS } from '../constants.js';\nimport type { CreateOptions, ProjectConfig, BrowserTarget } from '../types/index.js';\n\nexport function createCommand(): Command {\n const cmd = new Command('create')\n .description('Create a new browser extension project')\n .argument('[project-name]', 'Name of the extension project')\n .option('--chrome', 'Target Chrome / Edge (default)')\n .option('--firefox', 'Target Firefox')\n .option('--force', 'Overwrite existing directory')\n .action(async (projectName: string | undefined, options: CreateOptions) => {\n try {\n await handleCreate(projectName, options);\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n return cmd;\n}\n\nfunction resolveBrowserFromFlags(options: CreateOptions): BrowserTarget | null {\n if (options.chrome) return 'chrome';\n if (options.firefox) return 'firefox';\n return null;\n}\n\nasync function handleCreate(\n projectName: string | undefined,\n options: CreateOptions,\n): Promise<void> {\n // If no project name given as arg, prompt for it\n if (!projectName) {\n projectName = await promptProjectName();\n }\n\n // Validate the project name\n const nameValidation = validateProjectName(projectName);\n if (nameValidation !== true) {\n throw new Error(nameValidation);\n }\n\n // Resolve browser target\n let browser = resolveBrowserFromFlags(options);\n if (!browser) {\n browser = await promptBrowser();\n }\n\n const targetDir = path.resolve(process.cwd(), projectName);\n\n // Check if directory already exists\n if (!options.force) {\n const dirValidation = await validateDirectory(targetDir);\n if (dirValidation !== true) {\n throw new Error(dirValidation);\n }\n } else if (await fs.pathExists(targetDir)) {\n await fs.remove(targetDir);\n }\n\n const config: ProjectConfig = {\n name: projectName,\n targetDir,\n browser,\n };\n\n const browserMeta = BROWSERS[browser];\n\n newLine();\n banner(`🚀 Creating Vextro Extension for ${browserMeta.displayName} — \"${config.name}\"...`);\n newLine();\n\n // Handle SIGINT — clean up partial directory\n const cleanup = async () => {\n newLine();\n error('Interrupted! Cleaning up...');\n try {\n if (await fs.pathExists(targetDir)) {\n await fs.remove(targetDir);\n }\n } catch {\n // best-effort cleanup\n }\n process.exit(1);\n };\n process.on('SIGINT', cleanup);\n\n const generator = new ExtensionGenerator(config);\n await generator.generate();\n\n // Remove SIGINT handler after success\n process.removeListener('SIGINT', cleanup);\n\n newLine();\n success(\n `Vextro project \"${config.name}\" created successfully for ${browserMeta.displayName}! 🎉`,\n );\n newLine();\n console.log('Next steps:');\n console.log(` cd ${config.name}`);\n console.log(' npm run dev');\n newLine();\n\n if (browser === 'chrome') {\n console.log('Load extension:');\n console.log(' 1. Open chrome://extensions (or edge://extensions)');\n console.log(' 2. Enable \"Developer mode\"');\n console.log(' 3. Click \"Load unpacked\" → select the dist/ folder');\n } else if (browser === 'firefox') {\n console.log('Load extension:');\n console.log(' 1. Open about:debugging#/runtime/this-firefox');\n console.log(' 2. Click \"Load Temporary Add-on\"');\n console.log(' 3. Select any file in the dist/ folder');\n }\n\n newLine();\n console.log('Happy coding! 🚀');\n newLine();\n}\n","import inquirer from 'inquirer';\nimport { DEFAULT_PROJECT_NAME, BROWSERS } from '../constants.js';\nimport { validateProjectName } from '../utils/index.js';\nimport type { BrowserTarget } from '../types/index.js';\n\nexport async function promptProjectName(): Promise<string> {\n const { projectName } = await inquirer.prompt([\n {\n name: 'projectName',\n message: 'Enter your extension project name:',\n default: DEFAULT_PROJECT_NAME,\n validate: (input: string) => {\n const result = validateProjectName(input);\n return result === true ? true : result;\n },\n },\n ]);\n return projectName;\n}\n\nexport async function promptBrowser(): Promise<BrowserTarget> {\n const { browser } = await inquirer.prompt([\n {\n type: 'list',\n name: 'browser',\n message: 'Select target browser:',\n choices: Object.entries(BROWSERS).map(([value, meta]) => ({\n name: `${meta.displayName} — ${meta.description}`,\n value,\n })),\n default: 'chrome',\n },\n ]);\n return browser;\n}\n","import type { BrowserTarget } from './types/index.js';\n\nexport const PACKAGE_NAME = 'create-vextro';\nexport const BRAND_NAME = 'Vextro';\n\nexport const VALID_PROJECT_NAME = /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\nexport const DEFAULT_PROJECT_NAME = 'my-extension';\nexport const DEFAULT_BROWSER: BrowserTarget = 'chrome';\n\nexport const FILES_TO_REMOVE = [\n 'src/App.tsx',\n 'src/main.tsx',\n 'src/index.css',\n 'src/App.css',\n 'src/assets',\n 'index.html',\n];\n\nexport const BROWSERS: Record<BrowserTarget, { displayName: string; description: string }> = {\n chrome: {\n displayName: 'Chrome / Edge',\n description: 'Google Chrome & Microsoft Edge (Chromium-based, uses CRXJS)',\n },\n firefox: {\n displayName: 'Firefox',\n description: 'Mozilla Firefox (uses vite-plugin-web-extension)',\n },\n};\n\nexport const CHROME_DEV_DEPS = [\n '@types/chrome',\n '@types/node',\n '@crxjs/vite-plugin',\n 'tailwindcss',\n '@tailwindcss/vite',\n];\n\nexport const FIREFOX_DEV_DEPS = [\n '@types/chrome',\n '@types/node',\n 'vite-plugin-web-extension',\n 'tailwindcss',\n '@tailwindcss/vite',\n];\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\n\nlet verbose = false;\n\nexport function setVerbose(value: boolean): void {\n verbose = value;\n}\n\nexport function info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n}\n\nexport function success(message: string): void {\n console.log(chalk.green('✔'), message);\n}\n\nexport function warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n}\n\nexport function error(message: string): void {\n console.log(chalk.red('✖'), message);\n}\n\nexport function debug(message: string): void {\n if (verbose) {\n console.log(chalk.gray('⬥'), chalk.gray(message));\n }\n}\n\nexport function spinner(text: string): Ora {\n return ora({ text, color: 'cyan' });\n}\n\nexport function newLine(): void {\n console.log();\n}\n\nexport function banner(text: string): void {\n console.log(chalk.bold.cyan(text));\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport function getTemplatesDir(): string {\n // When bundled with tsup, __dirname is dist/ → go up 1 level to project root\n // When running unbundled (vitest), __dirname is src/utils/ → go up 2 levels to project root\n const isBundled =\n __dirname.replace(/\\\\/g, '/').endsWith('/dist') ||\n __dirname.replace(/\\\\/g, '/').includes('/dist/');\n const projectRoot = isBundled\n ? path.resolve(__dirname, '..')\n : path.resolve(__dirname, '..', '..');\n return path.resolve(projectRoot, 'src', 'templates');\n}\n\nexport async function createDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(dirPath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n","import { VALID_PROJECT_NAME } from '../constants.js';\nimport { directoryExists } from './file.js';\n\nexport function validateProjectName(name: string): string | true {\n if (!name || name.trim().length === 0) {\n return 'Project name is required.';\n }\n\n if (!VALID_PROJECT_NAME.test(name)) {\n return 'Project name must be a valid npm package name (lowercase, no spaces, can use hyphens and dots).';\n }\n\n if (name.length > 214) {\n return 'Project name must be less than 214 characters.';\n }\n\n return true;\n}\n\nexport async function validateDirectory(dirPath: string): Promise<string | true> {\n if (await directoryExists(dirPath)) {\n return `Directory \"${dirPath}\" already exists. Use --force to overwrite.`;\n }\n return true;\n}\n\nexport function checkNodeVersion(minMajor: number = 20): string | true {\n const version = process.version;\n const major = parseInt(version.slice(1).split('.')[0], 10);\n\n if (major < minMajor) {\n return `Node.js ${minMajor}+ is required. You are using ${version}.`;\n }\n\n return true;\n}\n","import path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport fs from 'fs-extra';\nimport { getTemplatesDir, spinner, success, debug } from '../utils/index.js';\nimport { FILES_TO_REMOVE, CHROME_DEV_DEPS, FIREFOX_DEV_DEPS } from '../constants.js';\nimport type { ProjectConfig } from '../types/index.js';\n\nexport class ExtensionGenerator {\n private config: ProjectConfig;\n private templatesDir: string;\n\n constructor(config: ProjectConfig) {\n this.config = config;\n this.templatesDir = getTemplatesDir();\n }\n\n async generate(): Promise<void> {\n await this.scaffoldVite();\n await this.installBaseDeps();\n await this.cleanViteDefaults();\n await this.copySharedFiles();\n await this.copyBrowserFiles();\n await this.overrideConfigs();\n await this.patchTsConfig();\n await this.injectProjectName();\n await this.installExtensionDeps();\n }\n\n private async scaffoldVite(): Promise<void> {\n const s = spinner('Creating base Vite + React + TS project...');\n s.start();\n try {\n execSync(`npm exec --yes -- create-vite@latest ${this.config.name} --template react-ts`, {\n cwd: path.dirname(this.config.targetDir),\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success('Created base Vite + React + TS project');\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to scaffold Vite project: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private async installBaseDeps(): Promise<void> {\n const s = spinner('Installing base dependencies...');\n s.start();\n try {\n execSync('npm install', {\n cwd: this.config.targetDir,\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success('Installed base dependencies');\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to install dependencies: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private async cleanViteDefaults(): Promise<void> {\n const s = spinner('Removing default Vite template files...');\n s.start();\n\n for (const file of FILES_TO_REMOVE) {\n const fullPath = path.join(this.config.targetDir, file);\n if (await fs.pathExists(fullPath)) {\n await fs.remove(fullPath);\n debug(`Removed: ${file}`);\n }\n }\n\n const publicPath = path.join(this.config.targetDir, 'public');\n if (await fs.pathExists(publicPath)) {\n await fs.emptyDir(publicPath);\n }\n\n s.stop();\n success('Cleaned default Vite template files');\n }\n\n private async copySharedFiles(): Promise<void> {\n const s = spinner('Copying shared extension files...');\n s.start();\n\n const sharedDir = path.join(this.templatesDir, 'shared');\n\n // Copy shared src files (popup, options, utils, styles)\n const sharedSrcDir = path.join(sharedDir, 'src');\n if (await fs.pathExists(sharedSrcDir)) {\n await fs.copy(sharedSrcDir, path.join(this.config.targetDir, 'src'));\n }\n\n // Copy shared public files (icons)\n const sharedPublicDir = path.join(sharedDir, 'public');\n if (await fs.pathExists(sharedPublicDir)) {\n await fs.copy(sharedPublicDir, path.join(this.config.targetDir, 'public'));\n }\n\n s.stop();\n success('Copied shared extension files');\n }\n\n private async copyBrowserFiles(): Promise<void> {\n const s = spinner(`Copying ${this.config.browser} browser files...`);\n s.start();\n\n const browserDir = path.join(this.templatesDir, this.config.browser);\n\n // Copy browser-specific src files (manifest, background, content)\n const browserSrcDir = path.join(browserDir, 'src');\n if (await fs.pathExists(browserSrcDir)) {\n await fs.copy(browserSrcDir, path.join(this.config.targetDir, 'src'), {\n overwrite: true,\n });\n }\n\n s.stop();\n success(`Copied ${this.config.browser} browser files`);\n }\n\n private async overrideConfigs(): Promise<void> {\n const s = spinner('Overriding config files...');\n s.start();\n\n const browserDir = path.join(this.templatesDir, this.config.browser);\n const viteConfigFrom = path.join(browserDir, 'vite.config.ts');\n const viteConfigTo = path.join(this.config.targetDir, 'vite.config.ts');\n\n if (await fs.pathExists(viteConfigFrom)) {\n await fs.copy(viteConfigFrom, viteConfigTo, { overwrite: true });\n debug('Overrode: vite.config.ts');\n }\n\n s.stop();\n success('Overrode config files');\n }\n\n private async patchTsConfig(): Promise<void> {\n const s = spinner('Patching tsconfig for extension types...');\n s.start();\n\n const tsconfigAppPath = path.join(this.config.targetDir, 'tsconfig.app.json');\n\n if (await fs.pathExists(tsconfigAppPath)) {\n let content = await fs.readFile(tsconfigAppPath, 'utf-8');\n\n // Both Chrome and Firefox use @types/chrome (Firefox MV3 supports chrome.* namespace)\n const typeToAdd = 'chrome';\n\n // Inject the type into the \"types\" array using string replacement\n // This preserves comments and formatting in the JSONC file\n content = content.replace(\n /(\"types\"\\s*:\\s*\\[)([\\s\\S]*?)(\\])/,\n (match, prefix, existing, suffix) => {\n const trimmed = existing.trim();\n if (trimmed.includes(`\"${typeToAdd}\"`)) return match; // already present\n if (trimmed.length === 0) {\n return `${prefix}\"${typeToAdd}\"${suffix}`;\n }\n return `${prefix}${existing.trimEnd()}, \"${typeToAdd}\"${suffix}`;\n },\n );\n\n await fs.writeFile(tsconfigAppPath, content, 'utf-8');\n debug(`Patched tsconfig.app.json with type: ${typeToAdd}`);\n }\n\n s.stop();\n success('Patched tsconfig for extension types');\n }\n\n private async injectProjectName(): Promise<void> {\n const s = spinner('Injecting project name...');\n s.start();\n\n if (this.config.browser === 'chrome') {\n // Chrome uses manifest.ts\n const manifestPath = path.join(this.config.targetDir, 'src', 'manifest.ts');\n if (await fs.pathExists(manifestPath)) {\n let manifest = await fs.readFile(manifestPath, 'utf-8');\n manifest = manifest.replace(/__EXT_NAME__/g, this.config.name);\n await fs.writeFile(manifestPath, manifest, 'utf-8');\n }\n } else if (this.config.browser === 'firefox') {\n // Firefox uses manifest.json\n const manifestPath = path.join(this.config.targetDir, 'src', 'manifest.json');\n if (await fs.pathExists(manifestPath)) {\n let manifest = await fs.readFile(manifestPath, 'utf-8');\n manifest = manifest.replace(/__EXT_NAME__/g, this.config.name);\n await fs.writeFile(manifestPath, manifest, 'utf-8');\n }\n }\n\n // Update package.json name\n const pkgPath = path.join(this.config.targetDir, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n let pkg = await fs.readFile(pkgPath, 'utf-8');\n pkg = pkg.replace(/\"__EXT_NAME__\"/g, `\"${this.config.name}\"`);\n await fs.writeFile(pkgPath, pkg, 'utf-8');\n }\n\n s.stop();\n success('Injected project name');\n }\n\n private async installExtensionDeps(): Promise<void> {\n const deps = this.config.browser === 'firefox' ? FIREFOX_DEV_DEPS : CHROME_DEV_DEPS;\n\n const s = spinner(`Installing ${this.config.browser} extension dev dependencies...`);\n s.start();\n try {\n execSync(`npm install --save-dev ${deps.join(' ')}`, {\n cwd: this.config.targetDir,\n stdio: 'pipe',\n maxBuffer: 10 * 1024 * 1024,\n });\n s.stop();\n success(`Installed ${this.config.browser} extension dev dependencies`);\n } catch (err) {\n s.stop();\n throw new Error(\n `Failed to install extension dependencies: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n","{\n \"name\": \"create-vextro\",\n \"version\": \"0.1.2\",\n \"description\": \"Scaffold modern browser extensions (Chrome, Edge, Firefox) with Vite + React + Tailwind\",\n \"type\": \"module\",\n \"bin\": {\n \"create-vextro\": \"./dist/index.js\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src/\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"prepublishOnly\": \"npm run build && npm test\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"fs-extra\": \"^11.2.0\",\n \"inquirer\": \"^9.2.8\",\n \"ora\": \"^8.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^20.0.0\",\n \"eslint\": \"^9.0.0\",\n \"prettier\": \"^3.3.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.5.0\",\n \"typescript-eslint\": \"^8.0.0\",\n \"vitest\": \"^2.0.0\"\n },\n \"files\": [\n \"dist\",\n \"src/templates\"\n ],\n \"keywords\": [\n \"vite\",\n \"chrome-extension\",\n \"firefox-extension\",\n \"browser-extension\",\n \"vite-plugin\",\n \"react\",\n \"tailwind\",\n \"crxjs\",\n \"manifest-v3\",\n \"scaffold\",\n \"cli\",\n \"generator\",\n \"starter-kit\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/CodeCanvasCollective/vextro.git\"\n },\n \"author\": \"Lasantha <lasanthaslakmal@gmail.com>\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/CodeCanvasCollective/vextro/issues\"\n },\n \"homepage\": \"https://github.com/CodeCanvasCollective/vextro#readme\"\n}\n","import { createCli } from './cli.js';\n\nconst program = createCli();\nprogram.parse();\n"],"mappings":"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","names":["Command","path","fs","__filename","__dirname","path","fs","path","fs","path","fs","program","Command"]}
|