diff --git a/packages/create-app/index.js b/packages/create-app/index.js index 2613a66ab50cf2..4d5b7df838248a 100755 --- a/packages/create-app/index.js +++ b/packages/create-app/index.js @@ -39,17 +39,17 @@ async function init() { let targetDir = argv._[0] if (!targetDir) { /** - * @type {{ name: string }} + * @type {{ projectName: string }} */ - const { name } = await prompt({ + const { projectName } = await prompt({ type: 'input', - name: 'name', + name: 'projectName', message: `Project name:`, initial: 'vite-project' }) - targetDir = name + targetDir = projectName } - + const packageName = await getValidPackageName(targetDir) const root = path.join(cwd, targetDir) console.log(`\nScaffolding project in ${root}...`) @@ -122,13 +122,7 @@ async function init() { const pkg = require(path.join(templateDir, `package.json`)) - pkg.name = path - .basename(root) - // #2360 ensure packgae.json name is valid - .trim() - .replace(/\s+/g, '-') - .replace(/^[._]/, '') - .replace(/[~)('!*]+/g, '-') + pkg.name = packageName write('package.json', JSON.stringify(pkg, null, 2)) @@ -152,6 +146,33 @@ function copy(src, dest) { } } +async function getValidPackageName(projectName) { + const packageNameRegExp = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/ + if (packageNameRegExp.test(projectName)) { + return projectName + } else { + const suggestedPackageName = projectName + .trim() + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/^[._]/, '') + .replace(/[^a-z0-9-~]+/g, '-') + + /** + * @type {{ inputPackageName: string }} + */ + const { inputPackageName } = await prompt({ + type: 'input', + name: 'inputPackageName', + message: `Package name:`, + initial: suggestedPackageName, + validate: (input) => + packageNameRegExp.test(input) ? true : 'Invalid package.json name' + }) + return inputPackageName + } +} + function copyDir(srcDir, destDir) { fs.mkdirSync(destDir, { recursive: true }) for (const file of fs.readdirSync(srcDir)) {