diff --git a/package-lock.json b/package-lock.json index ec97c73..d94e857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1669,6 +1669,11 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -12786,6 +12791,14 @@ "spdx-expression-parse": "1.0.4" } }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "requires": { + "builtins": "1.0.3" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", diff --git a/package.json b/package.json index e7feee5..5024b74 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,8 @@ "project-version": "^1.0.0", "replace-in-file": "^3.1.1", "sha.js": "^2.4.10", - "update-notifier": "^2.3.0" + "update-notifier": "^2.3.0", + "validate-npm-package-name": "^3.0.0" }, "devDependencies": { "@types/del": "^3.0.0", diff --git a/src/cli/tests/cli.unit.spec.ts b/src/cli/tests/cli.unit.spec.ts index 9163390..5a719f7 100644 --- a/src/cli/tests/cli.unit.spec.ts +++ b/src/cli/tests/cli.unit.spec.ts @@ -13,7 +13,7 @@ import { install, Placeholders } from '../tasks'; -import { getIntro, Runner } from '../utils'; +import { getIntro, Runner, validateName } from '../utils'; test('errors if outdated', async t => { nock.disableNetConnect(); @@ -101,6 +101,12 @@ test('checkArgs always returns { install } (so --no-install works in interactive t.deepEqual(opts, { install: true }); }); +test('only accepts valid package names', async t => { + t.true(validateName('package-name')); + t.true(validateName('package-name-2')); + t.true(validateName('@example/package-name-2')); +}); + test('ascii art shows if stdout has 85+ columns', async t => { const jumbo = getIntro(100); const snippet = `| __| | | | '_ \\ / _ \\/ __|/ __| '__| | '_ \\|`; diff --git a/src/cli/utils.ts b/src/cli/utils.ts index 254b112..558cf8f 100644 --- a/src/cli/utils.ts +++ b/src/cli/utils.ts @@ -1,6 +1,7 @@ import chalk from 'chalk'; import { existsSync } from 'fs'; import gradient from 'gradient-string'; +import validateNpmPackageName from 'validate-npm-package-name'; export enum Runner { Npm = 'npm', Yarn = 'yarn' @@ -31,8 +32,8 @@ export interface TypescriptStarterOptions TypescriptStarterInferredOptions {} export function validateName(input: string): true | string { - return !/^\s*[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\s*$/.test(input) - ? 'Name should be in-kebab-case' + return !validateNpmPackageName(input).validForNewPackages + ? 'Name should be in-kebab-case (for npm)' : existsSync(input) ? `The "${input}" path already exists in this directory.` : true; diff --git a/src/types/cli.d.ts b/src/types/cli.d.ts index 4ee13d7..4f5ec80 100644 --- a/src/types/cli.d.ts +++ b/src/types/cli.d.ts @@ -5,3 +5,4 @@ declare module 'github-username'; declare module 'gradient-string'; declare module 'md5-file'; declare module 'replace-in-file'; +declare module 'validate-npm-package-name';