diff --git a/bun.lock b/bun.lock index 0e11e269..c9be29ce 100644 --- a/bun.lock +++ b/bun.lock @@ -294,6 +294,7 @@ "dependencies": { "@1natsu/wait-element": "^4.1.2", "@aklinker1/rollup-plugin-visualizer": "5.12.0", + "@topcli/prompts": "^4.0.0", "@webext-core/fake-browser": "^2.0.1", "@webext-core/isolated-element": "^1.1.3 || ^2 || ^3", "@webext-core/match-patterns": "^2.0.0", @@ -322,7 +323,6 @@ "nypm": "^0.6.5", "ohash": "^2.0.11", "picomatch": "^4.0.3", - "prompts": "^2.4.2", "publish-browser-extension": "^5.1.0 || ^6.0.0", "scule": "^1.3.0", "tiny-open": "^1.3.0", @@ -1062,6 +1062,8 @@ "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.2", "", { "dependencies": { "obug": "^2.1.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig=="], + "@topcli/prompts": ["@topcli/prompts@4.0.0", "", {}, "sha512-kkKYPb4k/6kRdnESt77B5vJrrYnYHIYczwv0P1c+tfN/IWEx3KZeKEHoUq7sImIyBEXWdA2uakIroD9pmRJziQ=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -2110,8 +2112,6 @@ "promise-toolbox": ["promise-toolbox@0.21.0", "", { "dependencies": { "make-error": "^1.3.2" } }, "sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg=="], - "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], - "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], @@ -2244,8 +2244,6 @@ "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], - "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - "smol-toml": ["smol-toml@1.6.1", "", {}, "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg=="], "solid-js": ["solid-js@1.9.11", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.5.0", "seroval-plugins": "~1.5.0" } }, "sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q=="], diff --git a/cspell.yml b/cspell.yml index b192bbeb..0fe2cc1c 100644 --- a/cspell.yml +++ b/cspell.yml @@ -108,6 +108,7 @@ words: - subdependency - tabstrip - teleporting + - topcli - treemap - triaging - umami diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 9d4a13ac..9e50fb0c 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -17,6 +17,7 @@ "dependencies": { "@1natsu/wait-element": "^4.1.2", "@aklinker1/rollup-plugin-visualizer": "5.12.0", + "@topcli/prompts": "^4.0.0", "@webext-core/fake-browser": "^2.0.1", "@webext-core/isolated-element": "^1.1.3 || ^2 || ^3", "@webext-core/match-patterns": "^2.0.0", @@ -45,7 +46,6 @@ "nypm": "^0.6.5", "ohash": "^2.0.11", "picomatch": "^4.0.3", - "prompts": "^2.4.2", "publish-browser-extension": "^5.1.0 || ^6.0.0", "scule": "^1.3.0", "tiny-open": "^1.3.0", diff --git a/packages/wxt/src/core/initialize.ts b/packages/wxt/src/core/initialize.ts index 7f53c706..571cccfa 100644 --- a/packages/wxt/src/core/initialize.ts +++ b/packages/wxt/src/core/initialize.ts @@ -1,4 +1,4 @@ -import prompts from 'prompts'; +import { question, select } from '@topcli/prompts'; import { consola } from 'consola'; import { downloadTemplate } from 'giget'; import { readdir, rename } from 'node:fs/promises'; @@ -8,88 +8,78 @@ import { styleText } from 'node:util'; import { TextStyle } from '../utils/text-style'; export async function initialize(options: { - directory: string; - template: string; - packageManager: string; + directory?: string; + template?: string; + packageManager?: string; }) { consola.info('Initializing new project'); const templates = await listTemplates(); - const defaultTemplate = templates.find( - (template) => template.name === options.template?.toLowerCase().trim(), - ); + const inputTemplateName = options.template + ? templates.find( + (template) => template.name === options.template!.toLowerCase().trim(), + )?.name + : undefined; - const input = await prompts( - [ - { - name: 'directory', - type: () => (options.directory == null ? 'text' : undefined), - message: 'Project Directory', - initial: options.directory, - }, - { - name: 'template', - type: () => (defaultTemplate == null ? 'select' : undefined), - message: 'Choose a template', - choices: templates.map((template) => ({ - title: TEMPLATE_COLORS[template.name] - ? styleText(TEMPLATE_COLORS[template.name], template.name) - : template.name, - value: template, - })), - }, - { - name: 'packageManager', - type: () => (options.packageManager == null ? 'select' : undefined), - message: 'Package Manager', - choices: [ - { title: styleText('magenta', 'bun'), value: 'bun' }, - { title: styleText('red', 'npm'), value: 'npm' }, - { title: styleText('yellow', 'pnpm'), value: 'pnpm' }, - { title: styleText('cyan', 'yarn'), value: 'yarn' }, - ], - }, - ], - { - onCancel: () => process.exit(1), - }, - ); - input.directory ||= options.directory || '.'; - input.template ??= defaultTemplate; - input.packageManager ??= options.packageManager; + const directory = + options.directory ?? + (await question('Project Directory', { defaultValue: '.' })); + if (!directory) throw Error('Directory is required'); - const isExists = await pathExists(input.directory); + const templateName = + inputTemplateName ?? + (await select('Choose a template', { + choices: templates.map((template) => ({ + label: TEMPLATE_COLORS[template.name] + ? styleText(TEMPLATE_COLORS[template.name], template.name) + : template.name, + value: template.name, + })), + })); + const template = templates.find((t) => t.name === templateName); + if (!template) throw Error('Unknown template: ' + templateName); + + const packageManager = + options.packageManager ?? + (await select('Package Manager', { + choices: [ + { label: styleText('magenta', 'bun'), value: 'bun' }, + { label: styleText('red', 'npm'), value: 'npm' }, + { label: styleText('yellow', 'pnpm'), value: 'pnpm' }, + { label: styleText('cyan', 'yarn'), value: 'yarn' }, + ], + })); + + const isExists = await pathExists(directory); if (isExists) { const isEmpty = - (await readdir(input.directory)).filter((dir) => dir !== '.git') - .length === 0; + (await readdir(directory)).filter((dir) => dir !== '.git').length === 0; if (!isEmpty) { consola.error( - `The directory ${path.resolve(input.directory)} is not empty. Aborted.`, + `The directory ${path.resolve(directory)} is not empty. Aborted.`, ); process.exit(1); } } - await cloneProject(input); + await cloneProject({ directory, template }); - const cdPath = path.relative(process.cwd(), path.resolve(input.directory)); + const cdPath = path.relative(process.cwd(), path.resolve(directory)); console.log(); consola.log( `✨ WXT project created with the ${ - TEMPLATE_COLORS[input.template.name] - ? styleText(TEMPLATE_COLORS[input.template.name], input.template.name) - : input.template.name + TEMPLATE_COLORS[template.name] + ? styleText(TEMPLATE_COLORS[template.name], template.name) + : template.name } template.`, ); console.log(); consola.log('Next steps:'); + let step = 0; if (cdPath !== '') consola.log(` ${++step}.`, styleText('cyan', `cd ${cdPath}`)); - consola.log( - ` ${++step}.`, - styleText('cyan', `${input.packageManager} install`), - ); + consola.log(` ${++step}.`, styleText('cyan', `${packageManager} install`)); + console.log(); }