diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index a573536255a81..db699d5b32c5e 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -327,7 +327,8 @@ export const enum NameValidationResult { NameTooLong, NameStartsWithDot, NameStartsWithUnderscore, - NameContainsNonURISafeCharacters, + NameContainsInvalidCharacters, + NameContainsNonURISafeCharacters = NameContainsInvalidCharacters, // for backward compatibility } const maxPackageNameLength = 214; @@ -381,8 +382,8 @@ function validatePackageNameWorker(packageName: string, supportScopedPackage: bo return NameValidationResult.Ok; } } - if (encodeURIComponent(packageName) !== packageName) { - return NameValidationResult.NameContainsNonURISafeCharacters; + if (!/^[\w.-]+$/.test(packageName)) { + return NameValidationResult.NameContainsInvalidCharacters; } return NameValidationResult.Ok; } @@ -405,8 +406,8 @@ function renderPackageNameValidationFailureWorker(typing: string, result: NameVa return `'${typing}':: ${kind} name '${name}' cannot start with '.'`; case NameValidationResult.NameStartsWithUnderscore: return `'${typing}':: ${kind} name '${name}' cannot start with '_'`; - case NameValidationResult.NameContainsNonURISafeCharacters: - return `'${typing}':: ${kind} name '${name}' contains non URI safe characters`; + case NameValidationResult.NameContainsInvalidCharacters: + return `'${typing}':: ${kind} name '${name}' contains invalid characters`; case NameValidationResult.Ok: return Debug.fail(); // Shouldn't have called this. default: diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 1c7e77ae4039f..a832f3f2fcfe6 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1524,10 +1524,11 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () it("package name cannot start with underscore", () => { assert.equal(validatePackageName("_foo"), NameValidationResult.NameStartsWithUnderscore); }); - it("package non URI safe characters are not supported", () => { - assert.equal(validatePackageName(" scope "), NameValidationResult.NameContainsNonURISafeCharacters); - assert.equal(validatePackageName("; say ‘Hello from TypeScript!’ #"), NameValidationResult.NameContainsNonURISafeCharacters); - assert.equal(validatePackageName("a/b/c"), NameValidationResult.NameContainsNonURISafeCharacters); + it("package invalid characters are not supported", () => { + assert.equal(validatePackageName(" scope "), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("; say ‘Hello from TypeScript!’ #"), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("a/b/c"), NameValidationResult.NameContainsInvalidCharacters); + assert.equal(validatePackageName("react'test"), NameValidationResult.NameContainsInvalidCharacters); }); it("scoped package name is supported", () => { assert.equal(validatePackageName("@scope/bar"), NameValidationResult.Ok); @@ -1540,10 +1541,10 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () assert.deepEqual(validatePackageName("@_scope/bar"), { name: "_scope", isScopeName: true, result: NameValidationResult.NameStartsWithUnderscore }); assert.deepEqual(validatePackageName("@_scope/_bar"), { name: "_scope", isScopeName: true, result: NameValidationResult.NameStartsWithUnderscore }); }); - it("scope name in scoped package name with non URI safe characters are not supported", () => { - assert.deepEqual(validatePackageName("@ scope /bar"), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@; say ‘Hello from TypeScript!’ #/bar"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@ scope / bar "), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsNonURISafeCharacters }); + it("scope name in scoped package name with invalid characters are not supported", () => { + assert.deepEqual(validatePackageName("@ scope /bar"), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@; say ‘Hello from TypeScript!’ #/bar"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@ scope / bar "), { name: " scope ", isScopeName: true, result: NameValidationResult.NameContainsInvalidCharacters }); }); it("package name in scoped package name cannot start with dot", () => { assert.deepEqual(validatePackageName("@scope/.bar"), { name: ".bar", isScopeName: false, result: NameValidationResult.NameStartsWithDot }); @@ -1551,9 +1552,9 @@ describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () it("package name in scoped package name cannot start with underscore", () => { assert.deepEqual(validatePackageName("@scope/_bar"), { name: "_bar", isScopeName: false, result: NameValidationResult.NameStartsWithUnderscore }); }); - it("package name in scoped package name with non URI safe characters are not supported", () => { - assert.deepEqual(validatePackageName("@scope/ bar "), { name: " bar ", isScopeName: false, result: NameValidationResult.NameContainsNonURISafeCharacters }); - assert.deepEqual(validatePackageName("@scope/; say ‘Hello from TypeScript!’ #"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: false, result: NameValidationResult.NameContainsNonURISafeCharacters }); + it("package name in scoped package name with invalid characters are not supported", () => { + assert.deepEqual(validatePackageName("@scope/ bar "), { name: " bar ", isScopeName: false, result: NameValidationResult.NameContainsInvalidCharacters }); + assert.deepEqual(validatePackageName("@scope/; say ‘Hello from TypeScript!’ #"), { name: "; say ‘Hello from TypeScript!’ #", isScopeName: false, result: NameValidationResult.NameContainsInvalidCharacters }); }); }); diff --git a/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js b/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js index b32a3c36b7636..27c9be5bd0cc8 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/malformed-packagejson.js @@ -200,7 +200,7 @@ Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/projects/pro Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer TI:: [hh:mm:ss:mss] Installing typings ["co } }"] -TI:: [hh:mm:ss:mss] 'co } }':: Package name 'co } }' contains non URI safe characters +TI:: [hh:mm:ss:mss] 'co } }':: Package name 'co } }' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: { diff --git a/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js b/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js index 3bc84f2df7cd2..29afbcf692263 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/should-handle-node-core-modules.js @@ -654,7 +654,7 @@ TI:: [hh:mm:ss:mss] Sending response: "projectName": "/dev/null/inferredProject1*" } TI:: [hh:mm:ss:mss] Installing typings ["s tream"] -TI:: [hh:mm:ss:mss] 's tream':: Package name 's tream' contains non URI safe characters +TI:: [hh:mm:ss:mss] 's tream':: Package name 's tream' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: { diff --git a/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js b/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js index 499d7ad5544a9..d29fb6696c67f 100644 --- a/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js +++ b/tests/baselines/reference/tsserver/typingsInstaller/should-not-initialize-invaalid-package-names.js @@ -160,7 +160,7 @@ Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/projects/pro Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/projects/project/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Directory location for typing installer TI:: [hh:mm:ss:mss] Installing typings ["; say ‘Hello from TypeScript!’ #"] -TI:: [hh:mm:ss:mss] '; say ‘Hello from TypeScript!’ #':: Package name '; say ‘Hello from TypeScript!’ #' contains non URI safe characters +TI:: [hh:mm:ss:mss] '; say ‘Hello from TypeScript!’ #':: Package name '; say ‘Hello from TypeScript!’ #' contains invalid characters TI:: [hh:mm:ss:mss] All typings are known to be missing or invalid - no need to install more typings TI:: [hh:mm:ss:mss] Sending response: {