Remove jsTypings/semver.ts, add unit tests and logging

This commit is contained in:
Ron Buckton 2018-08-22 11:22:09 -07:00
parent 79d7f371bb
commit b9afdadf71
12 changed files with 207 additions and 151 deletions

View File

@ -3671,6 +3671,14 @@
"category": "Error",
"code": 6205
},
"'package.json' has invalid version '{0}' in 'typesVersions' field.": {
"category": "Message",
"code": 6206
},
"'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": {
"category": "Message",
"code": 6207
},
"Projects to reference": {
"category": "Message",

View File

@ -127,7 +127,14 @@ namespace ts {
/* @internal */
export function getPackageJsonTypesVersionsOverride(typesVersions: MapLike<string>) {
const typeScriptVersion = Version.parse(versionMajorMinor);
return getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, /*state*/ undefined);
}
let typeScriptVersion: Version | undefined;
function getPackageJsonTypesVersionsOverrideWithTrace(typesVersions: MapLike<string>, state: ModuleResolutionState | undefined) {
if (!typeScriptVersion) typeScriptVersion = new Version(versionMajorMinor);
let bestVersion: Version | undefined;
let bestVersionKey: string | undefined;
for (const key in typesVersions) {
@ -135,12 +142,15 @@ namespace ts {
const keyVersion = Version.tryParse(key);
if (keyVersion === undefined) {
if (state && state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_invalid_version_0_in_typesVersions_field, key);
}
continue;
}
// match the greatest version less than the current TypeScript version
if (keyVersion.compareTo(typeScriptVersion) <= 0
&& (bestVersion === undefined || keyVersion.compareTo(bestVersion) > 0)) {
if (keyVersion.compareTo(bestVersion) > 0 &&
keyVersion.compareTo(typeScriptVersion) <= 0) {
bestVersion = keyVersion;
bestVersionKey = key;
}
@ -169,22 +179,25 @@ namespace ts {
return;
}
const result = getPackageJsonTypesVersionsOverride(typesVersions);
const result = getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, state);
if (!result) {
return undefined;
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor);
}
return;
}
const { version: bestVersionKey, directory: bestVersionPath } = result;
if (!isString(bestVersionPath)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersion['${bestVersionKey}']`, "string", typeof bestVersionPath);
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "string", typeof bestVersionPath);
}
return;
}
if (state.traceEnabled) {
const path = normalizePath(combinePaths(baseDirectory, bestVersionPath));
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, `typesVersion['${bestVersionKey}']`, bestVersionPath, path);
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, `typesVersions['${bestVersionKey}']`, bestVersionPath, path);
}
return bestVersionPath;

View File

@ -1,48 +1,49 @@
/* @internal */
namespace ts {
// Per https://semver.org/#spec-item-2:
//
// https://semver.org/#spec-item-2
// > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
// > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
// > version, and Z is the patch version. Each element MUST increase numerically.
//
// NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
// value of `0`.
const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:(\+[a-z0-9-.]+))?)?)?$/i;
const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
// Per https://semver.org/#spec-item-9:
//
// https://semver.org/#spec-item-9
// > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
// > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
// > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers
// > MUST NOT include leading zeroes.
const prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i;
// Per https://semver.org/#spec-item-10:
//
// https://semver.org/#spec-item-10
// > Build metadata MAY be denoted by appending a plus sign and a series of dot separated
// > identifiers immediately following the patch or pre-release version. Identifiers MUST
// > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
const buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i;
// Per https://semver.org/#spec-item-9:
//
// https://semver.org/#spec-item-9
// > Numeric identifiers MUST NOT include leading zeroes.
const numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
/**
* Describes a precise semantic version number, per https://semver.org
* Describes a precise semantic version number, https://semver.org
*/
export class Version {
static readonly zero = new Version(0);
readonly major: number;
readonly minor: number;
readonly patch: number;
readonly prerelease: ReadonlyArray<string>;
readonly build: ReadonlyArray<string>;
constructor(major: number, minor = 0, patch = 0, prerelease = "", build = "") {
constructor(text: string);
constructor(major: number, minor?: number, patch?: number, prerelease?: string, build?: string);
constructor(major: number | string, minor = 0, patch = 0, prerelease = "", build = "") {
if (typeof major === "string") {
const result = Debug.assertDefined(tryParseComponents(major), "Invalid version");
({ major, minor, patch, prerelease, build } = result);
}
Debug.assert(major >= 0, "Invalid argument: major");
Debug.assert(minor >= 0, "Invalid argument: minor");
Debug.assert(patch >= 0, "Invalid argument: patch");
@ -51,104 +52,102 @@ namespace ts {
this.major = major;
this.minor = minor;
this.patch = patch;
this.prerelease = prerelease === "" ? emptyArray : prerelease.split(".");
this.build = build === "" ? emptyArray : build.split(".");
}
static parse(text: string) {
return Debug.assertDefined(this.tryParse(text));
this.prerelease = prerelease ? prerelease.split(".") : emptyArray;
this.build = build ? build.split(".") : emptyArray;
}
static tryParse(text: string) {
const match = versionRegExp.exec(text);
if (!match) return undefined;
const result = tryParseComponents(text);
if (!result) return undefined;
const [, major, minor = 0, patch = 0, prerelease, build] = match;
if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined;
if (build && !buildRegExp.test(build)) return undefined;
return new Version(+major, +minor, +patch, prerelease, build);
const { major, minor, patch, prerelease, build } = result;
return new Version(major, minor, patch, prerelease, build);
}
static compare(left: Version | undefined, right: Version | undefined, compareBuildMetadata?: boolean) {
// Per https://semver.org/#spec-item-11:
//
compareTo(other: Version | undefined) {
// https://semver.org/#spec-item-11
// > Precedence is determined by the first difference when comparing each of these
// > identifiers from left to right as follows: Major, minor, and patch versions are
// > always compared numerically.
//
// > When major, minor, and patch are equal, a pre-release version has lower
// > precedence than a normal version.
// https://semver.org/#spec-item-11
// > Precedence for two pre-release versions with the same major, minor, and patch version
// > MUST be determined by comparing each dot separated identifier from left to right until
// > a difference is found [...]
//
// Per https://semver.org/#spec-item-10:
//
// > Build metadata SHOULD be ignored when determining version precedence.
if (left === right) return Comparison.EqualTo;
if (left === undefined) return Comparison.LessThan;
if (right === undefined) return Comparison.GreaterThan;
return compareValues(left.major, right.major)
|| compareValues(left.minor, right.minor)
|| compareValues(left.patch, right.patch)
|| compareVersionFragments(left.prerelease, right.prerelease, /*compareNumericIdentifiers*/ true)
|| (compareBuildMetadata ? compareVersionFragments(left.build, right.build, /*compareNumericIdentifiers*/ false) : Comparison.EqualTo);
}
compareTo(other: Version, compareBuildMetadata?: boolean) {
return Version.compare(this, other, compareBuildMetadata);
// https://semver.org/#spec-item-11
// > Build metadata does not figure into precedence
if (this === other) return Comparison.EqualTo;
if (other === undefined) return Comparison.GreaterThan;
return compareValues(this.major, other.major)
|| compareValues(this.minor, other.minor)
|| compareValues(this.patch, other.patch)
|| comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
}
toString() {
let result = `${this.major}.${this.minor}.${this.patch}`;
if (this.prerelease) result += `-${this.prerelease.join(".")}`;
if (this.build) result += `+${this.build.join(".")}`;
if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`;
if (some(this.build)) result += `+${this.build.join(".")}`;
return result;
}
}
function compareVersionFragments(left: ReadonlyArray<string>, right: ReadonlyArray<string>, compareNumericIdentifiers: boolean) {
// Per https://semver.org/#spec-item-11:
//
function tryParseComponents(text: string) {
const match = versionRegExp.exec(text);
if (!match) return undefined;
const [, major, minor = "0", patch = "0", prerelease = "", build = ""] = match;
if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined;
if (build && !buildRegExp.test(build)) return undefined;
return {
major: parseInt(major, 10),
minor: parseInt(minor, 10),
patch: parseInt(patch, 10),
prerelease,
build
};
}
function comparePrerelaseIdentifiers(left: ReadonlyArray<string>, right: ReadonlyArray<string>) {
// https://semver.org/#spec-item-11
// > When major, minor, and patch are equal, a pre-release version has lower precedence
// > than a normal version.
if (left === right) return Comparison.EqualTo;
if (left.length === 0) return right.length === 0 ? Comparison.EqualTo : Comparison.GreaterThan;
if (right.length === 0) return Comparison.LessThan;
// Per https://semver.org/#spec-item-11:
//
// https://semver.org/#spec-item-11
// > Precedence for two pre-release versions with the same major, minor, and patch version
// > MUST be determined by comparing each dot separated identifier from left to right until
// > a difference is found
// > a difference is found [...]
const length = Math.min(left.length, right.length);
for (let i = 0; i < length; i++) {
const leftIdentifier = left[i];
const rightIdentifier = right[i];
if (leftIdentifier === rightIdentifier) continue;
const leftIsNumeric = compareNumericIdentifiers && numericIdentifierRegExp.test(leftIdentifier);
const rightIsNumeric = compareNumericIdentifiers && numericIdentifierRegExp.test(rightIdentifier);
const leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
const rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
if (leftIsNumeric || rightIsNumeric) {
// Per https://semver.org/#spec-item-11:
//
// https://semver.org/#spec-item-11
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
if (leftIsNumeric !== rightIsNumeric) return leftIsNumeric ? Comparison.LessThan : Comparison.GreaterThan;
// Per https://semver.org/#spec-item-11:
//
// https://semver.org/#spec-item-11
// > identifiers consisting of only digits are compared numerically
const result = compareValues(+leftIdentifier, +rightIdentifier);
if (result) return result;
}
else {
// Per https://semver.org/#spec-item-11:
//
// https://semver.org/#spec-item-11
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
const result = compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
if (result) return result;
}
}
// Per https://semver.org/#spec-item-11:
//
// https://semver.org/#spec-item-11
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
// > of the preceding identifiers are equal.
return compareValues(left.length, right.length);

View File

@ -21,13 +21,13 @@ namespace ts.JsTyping {
export interface CachedTyping {
typingLocation: string;
version: Semver;
version: Version;
}
/* @internal */
export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike<string>) {
const availableVersion = Semver.parse(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
return !availableVersion.greaterThan(cachedTyping.version);
const availableVersion = new Version(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
return availableVersion.compareTo(cachedTyping.version) <= 0;
}
/* @internal */

View File

@ -1,61 +0,0 @@
/* @internal */
namespace ts {
function stringToInt(str: string): number {
const n = parseInt(str, 10);
if (isNaN(n)) {
throw new Error(`Error in parseInt(${JSON.stringify(str)})`);
}
return n;
}
const isPrereleaseRegex = /^(.*)-next.\d+/;
const prereleaseSemverRegex = /^(\d+)\.(\d+)\.0-next.(\d+)$/;
const semverRegex = /^(\d+)\.(\d+)\.(\d+)$/;
export class Semver {
static parse(semver: string): Semver {
const isPrerelease = isPrereleaseRegex.test(semver);
const result = Semver.tryParse(semver, isPrerelease);
if (!result) {
throw new Error(`Unexpected semver: ${semver} (isPrerelease: ${isPrerelease})`);
}
return result;
}
static fromRaw({ major, minor, patch, isPrerelease }: Semver): Semver {
return new Semver(major, minor, patch, isPrerelease);
}
// This must parse the output of `versionString`.
private static tryParse(semver: string, isPrerelease: boolean): Semver | undefined {
// Per the semver spec <http://semver.org/#spec-item-2>:
// "A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers, and MUST NOT contain leading zeroes."
const rgx = isPrerelease ? prereleaseSemverRegex : semverRegex;
const match = rgx.exec(semver);
return match ? new Semver(stringToInt(match[1]), stringToInt(match[2]), stringToInt(match[3]), isPrerelease) : undefined;
}
private constructor(
readonly major: number, readonly minor: number, readonly patch: number,
/**
* If true, this is `major.minor.0-next.patch`.
* If false, this is `major.minor.patch`.
*/
readonly isPrerelease: boolean) { }
get versionString(): string {
return this.isPrerelease ? `${this.major}.${this.minor}.0-next.${this.patch}` : `${this.major}.${this.minor}.${this.patch}`;
}
equals(sem: Semver): boolean {
return this.major === sem.major && this.minor === sem.minor && this.patch === sem.patch && this.isPrerelease === sem.isPrerelease;
}
greaterThan(sem: Semver): boolean {
return this.major > sem.major || this.major === sem.major
&& (this.minor > sem.minor || this.minor === sem.minor
&& (!this.isPrerelease && sem.isPrerelease || this.isPrerelease === sem.isPrerelease
&& this.patch > sem.patch));
}
}
}

View File

@ -16,7 +16,6 @@
"files": [
"shared.ts",
"types.ts",
"jsTyping.ts",
"semver.ts"
"jsTyping.ts"
]
}

View File

@ -73,6 +73,7 @@
"unittests/publicApi.ts",
"unittests/reuseProgramStructure.ts",
"unittests/session.ts",
"unittests/semver.ts",
"unittests/symbolWalker.ts",
"unittests/telemetry.ts",
"unittests/textChanges.ts",

View File

@ -0,0 +1,94 @@
namespace ts {
describe("semver", () => {
describe("Version", () => {
function assertVersion(version: Version, [major, minor, patch, prerelease, build]: [number, number, number, string[]?, string[]?]) {
assert.strictEqual(version.major, major);
assert.strictEqual(version.minor, minor);
assert.strictEqual(version.patch, patch);
assert.deepEqual(version.prerelease, prerelease || emptyArray);
assert.deepEqual(version.build, build || emptyArray);
}
describe("new", () => {
it("text", () => {
assertVersion(new Version("1.2.3-pre.4+build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]);
});
it("parts", () => {
assertVersion(new Version(1, 2, 3, "pre.4", "build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]);
assertVersion(new Version(1, 2, 3), [1, 2, 3]);
assertVersion(new Version(1, 2), [1, 2, 0]);
assertVersion(new Version(1), [1, 0, 0]);
});
});
it("toString", () => {
assert.strictEqual(new Version(1, 2, 3, "pre.4", "build.5").toString(), "1.2.3-pre.4+build.5");
assert.strictEqual(new Version(1, 2, 3, "pre.4").toString(), "1.2.3-pre.4");
assert.strictEqual(new Version(1, 2, 3, /*prerelease*/ undefined, "build.5").toString(), "1.2.3+build.5");
assert.strictEqual(new Version(1, 2, 3).toString(), "1.2.3");
assert.strictEqual(new Version(1, 2).toString(), "1.2.0");
assert.strictEqual(new Version(1).toString(), "1.0.0");
});
it("compareTo", () => {
// https://semver.org/#spec-item-11
// > Precedence is determined by the first difference when comparing each of these
// > identifiers from left to right as follows: Major, minor, and patch versions are
// > always compared numerically.
assert.strictEqual(new Version("1.0.0").compareTo(new Version("2.0.0")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.1.0")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.1")), Comparison.LessThan);
assert.strictEqual(new Version("2.0.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.1.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.1").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0")), Comparison.EqualTo);
// https://semver.org/#spec-item-11
// > When major, minor, and patch are equal, a pre-release version has lower
// > precedence than a normal version.
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0-pre")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.1-pre").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-pre").compareTo(new Version("1.0.0")), Comparison.LessThan);
// https://semver.org/#spec-item-11
// > identifiers consisting of only digits are compared numerically
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-1")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-1").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-2").compareTo(new Version("1.0.0-10")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-10").compareTo(new Version("1.0.0-2")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo);
// https://semver.org/#spec-item-11
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-b")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-a-2").compareTo(new Version("1.0.0-a-10")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-b").compareTo(new Version("1.0.0-a")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-a")), Comparison.EqualTo);
assert.strictEqual(new Version("1.0.0-A").compareTo(new Version("1.0.0-a")), Comparison.LessThan);
// https://semver.org/#spec-item-11
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-alpha")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo);
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha")), Comparison.EqualTo);
// https://semver.org/#spec-item-11
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
// > of the preceding identifiers are equal.
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha.0")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-alpha.0").compareTo(new Version("1.0.0-alpha")), Comparison.GreaterThan);
// https://semver.org/#spec-item-11
// > Precedence for two pre-release versions with the same major, minor, and patch version
// > MUST be determined by comparing each dot separated identifier from left to right until
// > a difference is found [...]
assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-a.0.b.2")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-b.0.a.1")), Comparison.LessThan);
assert.strictEqual(new Version("1.0.0-a.0.b.2").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan);
assert.strictEqual(new Version("1.0.0-b.0.a.1").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan);
// https://semver.org/#spec-item-11
// > Build metadata does not figure into precedence
assert.strictEqual(new Version("1.0.0+build").compareTo(new Version("1.0.0")), Comparison.EqualTo);
});
});
});
}

