From fee72db30cc39a05b6514ae19b87243124800d2f Mon Sep 17 00:00:00 2001 From: priyanshu-001 <26710303+Priyanshu-001@users.noreply.github.com> Date: Thu, 17 Sep 2026 21:54:31 +0530 Subject: [PATCH] feat: add description prompt and validation for project scaffolding --- __tests__/cli.spec.ts | 14 ++++++++++++++ __tests__/utils.spec.ts | 12 ++++++++++++ src/index.ts | 17 +++++++++++++++++ src/utils.ts | 4 ++++ templates/react-ts/manifest.config.ts | 1 + templates/react-ts/package.json | 1 + templates/react/manifest.config.js | 1 + templates/react/package.json | 1 + templates/solid-ts/manifest.config.ts | 1 + templates/solid-ts/package.json | 1 + templates/solid/manifest.config.js | 1 + templates/solid/package.json | 1 + templates/svelte-ts/manifest.config.ts | 1 + templates/svelte-ts/package.json | 1 + templates/svelte/manifest.config.js | 1 + templates/svelte/package.json | 1 + templates/vanilla-ts/manifest.config.ts | 1 + templates/vanilla-ts/package.json | 1 + templates/vanilla/manifest.config.js | 1 + templates/vanilla/package.json | 1 + templates/vue-ts/manifest.config.ts | 1 + templates/vue-ts/package.json | 1 + templates/vue/manifest.config.js | 1 + templates/vue/package.json | 1 + 24 files changed, 67 insertions(+) create mode 100644 __tests__/utils.spec.ts diff --git a/__tests__/cli.spec.ts b/__tests__/cli.spec.ts index bc75f77..fb40cac 100644 --- a/__tests__/cli.spec.ts +++ b/__tests__/cli.spec.ts @@ -105,10 +105,17 @@ it('successfully scaffolds a project based on vue starter template', () => { cwd: __dirname, }) const generatedFiles = fs.readdirSync(genPath).sort() + const generatedPackage = JSON.parse( + fs.readFileSync(path.join(genPath, 'package.json'), 'utf-8'), + ) // Assertions expect(stdout).toContain(`Scaffolding project in ${genPath}`) expect(templateFiles).toEqual(generatedFiles) + expect(generatedPackage.name).toBe(projectName) + expect(generatedPackage.description).toBe( + 'A browser extension built with CRXJS.', + ) }) it('successfully scaffolds a project with subfolder based on react starter template', () => { @@ -116,10 +123,17 @@ it('successfully scaffolds a project with subfolder based on react starter templ cwd: __dirname, }) const generatedFiles = fs.readdirSync(genPathWithSubfolder).sort() + const generatedPackage = JSON.parse( + fs.readFileSync(path.join(genPathWithSubfolder, 'package.json'), 'utf-8'), + ) // Assertions expect(stdout).toContain(`Scaffolding project in ${genPathWithSubfolder}`) expect(templateFilesReact).toEqual(generatedFiles) + expect(generatedPackage.name).toBe(projectName) + expect(generatedPackage.description).toBe( + 'A browser extension built with CRXJS.', + ) }) it('works with the -t alias', () => { diff --git a/__tests__/utils.spec.ts b/__tests__/utils.spec.ts new file mode 100644 index 0000000..08c5bd4 --- /dev/null +++ b/__tests__/utils.spec.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from 'vitest' +import { isValidDescription } from '../src/utils' + +describe('isValidDescription', () => { + it('accepts descriptions up to 132 characters', () => { + expect(isValidDescription('a'.repeat(132))).toBe(true) + }) + + it('rejects descriptions longer than 132 characters', () => { + expect(isValidDescription('a'.repeat(133))).toBe(false) + }) +}) diff --git a/src/index.ts b/src/index.ts index 2bac7f6..046e841 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,7 @@ import { generateBanner, isEmpty, isGitHubUrl, + isValidDescription, isValidPackageName, pkgFromUserAgent, toValidPackageName, @@ -120,6 +121,20 @@ async function init() { packageName = packageNameResult } + const packageDescriptionResult = await prompts.text({ + message: 'Extension description (you can edit this anytime in package.json):', + defaultValue: 'A browser extension built with CRXJS.', + placeholder: 'A browser extension built with CRXJS.', + validate(description) { + if (!isValidDescription(description)) { + return 'Description must be non-blank and 132 characters or fewer' + } + }, + }) + if (prompts.isCancel(packageDescriptionResult)) + return cancel() + const packageDescription = packageDescriptionResult + // 4. Choose a framework and variant let template = argTemplate let hasInvalidArgTemplate = false @@ -180,6 +195,7 @@ async function init() { if (fs.existsSync(pkgPath)) { const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) pkg.name = packageName + pkg.description = packageDescription fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`) } s.stop('Cloning completed successfully') @@ -213,6 +229,7 @@ async function init() { ) pkg.name = packageName + pkg.description = packageDescription write('package.json', `${JSON.stringify(pkg, null, 2)}\n`) } diff --git a/src/utils.ts b/src/utils.ts index ba25eb9..453b49a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -23,6 +23,10 @@ export function isValidPackageName(projectName: string) { ) } +// Chrome webstore limit reference: https://developer.chrome.com/docs/extensions/reference/manifest#required-web-store +export function isValidDescription(description: string): boolean { + return description.trim().length > 0 && description.length <= 132 +} export function toValidPackageName(projectName: string) { return projectName .trim() diff --git a/templates/react-ts/manifest.config.ts b/templates/react-ts/manifest.config.ts index aa24a4b..046a6b7 100644 --- a/templates/react-ts/manifest.config.ts +++ b/templates/react-ts/manifest.config.ts @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/react-ts/package.json b/templates/react-ts/package.json index b810aee..c3a2eef 100644 --- a/templates/react-ts/package.json +++ b/templates/react-ts/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "tsc -b && vite build", diff --git a/templates/react/manifest.config.js b/templates/react/manifest.config.js index ad37ec8..ddb10ba 100644 --- a/templates/react/manifest.config.js +++ b/templates/react/manifest.config.js @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/react/package.json b/templates/react/package.json index 5ebbf0f..e07f77c 100644 --- a/templates/react/package.json +++ b/templates/react/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build", diff --git a/templates/solid-ts/manifest.config.ts b/templates/solid-ts/manifest.config.ts index 680a824..295c7f0 100644 --- a/templates/solid-ts/manifest.config.ts +++ b/templates/solid-ts/manifest.config.ts @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/solid-ts/package.json b/templates/solid-ts/package.json index 5dfe3e2..4518977 100644 --- a/templates/solid-ts/package.json +++ b/templates/solid-ts/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "tsc -b && vite build", diff --git a/templates/solid/manifest.config.js b/templates/solid/manifest.config.js index a091f0f..98e3868 100644 --- a/templates/solid/manifest.config.js +++ b/templates/solid/manifest.config.js @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/solid/package.json b/templates/solid/package.json index 011d123..d5848b1 100644 --- a/templates/solid/package.json +++ b/templates/solid/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build" diff --git a/templates/svelte-ts/manifest.config.ts b/templates/svelte-ts/manifest.config.ts index 680a824..295c7f0 100644 --- a/templates/svelte-ts/manifest.config.ts +++ b/templates/svelte-ts/manifest.config.ts @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/svelte-ts/package.json b/templates/svelte-ts/package.json index a1aa8c6..81f6f28 100644 --- a/templates/svelte-ts/package.json +++ b/templates/svelte-ts/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build" diff --git a/templates/svelte/manifest.config.js b/templates/svelte/manifest.config.js index a091f0f..98e3868 100644 --- a/templates/svelte/manifest.config.js +++ b/templates/svelte/manifest.config.js @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/svelte/package.json b/templates/svelte/package.json index 53c264d..1e86407 100644 --- a/templates/svelte/package.json +++ b/templates/svelte/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build" diff --git a/templates/vanilla-ts/manifest.config.ts b/templates/vanilla-ts/manifest.config.ts index 680a824..295c7f0 100644 --- a/templates/vanilla-ts/manifest.config.ts +++ b/templates/vanilla-ts/manifest.config.ts @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/vanilla-ts/package.json b/templates/vanilla-ts/package.json index f7b58fd..98f04dc 100644 --- a/templates/vanilla-ts/package.json +++ b/templates/vanilla-ts/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "tsc && vite build" diff --git a/templates/vanilla/manifest.config.js b/templates/vanilla/manifest.config.js index a091f0f..98e3868 100644 --- a/templates/vanilla/manifest.config.js +++ b/templates/vanilla/manifest.config.js @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/vanilla/package.json b/templates/vanilla/package.json index 09de8b5..5c337e4 100644 --- a/templates/vanilla/package.json +++ b/templates/vanilla/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build" diff --git a/templates/vue-ts/manifest.config.ts b/templates/vue-ts/manifest.config.ts index 680a824..295c7f0 100644 --- a/templates/vue-ts/manifest.config.ts +++ b/templates/vue-ts/manifest.config.ts @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/vue-ts/package.json b/templates/vue-ts/package.json index d2f0693..c2da4d4 100644 --- a/templates/vue-ts/package.json +++ b/templates/vue-ts/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build" diff --git a/templates/vue/manifest.config.js b/templates/vue/manifest.config.js index a091f0f..98e3868 100644 --- a/templates/vue/manifest.config.js +++ b/templates/vue/manifest.config.js @@ -4,6 +4,7 @@ import pkg from './package.json' export default defineManifest({ manifest_version: 3, name: pkg.name, + description: pkg.description, version: pkg.version, icons: { 48: 'public/logo.png', diff --git a/templates/vue/package.json b/templates/vue/package.json index af86689..9cb331c 100644 --- a/templates/vue/package.json +++ b/templates/vue/package.json @@ -3,6 +3,7 @@ "type": "module", "version": "1.0.0", "private": true, + "description": "A browser extension built with CRXJS.", "scripts": { "dev": "vite", "build": "vite build"