View File

@ -1322,7 +1322,7 @@ namespace ts.projectSystem {
content: ""
};
const host = createServerHost([f, node]);
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } });
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: new Version("1.3.0") } });
const registry = createTypesRegistry("node");
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], registry);
@ -1344,7 +1344,7 @@ namespace ts.projectSystem {
content: ""
};
const host = createServerHost([f, node]);
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } });
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: new Version("1.3.0") } });
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], emptyMap);
assert.deepEqual(logger.finish(), [
@ -1401,8 +1401,8 @@ namespace ts.projectSystem {
};
const host = createServerHost([app]);
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
node: { typingLocation: node.path, version: Semver.parse("1.3.0") },
commander: { typingLocation: commander.path, version: Semver.parse("1.0.0") }
node: { typingLocation: node.path, version: new Version("1.3.0") },
commander: { typingLocation: commander.path, version: new Version("1.0.0") }
});
const registry = createTypesRegistry("node", "commander");
const logger = trackingLogger();
@ -1427,7 +1427,7 @@ namespace ts.projectSystem {
};
const host = createServerHost([app]);
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
node: { typingLocation: node.path, version: Semver.parse("1.0.0") }
node: { typingLocation: node.path, version: new Version("1.0.0") }
});
const registry = createTypesRegistry("node");
registry.delete(`ts${versionMajorMinor}`);
@ -1458,8 +1458,8 @@ namespace ts.projectSystem {
};
const host = createServerHost([app]);
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
node: { typingLocation: node.path, version: Semver.parse("1.3.0-next.0") },
commander: { typingLocation: commander.path, version: Semver.parse("1.3.0-next.0") }
node: { typingLocation: node.path, version: new Version("1.3.0-next.0") },
commander: { typingLocation: commander.path, version: new Version("1.3.0-next.0") }
});
const registry = createTypesRegistry("node", "commander");
registry.get("node")![`ts${versionMajorMinor}`] = "1.3.0-next.1";

View File

@ -252,8 +252,11 @@ namespace ts.server.typingsInstaller {
}
const info = getProperty(npmLock.dependencies, key);
const version = info && info.version;
const semver = Semver.parse(version!); // TODO: GH#18217
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: semver };
if (!version) {
continue;
}
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: new Version(version) };
this.packageNameToTypingLocation.set(packageName, newTyping);
}
}
@ -356,7 +359,7 @@ namespace ts.server.typingsInstaller {
// packageName is guaranteed to exist in typesRegistry by filterTypings
const distTags = this.typesRegistry.get(packageName)!;
const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]);
const newVersion = new Version(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]);
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion };
this.packageNameToTypingLocation.set(packageName, newTyping);
installedTypingFiles.push(typingFile);

View File

@ -2,7 +2,7 @@
"======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.",
@ -21,7 +21,7 @@
"======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.",
@ -33,7 +33,7 @@
"Directory 'node_modules' does not exist, skipping all lookups in it.",
"Directory '/node_modules' does not exist, skipping all lookups in it.",
"Loading module 'ext/other' from 'node_modules' folder, target file type 'JavaScript'.",
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.js' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.jsx' does not exist.",

View File

@ -2,7 +2,7 @@
"======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.",
@ -21,7 +21,7 @@
"======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.",