Merge pull request #26568 from Microsoft/typesVersions

Adds support for "typesVersions" redirects
This commit is contained in:
Ron Buckton 2018-09-07 15:40:50 -07:00 committed by GitHub
commit af8e44ac85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
69 changed files with 2436 additions and 331 deletions

View file

@ -2292,12 +2292,12 @@ namespace ts {
? chainDiagnosticMessages(
/*details*/ undefined,
Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1,
packageId.name, getMangledNameForScopedPackage(packageId.name))
packageId.name, mangleScopedPackageName(packageId.name))
: chainDiagnosticMessages(
/*details*/ undefined,
Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
moduleReference,
getMangledNameForScopedPackage(packageId.name))
mangleScopedPackageName(packageId.name))
: undefined;
errorOrSuggestion(isError, errorNode, chainDiagnosticMessages(
errorInfo,

View file

@ -65,6 +65,7 @@ namespace ts {
/* @internal */
namespace ts {
export const emptyArray: never[] = [] as never[];
/** Create a MapLike with good performance. */
function createDictionaryObject<T>(): MapLike<T> {

View file

@ -3294,7 +3294,7 @@
"category": "Message",
"code": 6104
},
"Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.": {
"Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": {
"category": "Message",
"code": 6105
},
@ -3692,6 +3692,22 @@
"category": "Error",
"code": 6205
},
"'package.json' has a 'typesVersions' field with version-specific path mappings.": {
"category": "Message",
"code": 6206
},
"'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": {
"category": "Message",
"code": 6207
},
"'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.": {
"category": "Message",
"code": 6208
},
"'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range.": {
"category": "Message",
"code": 6209
},
"Projects to reference": {
"category": "Message",

View file

@ -24,6 +24,13 @@ namespace ts {
return withPackageId(/*packageId*/ undefined, r);
}
function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined {
if (r) {
Debug.assert(r.packageId === undefined);
return { path: r.path, ext: r.extension };
}
}
/** Result of trying to resolve a module. */
interface Resolved {
path: string;
@ -82,12 +89,14 @@ namespace ts {
host: ModuleResolutionHost;
compilerOptions: CompilerOptions;
traceEnabled: boolean;
failedLookupLocations: Push<string>;
}
/** Just the fields that we use for module resolution. */
interface PackageJsonPathFields {
typings?: string;
types?: string;
typesVersions?: MapLike<MapLike<string[]>>;
main?: string;
}
@ -96,48 +105,111 @@ namespace ts {
version?: string;
}
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
function tryReadPackageJsonFields(readTypes: boolean, jsonContent: PackageJsonPathFields, baseDirectory: string, state: ModuleResolutionState): string | undefined {
return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main");
type MatchingKeys<TRecord, TMatch, K extends keyof TRecord = keyof TRecord> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;
function tryReadFromField(fieldName: "typings" | "types" | "main"): string | undefined {
if (!hasProperty(jsonContent, fieldName)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName);
}
return;
}
const fileName = jsonContent[fieldName];
if (!isString(fileName)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName);
}
return;
}
const path = normalizePath(combinePaths(baseDirectory, fileName));
function readPackageJsonField<TMatch, K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined;
function readPackageJsonField<K extends MatchingKeys<PackageJson, object | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined;
function readPackageJsonField<K extends keyof PackageJson>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string" | "object", state: ModuleResolutionState): PackageJson[K] | undefined {
if (!hasProperty(jsonContent, fieldName)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName);
}
return path;
return;
}
const value = jsonContent[fieldName];
if (typeof value !== typeOfTag || value === null) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
}
return;
}
return value;
}
/* @internal */
export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object {
try {
const jsonText = host.readFile(path);
if (!jsonText) return {};
const result = parseConfigFileTextToJson(path, jsonText);
if (result.error) {
return {};
}
return result.config;
function readPackageJsonPathField<K extends "typings" | "types" | "main">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
const fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
if (fileName === undefined) return;
const path = normalizePath(combinePaths(baseDirectory, fileName));
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
}
catch (e) {
// gracefully handle if readFile fails or returns not JSON
return {};
return path;
}
function readPackageJsonTypesFields(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
return readPackageJsonPathField(jsonContent, "typings", baseDirectory, state)
|| readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
}
function readPackageJsonMainField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
}
function readPackageJsonTypesVersionsField(jsonContent: PackageJson, state: ModuleResolutionState) {
const typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state);
if (typesVersions === undefined) return;
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings);
}
return typesVersions;
}
interface VersionPaths {
version: string;
paths: MapLike<string[]>;
}
function readPackageJsonTypesVersionPaths(jsonContent: PackageJson, state: ModuleResolutionState): VersionPaths | undefined {
const typesVersions = readPackageJsonTypesVersionsField(jsonContent, state);
if (typesVersions === undefined) return;
if (state.traceEnabled) {
for (const key in typesVersions) {
if (hasProperty(typesVersions, key) && !VersionRange.tryParse(key)) {
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key);
}
}
}
const result = getPackageJsonTypesVersionsPaths(typesVersions);
if (!result) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor);
}
return;
}
const { version: bestVersionKey, paths: bestVersionPaths } = result;
if (typeof bestVersionPaths !== "object") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "object", typeof bestVersionPaths);
}
return;
}
return result;
}
let typeScriptVersion: Version | undefined;
/* @internal */
export function getPackageJsonTypesVersionsPaths(typesVersions: MapLike<MapLike<string[]>>) {
if (!typeScriptVersion) typeScriptVersion = new Version(version);
for (const key in typesVersions) {
if (!hasProperty(typesVersions, key)) continue;
const keyRange = VersionRange.tryParse(key);
if (keyRange === undefined) {
continue;
}
// return the first entry whose range matches the current compiler version.
if (keyRange.test(typeScriptVersion)) {
return { version: key, paths: typesVersions[key] };
}
}
}
@ -188,7 +260,8 @@ namespace ts {
*/
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(options, host);
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled };
const failedLookupLocations: string[] = [];
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations };
const typeRoots = getEffectiveTypeRoots(options, host);
if (traceEnabled) {
@ -210,8 +283,6 @@ namespace ts {
}
}
const failedLookupLocations: string[] = [];
let resolved = primaryLookup();
let primary = true;
if (!resolved) {
@ -247,7 +318,7 @@ namespace ts {
trace(host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
}
return resolvedTypeScriptOnly(
loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations,
loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate,
!directoryExists, moduleResolutionState));
});
}
@ -266,7 +337,7 @@ namespace ts {
if (traceEnabled) {
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
}
const result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined);
const result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined);
const resolvedFile = resolvedTypeScriptOnly(result && result.value);
if (!resolvedFile && traceEnabled) {
trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
@ -304,7 +375,7 @@ namespace ts {
if (host.directoryExists(root)) {
for (const typeDirectivePath of host.getDirectories(root)) {
const normalized = normalizePath(typeDirectivePath);
const packageJsonPath = pathToPackageJson(combinePaths(root, normalized));
const packageJsonPath = combinePaths(root, normalized, "package.json");
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
// See `createNotNeededPackageJSON` in the types-publisher` repo.
// tslint:disable-next-line:no-null-keyword
@ -527,7 +598,7 @@ namespace ts {
* 'typings' entry or file 'index' with some supported extension
* - Classic loader will only try to interpret '/a/b/c' as file.
*/
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;
/**
* Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
@ -590,18 +661,18 @@ namespace ts {
* entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
*/
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
state: ModuleResolutionState): Resolved | undefined {
if (!isExternalModuleNameRelative(moduleName)) {
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
}
else {
return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state);
}
}
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.rootDirs) {
return undefined;
@ -646,7 +717,7 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
}
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(containingDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@ -665,7 +736,7 @@ namespace ts {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate);
}
const baseDirectory = getDirectoryPath(candidate);
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(baseDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@ -677,60 +748,28 @@ namespace ts {
return undefined;
}
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.baseUrl) {
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined {
const { baseUrl, paths } = state.compilerOptions;
if (!baseUrl) {
return undefined;
}
if (state.traceEnabled) {
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, state.compilerOptions.baseUrl, moduleName);
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
}
// string is for exact match
let matchedPattern: Pattern | string | undefined;
if (state.compilerOptions.paths) {
if (paths) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
}
matchedPattern = matchPatternOrExact(getOwnKeys(state.compilerOptions.paths), moduleName);
}
if (matchedPattern) {
const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName);
const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern);
if (state.traceEnabled) {
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
const resolved = tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
if (resolved) {
return resolved.value;
}
return forEach(state.compilerOptions.paths![matchedPatternText], subst => {
const path = matchedStar ? subst.replace("*", matchedStar) : subst;
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl!, path));
if (state.traceEnabled) {
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
}
// A path mapping may have an extension, in contrast to an import, which should omit it.
const extension = tryGetExtensionFromPath(candidate);
if (extension !== undefined) {
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
if (path !== undefined) {
return noPackageId({ path, ext: extension });
}
}
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
});
}
else {
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl, moduleName));
if (state.traceEnabled) {
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
}
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
const candidate = normalizePath(combinePaths(baseUrl, moduleName));
if (state.traceEnabled) {
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
}
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
return loader(extensions, candidate, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
}
/**
@ -748,11 +787,15 @@ namespace ts {
return resolvedModule.resolvedFileName;
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
}
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
const result = jsOnly ?
tryResolve(Extensions.JavaScript) :
@ -766,8 +809,8 @@ namespace ts {
return { resolvedModule: undefined, failedLookupLocations };
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true);
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true);
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
if (resolved) {
return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) });
}
@ -776,7 +819,7 @@ namespace ts {
if (traceEnabled) {
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache);
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache);
if (!resolved) return undefined;
let resolvedValue = resolved.value;
@ -790,7 +833,7 @@ namespace ts {
}
else {
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
// Treat explicit "node_modules" import as an external library import.
return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") });
}
@ -810,7 +853,7 @@ namespace ts {
return real;
}
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined {
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
}
@ -824,10 +867,11 @@ namespace ts {
onlyRecordFailures = true;
}
}
const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
const resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
if (resolvedFromFile) {
const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId;
const packageInfo = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, /*onlyRecordFailures*/ false, state);
const packageId = packageInfo && packageInfo.packageId;
return withPackageId(packageId, resolvedFromFile);
}
}
@ -840,7 +884,7 @@ namespace ts {
onlyRecordFailures = true;
}
}
return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson);
return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
}
/*@internal*/
@ -886,34 +930,28 @@ namespace ts {
if (endsWith(path, ".d.ts")) {
return path;
}
if (endsWith(path, "/index")) {
if (path === "index" || endsWith(path, "/index")) {
return path + ".d.ts";
}
return path + "/index.d.ts";
}
/* @internal */
export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean {
// if host does not support 'directoryExists' assume that directory will exist
return !host.directoryExists || host.directoryExists(directoryName);
}
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state));
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
}
/**
* @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
*/
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
if (extensions === Extensions.Json) {
const extensionLess = tryRemoveExtension(candidate, Extension.Json);
return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state);
return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, onlyRecordFailures, state);
}
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state);
if (resolvedByAddingExtension) {
return resolvedByAddingExtension;
}
@ -926,12 +964,12 @@ namespace ts {
const extension = candidate.substring(extensionless.length);
trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
}
return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state);
}
}
/** Try to return an existing file that adds one of the `extensions` to `candidate`. */
function tryAddingExtensions(candidate: string, extensions: Extensions, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
function tryAddingExtensions(candidate: string, extensions: Extensions, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
if (!onlyRecordFailures) {
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
const directory = getDirectoryPath(candidate);
@ -952,13 +990,13 @@ namespace ts {
}
function tryExtension(ext: Extension): PathAndExtension | undefined {
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
const path = tryFile(candidate + ext, onlyRecordFailures, state);
return path === undefined ? undefined : { path, ext };
}
}
/** Return the file if it exists. */
function tryFile(fileName: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
function tryFile(fileName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
if (!onlyRecordFailures) {
if (state.host.fileExists(fileName)) {
if (state.traceEnabled) {
@ -972,47 +1010,48 @@ namespace ts {
}
}
}
failedLookupLocations.push(fileName);
state.failedLookupLocations.push(fileName);
return undefined;
}
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
const { packageJsonContent, packageId } = considerPackageJson
? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state)
: { packageJsonContent: undefined, packageId: undefined };
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent));
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, "", onlyRecordFailures, state) : undefined;
const packageId = packageInfo && packageInfo.packageId;
const packageJsonContent = packageInfo && packageInfo.packageJsonContent;
const versionPaths = packageJsonContent && readPackageJsonTypesVersionPaths(packageJsonContent, state);
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
}
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined): PathAndExtension | undefined {
const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state);
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined {
const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, versionPaths, extensions, candidate, state);
if (fromPackageJson) {
return fromPackageJson;
}
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), !directoryExists, state);
}
function getPackageJsonInfo(
nodeModuleDirectory: string,
subModuleName: string,
failedLookupLocations: Push<string>,
onlyRecordFailures: boolean,
state: ModuleResolutionState,
): { found: boolean, packageJsonContent: PackageJsonPathFields | undefined, packageId: PackageId | undefined } {
interface PackageJsonInfo {
packageJsonContent: PackageJsonPathFields | undefined;
packageId: PackageId | undefined;
versionPaths: VersionPaths | undefined;
}
function getPackageJsonInfo(packageDirectory: string, subModuleName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
const { host, traceEnabled } = state;
const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host);
const packageJsonPath = pathToPackageJson(nodeModuleDirectory);
const directoryExists = !onlyRecordFailures && directoryProbablyExists(packageDirectory, host);
const packageJsonPath = combinePaths(packageDirectory, "package.json");
if (directoryExists && host.fileExists(packageJsonPath)) {
const packageJsonContent = readJson(packageJsonPath, host) as PackageJson;
if (subModuleName === "") { // looking up the root - need to handle types/typings/main redirects for subModuleName
const path = tryReadPackageJsonFields(/*readTypes*/ true, packageJsonContent, nodeModuleDirectory, state);
const path = readPackageJsonTypesFields(packageJsonContent, packageDirectory, state);
if (typeof path === "string") {
subModuleName = addExtensionAndIndex(path.substring(nodeModuleDirectory.length + 1));
subModuleName = addExtensionAndIndex(path.substring(packageDirectory.length + 1));
}
else {
const jsPath = tryReadPackageJsonFields(/*readTypes*/ false, packageJsonContent, nodeModuleDirectory, state);
if (typeof jsPath === "string" && jsPath.length > nodeModuleDirectory.length) {
const potentialSubModule = jsPath.substring(nodeModuleDirectory.length + 1);
const jsPath = readPackageJsonMainField(packageJsonContent, packageDirectory, state);
if (typeof jsPath === "string" && jsPath.length > packageDirectory.length) {
const potentialSubModule = jsPath.substring(packageDirectory.length + 1);
subModuleName = (forEach(supportedJavascriptExtensions, extension =>
tryRemoveExtension(potentialSubModule, extension)) || potentialSubModule) + Extension.Dts;
}
@ -1021,9 +1060,12 @@ namespace ts {
}
}
}
if (!endsWith(subModuleName, Extension.Dts)) {
subModuleName = addExtensionAndIndex(subModuleName);
}
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
const packageId: PackageId | undefined = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
: undefined;
@ -1035,24 +1077,27 @@ namespace ts {
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
}
return { found: true, packageJsonContent, packageId };
return { packageJsonContent, packageId, versionPaths };
}
else {
if (directoryExists && traceEnabled) {
trace(host, Diagnostics.File_0_does_not_exist, packageJsonPath);
}
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
failedLookupLocations.push(packageJsonPath);
return { found: false, packageJsonContent: undefined, packageId: undefined };
state.failedLookupLocations.push(packageJsonPath);
}
}
function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): PathAndExtension | undefined {
let file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript && extensions !== Extensions.Json, jsonContent, candidate, state);
function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, versionPaths: VersionPaths | undefined, extensions: Extensions, candidate: string, state: ModuleResolutionState): PathAndExtension | undefined {
let file = extensions !== Extensions.JavaScript && extensions !== Extensions.Json
? readPackageJsonTypesFields(jsonContent, candidate, state)
: readPackageJsonMainField(jsonContent, candidate, state);
if (!file) {
if (extensions === Extensions.TypeScript) {
// When resolving typescript modules, try resolving using main field as well
file = tryReadPackageJsonFields(/*readTypes*/ false, jsonContent, candidate, state);
file = readPackageJsonMainField(jsonContent, candidate, state);
if (!file) {
return undefined;
}
@ -1062,27 +1107,39 @@ namespace ts {
}
}
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host);
const fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state);
if (fromFile) {
const resolved = resolvedIfExtensionMatches(extensions, fromFile);
if (resolved) {
return resolved;
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
const fromFile = tryFile(candidate, onlyRecordFailures, state);
if (fromFile) {
const resolved = resolvedIfExtensionMatches(extensions, fromFile);
if (resolved) {
return noPackageId(resolved);
}
if (state.traceEnabled) {
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
}
}
// Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
// Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false);
};
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host);
if (versionPaths && containsPath(candidate, file)) {
const moduleName = getRelativePathFromDirectory(candidate, file, /*ignoreCase*/ false);
if (state.traceEnabled) {
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, moduleName);
}
const result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailures, state);
if (result) {
return removeIgnoredPackageId(result.value);
}
}
// Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
// Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
const result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false);
if (result) {
// It won't have a `packageId` set, because we disabled `considerPackageJson`.
Debug.assert(result.packageId === undefined);
return { path: result.path, ext: result.extension };
}
// It won't have a `packageId` set, because we disabled `considerPackageJson`.
return removeIgnoredPackageId(loader(extensions, file, onlyRecordFailures, state));
}
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
@ -1105,34 +1162,8 @@ namespace ts {
}
}
function pathToPackageJson(directory: string): string {
return combinePaths(directory, "package.json");
}
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
let packageJsonContent: PackageJsonPathFields | undefined;
let packageId: PackageId | undefined;
const packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state);
if (packageInfo.found) {
({ packageJsonContent, packageId } = packageInfo);
}
else {
const { packageName, rest } = getPackageName(moduleName);
if (rest !== "") { // If "rest" is empty, we just did this search above.
const packageRootPath = combinePaths(nodeModulesFolder, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId.
packageId = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state).packageId;
}
}
const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
return withPackageId(packageId, pathAndExtension);
}
/* @internal */
export function getPackageName(moduleName: string): { packageName: string, rest: string } {
export function parsePackageName(moduleName: string): { packageName: string, rest: string } {
let idx = moduleName.indexOf(directorySeparator);
if (moduleName[0] === "@") {
idx = moduleName.indexOf(directorySeparator, idx + 1);
@ -1140,36 +1171,36 @@ namespace ts {
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
}
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache);
}
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): SearchResult<Resolved> {
// Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined);
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache);
}
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, typesOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, directory: string, state: ModuleResolutionState): SearchResult<Resolved> {
// Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined);
}
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host, failedLookupLocations);
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
if (resolutionFromCache) {
return resolutionFromCache;
}
return toSearchResult(loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly));
return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly));
}
});
}
/** Load a module from a single node_modules directory, but not from any ancestors' node_modules directories. */
function loadModuleFromNodeModulesOneLevel(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, typesOnly = false): Resolved | undefined {
function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean): Resolved | undefined {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
if (!nodeModulesFolderExists && state.traceEnabled) {
trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
}
const packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state);
const packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state);
if (packageResult) {
return packageResult;
}
@ -1182,7 +1213,84 @@ namespace ts {
}
nodeModulesAtTypesExists = false;
}
return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state);
return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, state);
}
}
function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState): Resolved | undefined {
const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName));
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
let packageJsonContent: PackageJsonPathFields | undefined;
let packageId: PackageId | undefined;
let versionPaths: VersionPaths | undefined;
const packageInfo = getPackageJsonInfo(candidate, "", !nodeModulesDirectoryExists, state);
if (packageInfo) {
({ packageJsonContent, packageId, versionPaths } = packageInfo);
const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
if (fromFile) {
return noPackageId(fromFile);
}
const fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageJsonContent, versionPaths);
return withPackageId(packageId, fromDirectory);
}
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
const pathAndExtension =
loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths);
return withPackageId(packageId, pathAndExtension);
};
const { packageName, rest } = parsePackageName(moduleName);
if (rest !== "") { // If "rest" is empty, we just did this search above.
const packageDirectory = combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
const packageInfo = getPackageJsonInfo(packageDirectory, rest, !nodeModulesDirectoryExists, state);
if (packageInfo) ({ packageId, versionPaths } = packageInfo);
if (versionPaths) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, rest);
}
const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host);
const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, versionPaths.paths, loader, !packageDirectoryExists, state);
if (fromPaths) {
return fromPaths.value;
}
}
}
return loader(extensions, candidate, !nodeModulesDirectoryExists, state);
}
function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, baseDirectory: string, paths: MapLike<string[]>, loader: ResolutionKindSpecificLoader, onlyRecordFailures: boolean, state: ModuleResolutionState): SearchResult<Resolved> {
const matchedPattern = matchPatternOrExact(getOwnKeys(paths), moduleName);
if (matchedPattern) {
const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName);
const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern);
if (state.traceEnabled) {
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
}
const resolved = forEach(paths[matchedPatternText], subst => {
const path = matchedStar ? subst.replace("*", matchedStar) : subst;
const candidate = normalizePath(combinePaths(baseDirectory, path));
if (state.traceEnabled) {
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
}
// A path mapping may have an extension, in contrast to an import, which should omit it.
const extension = tryGetExtensionFromPath(candidate);
if (extension !== undefined) {
const path = tryFile(candidate, onlyRecordFailures, state);
if (path !== undefined) {
return noPackageId({ path, ext: extension });
}
}
return loader(extensions, candidate, onlyRecordFailures || !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
});
return { value: resolved };
}
}
@ -1190,8 +1298,8 @@ namespace ts {
const mangledScopedPackageSeparator = "__";
/** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
function mangleScopedPackage(packageName: string, state: ModuleResolutionState): string {
const mangled = getMangledNameForScopedPackage(packageName);
function mangleScopedPackageNameWithTrace(packageName: string, state: ModuleResolutionState): string {
const mangled = mangleScopedPackageName(packageName);
if (state.traceEnabled && mangled !== packageName) {
trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled);
}
@ -1200,11 +1308,11 @@ namespace ts {
/* @internal */
export function getTypesPackageName(packageName: string): string {
return `@types/${getMangledNameForScopedPackage(packageName)}`;
return `@types/${mangleScopedPackageName(packageName)}`;
}
/* @internal */
export function getMangledNameForScopedPackage(packageName: string): string {
export function mangleScopedPackageName(packageName: string): string {
if (startsWith(packageName, "@")) {
const replaceSlash = packageName.replace(directorySeparator, mangledScopedPackageSeparator);
if (replaceSlash !== packageName) {
@ -1215,36 +1323,36 @@ namespace ts {
}
/* @internal */
export function getPackageNameFromAtTypesDirectory(mangledName: string): string {
export function getPackageNameFromTypesPackageName(mangledName: string): string {
const withoutAtTypePrefix = removePrefix(mangledName, "@types/");
if (withoutAtTypePrefix !== mangledName) {
return getUnmangledNameForScopedPackage(withoutAtTypePrefix);
return unmangleScopedPackageName(withoutAtTypePrefix);
}
return mangledName;
}
/* @internal */
export function getUnmangledNameForScopedPackage(typesPackageName: string): string {
export function unmangleScopedPackageName(typesPackageName: string): string {
return stringContains(typesPackageName, mangledScopedPackageSeparator) ?
"@" + typesPackageName.replace(mangledScopedPackageSeparator, directorySeparator) :
typesPackageName;
}
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost, failedLookupLocations: Push<string>): SearchResult<Resolved> {
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, state: ModuleResolutionState): SearchResult<Resolved> {
const result = cache && cache.get(containingDirectory);
if (result) {
if (traceEnabled) {
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
if (state.traceEnabled) {
trace(state.host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
}
failedLookupLocations.push(...result.failedLookupLocations);
state.failedLookupLocations.push(...result.failedLookupLocations);
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
}
}
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
const containingDirectory = getDirectoryPath(containingFile);
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
@ -1252,7 +1360,7 @@ namespace ts {
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
if (resolvedUsingSettings) {
return { value: resolvedUsingSettings };
}
@ -1261,24 +1369,24 @@ namespace ts {
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
// Climb up parent directories looking for a module.
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host, failedLookupLocations);
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
if (resolutionFromCache) {
return resolutionFromCache;
}
const searchName = normalizePath(combinePaths(directory, moduleName));
return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state));
return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state));
});
if (resolved) {
return resolved;
}
if (extensions === Extensions.TypeScript) {
// If we didn't find the file normally, look it up in @types.
return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
}
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state));
return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state));
}
}
}
@ -1293,9 +1401,9 @@ namespace ts {
if (traceEnabled) {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
}
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
}

View file

@ -235,7 +235,8 @@ namespace ts.moduleSpecifiers {
const suffix = pattern.substr(indexOfStar + 1);
if (relativeToBaseUrl.length >= prefix.length + suffix.length &&
startsWith(relativeToBaseUrl, prefix) &&
endsWith(relativeToBaseUrl, suffix)) {
endsWith(relativeToBaseUrl, suffix) ||
!suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) {
const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
return key.replace("*", matchedStar);
}
@ -264,6 +265,26 @@ namespace ts.moduleSpecifiers {
return undefined;
}
const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
const packageJsonPath = combinePaths(packageRootPath, "package.json");
const packageJsonContent = host.fileExists!(packageJsonPath)
? JSON.parse(host.readFile!(packageJsonPath)!)
: undefined;
const versionPaths = packageJsonContent && packageJsonContent.typesVersions
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
: undefined;
if (versionPaths) {
const subModuleName = moduleFileName.slice(parts.packageRootIndex + 1);
const fromPaths = tryGetModuleNameFromPaths(
removeFileExtension(subModuleName),
removeExtensionAndIndexPostFix(subModuleName, Ending.Minimal, options),
versionPaths.paths
);
if (fromPaths !== undefined) {
moduleFileName = combinePaths(moduleFileName.slice(0, parts.packageRootIndex), fromPaths);
}
}
// Simplify the full file path to something that can be resolved by Node.
// If the module could be imported by a directory name, use that directory's name
@ -274,23 +295,18 @@ namespace ts.moduleSpecifiers {
// If the module was found in @types, get the actual Node package name
const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
const packageName = getPackageNameFromAtTypesDirectory(nodeModulesDirectoryName);
const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
return getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
function getDirectoryOrExtensionlessFileName(path: string): string {
// If the file is the main module, it can be imported by the package name
const packageRootPath = path.substring(0, parts.packageRootIndex);
const packageJsonPath = combinePaths(packageRootPath, "package.json");
if (host.fileExists!(packageJsonPath)) { // TODO: GH#18217
const packageJsonContent = JSON.parse(host.readFile!(packageJsonPath)!);
if (packageJsonContent) {
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
if (mainFileRelative) {
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) {
return packageRootPath;
}
if (packageJsonContent) {
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
if (mainFileRelative) {
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) {
return packageRootPath;
}
}
}

391
src/compiler/semver.ts Normal file
View file

@ -0,0 +1,391 @@
/* @internal */
namespace ts {
// 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;
// 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;
// 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;
// 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, https://semver.org
*/
export class Version {
static readonly zero = new Version(0, 0, 0);
readonly major: number;
readonly minor: number;
readonly patch: number;
readonly prerelease: ReadonlyArray<string>;
readonly build: ReadonlyArray<string>;
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");
Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease");
Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build");
this.major = major;
this.minor = minor;
this.patch = patch;
this.prerelease = prerelease ? prerelease.split(".") : emptyArray;
this.build = build ? build.split(".") : emptyArray;
}
static tryParse(text: string) {
const result = tryParseComponents(text);
if (!result) return undefined;
const { major, minor, patch, prerelease, build } = result;
return new Version(major, minor, patch, prerelease, build);
}
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.
//
// 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 [...]
//
// 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);
}
increment(field: "major" | "minor" | "patch") {
switch (field) {
case "major": return new Version(this.major + 1, 0, 0);
case "minor": return new Version(this.major, this.minor + 1, 0);
case "patch": return new Version(this.major, this.minor, this.patch + 1);
default: return Debug.assertNever(field);
}
}
toString() {
let result = `${this.major}.${this.minor}.${this.patch}`;
if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`;
if (some(this.build)) result += `+${this.build.join(".")}`;
return result;
}
}
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;
// 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 [...]
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 = numericIdentifierRegExp.test(leftIdentifier);
const rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
if (leftIsNumeric || rightIsNumeric) {
// 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;
// https://semver.org/#spec-item-11
// > identifiers consisting of only digits are compared numerically
const result = compareValues(+leftIdentifier, +rightIdentifier);
if (result) return result;
}
else {
// 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;
}
}
// 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);
}
/**
* Describes a semantic version range, per https://github.com/npm/node-semver#ranges
*/
export class VersionRange {
private _alternatives: ReadonlyArray<ReadonlyArray<Comparator>>;
constructor(spec: string) {
this._alternatives = spec ? Debug.assertDefined(parseRange(spec), "Invalid range spec.") : emptyArray;
}
static tryParse(text: string) {
const sets = parseRange(text);
if (sets) {
const range = new VersionRange("");
range._alternatives = sets;
return range;
}
return undefined;
}
test(version: Version | string) {
if (typeof version === "string") version = new Version(version);
return testDisjunction(version, this._alternatives);
}
toString() {
return formatDisjunction(this._alternatives);
}
}
interface Comparator {
readonly operator: "<" | "<=" | ">" | ">=" | "=";
readonly operand: Version;
}
// https://github.com/npm/node-semver#range-grammar
//
// range-set ::= range ( logical-or range ) *
// range ::= hyphen | simple ( ' ' simple ) * | ''
// logical-or ::= ( ' ' ) * '||' ( ' ' ) *
const logicalOrRegExp = /\s*\|\|\s*/g;
const whitespaceRegExp = /\s+/g;
// https://github.com/npm/node-semver#range-grammar
//
// partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
// xr ::= 'x' | 'X' | '*' | nr
// nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
// qualifier ::= ( '-' pre )? ( '+' build )?
// pre ::= parts
// build ::= parts
// parts ::= part ( '.' part ) *
// part ::= nr | [-0-9A-Za-z]+
const partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
// https://github.com/npm/node-semver#range-grammar
//
// hyphen ::= partial ' - ' partial
const hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
// https://github.com/npm/node-semver#range-grammar
//
// simple ::= primitive | partial | tilde | caret
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
// tilde ::= '~' partial
// caret ::= '^' partial
const rangeRegExp = /^\s*(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
function parseRange(text: string) {
const alternatives: Comparator[][] = [];
for (const range of text.trim().split(logicalOrRegExp)) {
if (!range) continue;
const comparators: Comparator[] = [];
const match = hyphenRegExp.exec(range);
if (match) {
if (!parseHyphen(match[1], match[2], comparators)) return undefined;
}
else {
for (const simple of range.split(whitespaceRegExp)) {
const match = rangeRegExp.exec(simple);
if (!match || !parseComparator(match[1], match[2], comparators)) return undefined;
}
}
alternatives.push(comparators);
}
return alternatives;
}
function parsePartial(text: string) {
const match = partialRegExp.exec(text);
if (!match) return undefined;
const [, major, minor = "*", patch = "*", prerelease, build] = match;
const version = new Version(
isWildcard(major) ? 0 : parseInt(major, 10),
isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10),
isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10),
prerelease,
build);
return { version, major, minor, patch };
}
function parseHyphen(left: string, right: string, comparators: Comparator[]) {
const leftResult = parsePartial(left);
if (!leftResult) return false;
const rightResult = parsePartial(right);
if (!rightResult) return false;
if (!isWildcard(leftResult.major)) {
comparators.push(createComparator(">=", leftResult.version));
}
if (!isWildcard(rightResult.major)) {
comparators.push(
isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) :
isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) :
createComparator("<=", rightResult.version));
}
return true;
}
function parseComparator(operator: string, text: string, comparators: Comparator[]) {
const result = parsePartial(text);
if (!result) return false;
const { version, major, minor, patch } = result;
if (!isWildcard(major)) {
switch (operator) {
case "~":
comparators.push(createComparator(">=", version));
comparators.push(createComparator("<", version.increment(
isWildcard(minor) ? "major" :
"minor")));
break;
case "^":
comparators.push(createComparator(">=", version));
comparators.push(createComparator("<", version.increment(
version.major > 0 || isWildcard(minor) ? "major" :
version.minor > 0 || isWildcard(patch) ? "minor" :
"patch")));
break;
case "<":
case ">=":
comparators.push(createComparator(operator, version));
break;
case "<=":
case ">":
comparators.push(
isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) :
isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) :
createComparator(operator, version));
break;
case "=":
case undefined:
if (isWildcard(minor) || isWildcard(patch)) {
comparators.push(createComparator(">=", version));
comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor")));
}
else {
comparators.push(createComparator("=", version));
}
break;
default:
// unrecognized
return false;
}
}
else if (operator === "<" || operator === ">") {
comparators.push(createComparator("<", Version.zero));
}
return true;
}
function isWildcard(part: string) {
return part === "*" || part === "x" || part === "X";
}
function createComparator(operator: Comparator["operator"], operand: Version) {
return { operator, operand };
}
function testDisjunction(version: Version, alternatives: ReadonlyArray<ReadonlyArray<Comparator>>) {
// an empty disjunction is treated as "*" (all versions)
if (alternatives.length === 0) return true;
for (const alternative of alternatives) {
if (testAlternative(version, alternative)) return true;
}
return false;
}
function testAlternative(version: Version, comparators: ReadonlyArray<Comparator>) {
for (const comparator of comparators) {
if (!testComparator(version, comparator.operator, comparator.operand)) return false;
}
return true;
}
function testComparator(version: Version, operator: Comparator["operator"], operand: Version) {
const cmp = version.compareTo(operand);
switch (operator) {
case "<": return cmp < 0;
case "<=": return cmp <= 0;
case ">": return cmp > 0;
case ">=": return cmp >= 0;
case "=": return cmp === 0;
default: return Debug.assertNever(operator);
}
}
function formatDisjunction(alternatives: ReadonlyArray<ReadonlyArray<Comparator>>) {
return map(alternatives, formatAlternative).join(" || ") || "*";
}
function formatAlternative(comparators: ReadonlyArray<Comparator>) {
return map(comparators, formatComparator).join(" ");
}
function formatComparator(comparator: Comparator) {
return `${comparator.operator}${comparator.operand}`;
}
}

View file

@ -289,6 +289,13 @@ namespace ts {
if (startsWith(fileName, "./") && hasExtension(fileName)) {
fileName = fileName.substring(2);
}
// omit references to files from node_modules (npm may disambiguate module
// references when installing this package, making the path is unreliable).
if (startsWith(fileName, "node_modules/") || fileName.indexOf("/node_modules/") !== -1) {
return;
}
references.push({ pos: -1, end: -1, fileName });
}
};

View file

@ -9,6 +9,7 @@
"files": [
"core.ts",
"performance.ts",
"semver.ts",
"types.ts",
"sys.ts",

View file

@ -14,7 +14,6 @@ namespace ts {
/* @internal */
namespace ts {
export const emptyArray: never[] = [] as never[];
export const resolvingEmptyArray: never[] = [] as never[];
export const emptyMap = createMap<never>() as ReadonlyMap<never> & ReadonlyPragmaMap;
export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap<never> = emptyMap as ReadonlyUnderscoreEscapedMap<never>;
@ -3974,6 +3973,27 @@ namespace ts {
return getStringFromExpandedCharCodes(expandedCharCodes);
}
export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object {
try {
const jsonText = host.readFile(path);
if (!jsonText) return {};
const result = parseConfigFileTextToJson(path, jsonText);
if (result.error) {
return {};
}
return result.config;
}
catch (e) {
// gracefully handle if readFile fails or returns not JSON
return {};
}
}
export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean {
// if host does not support 'directoryExists' assume that directory will exist
return !host.directoryExists || host.directoryExists(directoryName);
}
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, getNewLine?: () => string): string {

View file

@ -82,4 +82,16 @@ namespace utils {
export function addUTF8ByteOrderMark(text: string) {
return getByteOrderMarkLength(text) === 0 ? "\u00EF\u00BB\u00BF" + text : text;
}
export function theory<T extends any[]>(name: string, cb: (...args: T) => void, data: T[]) {
for (const entry of data) {
it(`${name}(${entry.map(formatTheoryDatum).join(", ")})`, () => cb(...entry));
}
}
function formatTheoryDatum(value: any) {
return typeof value === "function" ? value.name || "<anonymous function>" :
value === undefined ? "undefined" :
JSON.stringify(value);
}
}

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

@ -29,7 +29,7 @@ namespace ts.codefix {
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number, diagCode: number): string | undefined {
const moduleName = cast(getTokenAtPosition(sourceFile, pos), isStringLiteral).text;
const { packageName } = getPackageName(moduleName);
const { packageName } = parsePackageName(moduleName);
return diagCode === errorCodeCannotFindModule
? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
: (host.isKnownTypesPackageName!(packageName) ? getTypesPackageName(packageName) : undefined); // TODO: GH#18217

View file

@ -151,11 +151,41 @@ namespace ts.Completions.PathCompletions {
}
}
}
// check for a version redirect
const packageJsonPath = findPackageJson(baseDirectory, host);
if (packageJsonPath) {
const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined });
const typesVersions = (packageJson as any).typesVersions;
if (typeof typesVersions === "object") {
const versionResult = getPackageJsonTypesVersionsPaths(typesVersions);
const versionPaths = versionResult && versionResult.paths;
const rest = absolutePath.slice(ensureTrailingDirectorySeparator(baseDirectory).length);
if (versionPaths) {
addCompletionEntriesFromPaths(result, rest, baseDirectory, extensions, versionPaths, host);
}
}
}
}
return result;
}
function addCompletionEntriesFromPaths(result: NameAndKind[], fragment: string, baseDirectory: string, fileExtensions: ReadonlyArray<string>, paths: MapLike<string[]>, host: LanguageServiceHost) {
for (const path in paths) {
if (!hasProperty(paths, path)) continue;
const patterns = paths[path];
if (patterns) {
for (const { name, kind } of getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host)) {
// Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
if (!result.some(entry => entry.name === name)) {
result.push(nameAndKind(name, kind));
}
}
}
}
}
/**
* Check all of the declared modules and those in node modules. Possible sources of modules:
* Modules that are found by the type checker
@ -171,19 +201,10 @@ namespace ts.Completions.PathCompletions {
const fileExtensions = getSupportedExtensionsForModuleResolution(compilerOptions);
if (baseUrl) {
const projectDir = compilerOptions.project || host.getCurrentDirectory();
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, host, /*exclude*/ undefined, result);
for (const path in paths!) {
const patterns = paths![path];
if (paths!.hasOwnProperty(path) && patterns) {
for (const { name, kind } of getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host)) {
// Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
if (!result.some(entry => entry.name === name)) {
result.push(nameAndKind(name, kind));
}
}
}
const absolute = normalizePath(combinePaths(projectDir, baseUrl));
getCompletionEntriesForDirectoryFragment(fragment, absolute, fileExtensions, /*includeExtensions*/ false, host, /*exclude*/ undefined, result);
if (paths) {
addCompletionEntriesFromPaths(result, fragment, absolute, fileExtensions, paths, host);
}
}
@ -329,7 +350,7 @@ namespace ts.Completions.PathCompletions {
const seen = createMap<true>();
if (options.types) {
for (const typesName of options.types) {
const moduleName = getUnmangledNameForScopedPackage(typesName);
const moduleName = unmangleScopedPackageName(typesName);
pushResult(moduleName);
}
}
@ -363,7 +384,7 @@ namespace ts.Completions.PathCompletions {
for (let typeDirectory of directories) {
typeDirectory = normalizePath(typeDirectory);
const directoryName = getBaseFileName(typeDirectory);
const moduleName = getUnmangledNameForScopedPackage(directoryName);
const moduleName = unmangleScopedPackageName(directoryName);
pushResult(moduleName);
}
}
@ -390,6 +411,18 @@ namespace ts.Completions.PathCompletions {
return paths;
}
function findPackageJson(directory: string, host: LanguageServiceHost): string | undefined {
let packageJson: string | undefined;
forEachAncestorDirectory(directory, ancestor => {
if (ancestor === "node_modules") return true;
packageJson = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json");
if (packageJson) {
return true; // break out
}
});
return packageJson;
}
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string): ReadonlyArray<string> {
if (!host.readFile || !host.fileExists) return emptyArray;

View file

@ -74,6 +74,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,228 @@
namespace ts {
import theory = utils.theory;
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);
});
it("increment", () => {
assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("major"), [2, 0, 0]);
assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("minor"), [1, 3, 0]);
assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("patch"), [1, 2, 4]);
});
});
describe("VersionRange", () => {
function assertRange(rangeText: string, versionText: string, inRange = true) {
const range = new VersionRange(rangeText);
const version = new Version(versionText);
assert.strictEqual(range.test(version), inRange, `Expected version '${version}' ${inRange ? `to be` : `to not be`} in range '${rangeText}' (${range})`);
}
theory("comparators", assertRange, [
["", "1.0.0"],
["*", "1.0.0"],
["1", "1.0.0"],
["1", "2.0.0", false],
["1.0", "1.0.0"],
["1.0", "1.1.0", false],
["1.0.0", "1.0.0"],
["1.0.0", "1.0.1", false],
["1.*", "1.0.0"],
["1.*", "2.0.0", false],
["1.x", "1.0.0"],
["1.x", "2.0.0", false],
["=1", "1.0.0"],
["=1", "1.1.0"],
["=1", "1.0.1"],
["=1.0", "1.0.0"],
["=1.0", "1.0.1"],
["=1.0.0", "1.0.0"],
["=*", "0.0.0"],
["=*", "1.0.0"],
[">1", "2"],
[">1.0", "1.1"],
[">1.0.0", "1.0.1"],
[">1.0.0", "1.0.1-pre"],
[">*", "0.0.0", false],
[">*", "1.0.0", false],
[">=1", "1.0.0"],
[">=1.0", "1.0.0"],
[">=1.0.0", "1.0.0"],
[">=1.0.0", "1.0.1-pre"],
[">=*", "0.0.0"],
[">=*", "1.0.0"],
["<2", "1.0.0"],
["<2.1", "2.0.0"],
["<2.0.1", "2.0.0"],
["<2.0.0", "2.0.0-pre"],
["<*", "0.0.0", false],
["<*", "1.0.0", false],
["<=2", "2.0.0"],
["<=2.1", "2.1.0"],
["<=2.0.1", "2.0.1"],
["<=*", "0.0.0"],
["<=*", "1.0.0"],
]);
theory("conjunctions", assertRange, [
[">1.0.0 <2.0.0", "1.0.1"],
[">1.0.0 <2.0.0", "2.0.0", false],
[">1.0.0 <2.0.0", "1.0.0", false],
[">1 >2", "3.0.0"],
]);
theory("disjunctions", assertRange, [
[">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "1.0.0"],
[">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "2.0.0", false],
[">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "3.0.0"],
]);
theory("hyphen", assertRange, [
["1.0.0 - 2.0.0", "1.0.0"],
["1.0.0 - 2.0.0", "2.0.0"],
["1.0.0 - 2.0.0", "3.0.0", false],
]);
theory("tilde", assertRange, [
["~0", "0.0.0"],
["~0", "0.1.0"],
["~0", "0.1.2"],
["~0", "0.1.9"],
["~0", "1.0.0", false],
["~0.1", "0.1.0"],
["~0.1", "0.1.2"],
["~0.1", "0.1.9"],
["~0.1", "0.2.0", false],
["~0.1.2", "0.1.2"],
["~0.1.2", "0.1.9"],
["~0.1.2", "0.2.0", false],
["~1", "1.0.0"],
["~1", "1.2.0"],
["~1", "1.2.3"],
["~1", "1.2.0"],
["~1", "1.2.3"],
["~1", "0.0.0", false],
["~1", "2.0.0", false],
["~1.2", "1.2.0"],
["~1.2", "1.2.3"],
["~1.2", "1.1.0", false],
["~1.2", "1.3.0", false],
["~1.2.3", "1.2.3"],
["~1.2.3", "1.2.9"],
["~1.2.3", "1.1.0", false],
["~1.2.3", "1.3.0", false],
]);
theory("caret", assertRange, [
["^0", "0.0.0"],
["^0", "0.1.0"],
["^0", "0.9.0"],
["^0", "0.1.2"],
["^0", "0.1.9"],
["^0", "1.0.0", false],
["^0.1", "0.1.0"],
["^0.1", "0.1.2"],
["^0.1", "0.1.9"],
["^0.1.2", "0.1.2"],
["^0.1.2", "0.1.9"],
["^0.1.2", "0.0.0", false],
["^0.1.2", "0.2.0", false],
["^0.1.2", "1.0.0", false],
["^1", "1.0.0"],
["^1", "1.2.0"],
["^1", "1.2.3"],
["^1", "1.9.0"],
["^1", "0.0.0", false],
["^1", "2.0.0", false],
["^1.2", "1.2.0"],
["^1.2", "1.2.3"],
["^1.2", "1.9.0"],
["^1.2", "1.1.0", false],
["^1.2", "2.0.0", false],
["^1.2.3", "1.2.3"],
["^1.2.3", "1.9.0"],
["^1.2.3", "1.2.2", false],
["^1.2.3", "2.0.0", false],
]);
});
});
}

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,6 +2,7 @@
"======== Resolving module 'foo/use' from '/index.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use/index.d.ts@1.2.3'.",
"File '/node_modules/foo/use.ts' does not exist.",
"File '/node_modules/foo/use.tsx' does not exist.",
@ -26,6 +27,7 @@
"File '/node_modules/foo/index.ts' does not exist.",
"File '/node_modules/foo/index.tsx' does not exist.",
"File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/index.d.ts@1.2.3'.",
"======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========",
"======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========",
@ -34,6 +36,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' does not have a 'main' field.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo/index.d.ts@1.2.3'.",
"File '/node_modules/a/node_modules/foo.ts' does not exist.",
"File '/node_modules/a/node_modules/foo.tsx' does not exist.",

View file

@ -2,6 +2,7 @@
"======== Resolving module '@foo/bar/use' from '/index.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use/index.d.ts@1.2.3'.",
"File '/node_modules/@foo/bar/use.ts' does not exist.",
"File '/node_modules/@foo/bar/use.tsx' does not exist.",
@ -26,6 +27,7 @@
"File '/node_modules/@foo/bar/index.ts' does not exist.",
"File '/node_modules/@foo/bar/index.tsx' does not exist.",
"File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/index.d.ts@1.2.3'.",
"======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========",
"======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========",
@ -34,6 +36,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' does not have a 'main' field.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/index.d.ts@1.2.3'.",
"File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.",
"File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.",

View file

@ -2,7 +2,9 @@
"======== Resolving type reference directive 'jquery', containing file '/foo/consumer.ts', root directory './types'. ========",
"Resolving with primary search path './types'.",
"'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at './types/jquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.",
"File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'types/jquery/jquery.d.ts', result '/foo/types/jquery/jquery.d.ts'.",
@ -10,7 +12,9 @@
"======== Resolving type reference directive 'jquery', containing file '/foo/__inferred type names__.ts', root directory './types'. ========",
"Resolving with primary search path './types'.",
"'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at './types/jquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.",
"File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'types/jquery/jquery.d.ts', result '/foo/types/jquery/jquery.d.ts'.",

View file

@ -4,6 +4,7 @@
"Looking up in 'node_modules' folder, initial location '/a/b'.",
"Directory '/a/b/node_modules' does not exist, skipping all lookups in it.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/a/node_modules/jquery/package.json'.",
"File '/a/node_modules/jquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.",

View file

@ -5,6 +5,7 @@
"Directory '/a/b/node_modules' does not exist, skipping all lookups in it.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/a/node_modules/jquery/package.json'.",
"File '/a/node_modules/jquery.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",

View file

@ -3,7 +3,9 @@
"Resolving with primary search path '/types'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/types/jquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.",
"File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.",
@ -13,7 +15,9 @@
"Resolving with primary search path '/types'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/types/jquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.",
"File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.",

View file

@ -5,6 +5,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
"File '/node_modules/normalize.css.ts' does not exist.",
"File '/node_modules/normalize.css.tsx' does not exist.",
@ -27,6 +28,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
"File '/node_modules/normalize.css.js' does not exist.",
"File '/node_modules/normalize.css.jsx' does not exist.",

View file

@ -4,6 +4,7 @@
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.ts' does not exist.",
"File '/node_modules/foo.tsx' does not exist.",
@ -28,6 +29,7 @@
"Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.js' does not exist.",
"File '/node_modules/foo.jsx' does not exist.",

View file

@ -4,6 +4,7 @@
"Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/bar/types.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/bar/package.json'.",
"File '/node_modules/foo/bar.ts' does not exist.",
"File '/node_modules/foo/bar.tsx' does not exist.",

View file

@ -4,6 +4,7 @@
"Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/@bar/types.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/@bar/package.json'.",
"File '/node_modules/foo/@bar.ts' does not exist.",
"File '/node_modules/foo/@bar.tsx' does not exist.",

View file

@ -4,6 +4,7 @@
"Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'types.d.ts' that references '/node_modules/@foo/bar/types.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@foo/bar/package.json'.",
"File '/node_modules/@foo/bar.ts' does not exist.",
"File '/node_modules/@foo/bar.tsx' does not exist.",

View file

@ -3,6 +3,7 @@
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/foo/bar/package.json' does not exist.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar/index.d.ts@1.2.3'.",
"File '/node_modules/foo/bar.ts' does not exist.",
"File '/node_modules/foo/bar.tsx' does not exist.",
@ -13,6 +14,7 @@
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.",
"Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.",
"File '/node_modules/foo/bar/package.json' does not exist.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar/index.d.ts@1.2.3'.",
"File '/node_modules/foo/bar.js' does not exist.",
"File '/node_modules/foo/bar.jsx' does not exist.",

View file

@ -3,6 +3,7 @@
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/foo/@bar/package.json' does not exist.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar/index.d.ts@1.2.3'.",
"File '/node_modules/foo/@bar.ts' does not exist.",
"File '/node_modules/foo/@bar.tsx' does not exist.",
@ -13,6 +14,7 @@
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.",
"Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.",
"File '/node_modules/foo/@bar/package.json' does not exist.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar/index.d.ts@1.2.3'.",
"File '/node_modules/foo/@bar.js' does not exist.",
"File '/node_modules/foo/@bar.jsx' does not exist.",

View file

@ -5,6 +5,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'src/index.js' that references '/node_modules/foo/src/index.js'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/src/index.d.ts@1.2.3'.",
"File '/node_modules/foo.ts' does not exist.",
"File '/node_modules/foo.tsx' does not exist.",

View file

@ -5,6 +5,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.ts' does not exist.",
"File '/node_modules/foo.tsx' does not exist.",
@ -26,6 +27,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.js' does not exist.",
"File '/node_modules/foo.jsx' does not exist.",
@ -41,6 +43,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'rab.js' that references '/node_modules/bar/rab.js'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/bar/package.json'.",
"File '/node_modules/bar.ts' does not exist.",
"File '/node_modules/bar.tsx' does not exist.",
@ -67,6 +70,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'rab.js' that references '/node_modules/bar/rab.js'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/bar/package.json'.",
"File '/node_modules/bar.js' does not exist.",
"File '/node_modules/bar.jsx' does not exist.",
@ -80,6 +84,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'zab' that references '/node_modules/baz/zab'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/baz/package.json'.",
"File '/node_modules/baz.ts' does not exist.",
"File '/node_modules/baz.tsx' does not exist.",
@ -103,6 +108,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'zab' that references '/node_modules/baz/zab'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/baz/package.json'.",
"File '/node_modules/baz.js' does not exist.",
"File '/node_modules/baz.jsx' does not exist.",

View file

@ -5,6 +5,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.ts' does not exist.",
"File '/node_modules/foo.tsx' does not exist.",
@ -28,6 +29,7 @@
"'package.json' does not have a 'typings' field.",
"'package.json' does not have a 'types' field.",
"'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/foo/package.json'.",
"File '/node_modules/foo.js' does not exist.",
"File '/node_modules/foo.jsx' does not exist.",

View file

@ -43,7 +43,6 @@ exports["default"] = Form;
//// [index.d.ts]
/// <reference path="node_modules/create-emotion-styled/types/react/index.d.ts" />
/// <reference types="react" />
declare const Form: import("create-emotion-styled/types/react").StyledOtherComponent<{}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>;
export default Form;

View file

@ -0,0 +1,43 @@
//// [tests/cases/conformance/moduleResolution/typesVersions.ambientModules.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
//// [index.d.ts]
declare module "ext" {
export const a = "default a";
}
declare module "ext/other" {
export const b = "default b";
}
//// [index.d.ts]
declare module "ext" {
export const a = "ts3.1 a";
}
declare module "ext/other" {
export const b = "ts3.1 b";
}
//// [main.ts]
import { a } from "ext";
import { b } from "ext/other";
const aa: "ts3.1 a" = a;
const bb: "ts3.1 b" = b;
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
const aa = ext_1.a;
const bb = other_1.b;

View file

@ -0,0 +1,29 @@
=== tests/cases/conformance/moduleResolution/main.ts ===
import { a } from "ext";
>a : Symbol(a, Decl(main.ts, 0, 8))
import { b } from "ext/other";
>b : Symbol(b, Decl(main.ts, 1, 8))
const aa: "ts3.1 a" = a;
>aa : Symbol(aa, Decl(main.ts, 3, 5))
>a : Symbol(a, Decl(main.ts, 0, 8))
const bb: "ts3.1 b" = b;
>bb : Symbol(bb, Decl(main.ts, 4, 5))
>b : Symbol(b, Decl(main.ts, 1, 8))
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts ===
declare module "ext" {
>"ext" : Symbol("ext", Decl(index.d.ts, 0, 0))
export const a = "ts3.1 a";
>a : Symbol(a, Decl(index.d.ts, 1, 16))
}
declare module "ext/other" {
>"ext/other" : Symbol("ext/other", Decl(index.d.ts, 2, 1))
export const b = "ts3.1 b";
>b : Symbol(b, Decl(index.d.ts, 4, 16))
}

View file

@ -0,0 +1,55 @@
[
"======== 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' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== 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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts' does not exist.",
"Directory 'tests/cases/conformance/moduleResolution/node_modules/@types' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.",
"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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.js' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.jsx' does not exist.",
"Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.",
"Directory 'node_modules' does not exist, skipping all lookups in it.",
"Directory '/node_modules' does not exist, skipping all lookups in it.",
"======== Module name 'ext/other' was not resolved. ========"
]

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/moduleResolution/main.ts ===
import { a } from "ext";
>a : "ts3.1 a"
import { b } from "ext/other";
>b : "ts3.1 b"
const aa: "ts3.1 a" = a;
>aa : "ts3.1 a"
>a : "ts3.1 a"
const bb: "ts3.1 b" = b;
>bb : "ts3.1 b"
>b : "ts3.1 b"
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts ===
declare module "ext" {
>"ext" : typeof import("ext")
export const a = "ts3.1 a";
>a : "ts3.1 a"
>"ts3.1 a" : "ts3.1 a"
}
declare module "ext/other" {
>"ext/other" : typeof import("ext/other")
export const b = "ts3.1 b";
>b : "ts3.1 b"
>"ts3.1 b" : "ts3.1 b"
}

View file

@ -0,0 +1,39 @@
//// [tests/cases/conformance/moduleResolution/typesVersions.multiFile.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
//// [index.d.ts]
export const a = "default a";
//// [other.d.ts]
export const b = "default b";
//// [index.d.ts]
export const a = "ts3.1 a";
//// [other.d.ts]
export const b = "ts3.1 b";
//// [main.ts]
import { a } from "ext";
import { b } from "ext/other";
const aa: "ts3.1 a" = a;
const bb: "ts3.1 b" = b;
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
const aa = ext_1.a;
const bb = other_1.b;

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/moduleResolution/node_modules/ext/index.d.ts ===
export const a = "default a";
>a : Symbol(a, Decl(index.d.ts, 0, 12))
=== tests/cases/conformance/moduleResolution/node_modules/ext/other.d.ts ===
export const b = "default b";
>b : Symbol(b, Decl(other.d.ts, 0, 12))
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts ===
export const a = "ts3.1 a";
>a : Symbol(a, Decl(index.d.ts, 0, 12))
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts ===
export const b = "ts3.1 b";
>b : Symbol(b, Decl(other.d.ts, 0, 12))
=== tests/cases/conformance/moduleResolution/main.ts ===
import { a } from "ext";
>a : Symbol(a, Decl(main.ts, 0, 8))
import { b } from "ext/other";
>b : Symbol(b, Decl(main.ts, 1, 8))
const aa: "ts3.1 a" = a;
>aa : Symbol(aa, Decl(main.ts, 3, 5))
>a : Symbol(a, Decl(main.ts, 0, 8))
const bb: "ts3.1 b" = b;
>bb : Symbol(bb, Decl(main.ts, 4, 5))
>b : Symbol(b, Decl(main.ts, 1, 8))

View file

@ -0,0 +1,37 @@
[
"======== 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' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== 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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.ts' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.tsx' does not exist.",
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts', result 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts'.",
"======== Module name 'ext/other' was successfully resolved to 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts'. ========"
]

View file

@ -0,0 +1,35 @@
=== tests/cases/conformance/moduleResolution/node_modules/ext/index.d.ts ===
export const a = "default a";
>a : "default a"
>"default a" : "default a"
=== tests/cases/conformance/moduleResolution/node_modules/ext/other.d.ts ===
export const b = "default b";
>b : "default b"
>"default b" : "default b"
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/index.d.ts ===
export const a = "ts3.1 a";
>a : "ts3.1 a"
>"ts3.1 a" : "ts3.1 a"
=== tests/cases/conformance/moduleResolution/node_modules/ext/ts3.1/other.d.ts ===
export const b = "ts3.1 b";
>b : "ts3.1 b"
>"ts3.1 b" : "ts3.1 b"
=== tests/cases/conformance/moduleResolution/main.ts ===
import { a } from "ext";
>a : "ts3.1 a"
import { b } from "ext/other";
>b : "ts3.1 b"
const aa: "ts3.1 a" = a;
>aa : "ts3.1 a"
>a : "ts3.1 a"
const bb: "ts3.1 b" = b;
>bb : "ts3.1 b"
>b : "ts3.1 b"

View file

@ -0,0 +1,51 @@
//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
//// [index.d.ts]
declare module "ext" {
export interface A {}
export function fa(): A;
}
declare module "ext/other" {
export interface B {}
export function fb(): B;
}
//// [index.d.ts]
declare module "ext" {
export interface A {}
export function fa(): A;
}
declare module "ext/other" {
export interface B {}
export function fb(): B;
}
//// [main.ts]
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
exports.va = ext_1.fa();
exports.vb = other_1.fb();
//// [main.d.ts]
export declare const va: import("ext").A;
export declare const vb: import("ext/other").B;

View file

@ -0,0 +1,37 @@
=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : Symbol(fa, Decl(main.ts, 0, 8))
import { fb } from "ext/other";
>fb : Symbol(fb, Decl(main.ts, 1, 8))
export const va = fa();
>va : Symbol(va, Decl(main.ts, 3, 12))
>fa : Symbol(fa, Decl(main.ts, 0, 8))
export const vb = fb();
>vb : Symbol(vb, Decl(main.ts, 4, 12))
>fb : Symbol(fb, Decl(main.ts, 1, 8))
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
declare module "ext" {
>"ext" : Symbol("ext", Decl(index.d.ts, 0, 0))
export interface A {}
>A : Symbol(A, Decl(index.d.ts, 0, 22))
export function fa(): A;
>fa : Symbol(fa, Decl(index.d.ts, 1, 25))
>A : Symbol(A, Decl(index.d.ts, 0, 22))
}
declare module "ext/other" {
>"ext/other" : Symbol("ext/other", Decl(index.d.ts, 3, 1))
export interface B {}
>B : Symbol(B, Decl(index.d.ts, 4, 28))
export function fb(): B;
>fb : Symbol(fb, Decl(index.d.ts, 5, 25))
>B : Symbol(B, Decl(index.d.ts, 4, 28))
}

View file

@ -0,0 +1,55 @@
[
"======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts' does not exist.",
"Directory 'tests/cases/conformance/declarationEmit/node_modules/@types' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.",
"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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.js' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.jsx' does not exist.",
"Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.",
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.",
"Directory 'node_modules' does not exist, skipping all lookups in it.",
"Directory '/node_modules' does not exist, skipping all lookups in it.",
"======== Module name 'ext/other' was not resolved. ========"
]

View file

@ -0,0 +1,33 @@
=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : () => import("ext").A
import { fb } from "ext/other";
>fb : () => import("ext/other").B
export const va = fa();
>va : import("ext").A
>fa() : import("ext").A
>fa : () => import("ext").A
export const vb = fb();
>vb : import("ext/other").B
>fb() : import("ext/other").B
>fb : () => import("ext/other").B
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
declare module "ext" {
>"ext" : typeof import("ext")
export interface A {}
export function fa(): A;
>fa : () => A
}
declare module "ext/other" {
>"ext/other" : typeof import("ext/other")
export interface B {}
export function fb(): B;
>fb : () => B
}

View file

@ -0,0 +1,48 @@
//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
//// [index.d.ts]
export interface A {}
export function fa(): A;
//// [other.d.ts]
export interface B {}
export function fb(): B;
//// [index.d.ts]
export interface A {}
export function fa(): A;
//// [other.d.ts]
export interface B {}
export function fb(): B;
//// [main.ts]
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
exports.va = ext_1.fa();
exports.vb = other_1.fb();
//// [main.d.ts]
export declare const va: import("ext").A;
export declare const vb: import("ext/other").B;

View file

@ -0,0 +1,47 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
>A : Symbol(A, Decl(index.d.ts, 0, 0))
export function fa(): A;
>fa : Symbol(fa, Decl(index.d.ts, 0, 21))
>A : Symbol(A, Decl(index.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface B {}
>B : Symbol(B, Decl(other.d.ts, 0, 0))
export function fb(): B;
>fb : Symbol(fb, Decl(other.d.ts, 0, 21))
>B : Symbol(B, Decl(other.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export interface A {}
>A : Symbol(A, Decl(index.d.ts, 0, 0))
export function fa(): A;
>fa : Symbol(fa, Decl(index.d.ts, 0, 21))
>A : Symbol(A, Decl(index.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts ===
export interface B {}
>B : Symbol(B, Decl(other.d.ts, 0, 0))
export function fb(): B;
>fb : Symbol(fb, Decl(other.d.ts, 0, 21))
>B : Symbol(B, Decl(other.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : Symbol(fa, Decl(main.ts, 0, 8))
import { fb } from "ext/other";
>fb : Symbol(fb, Decl(main.ts, 1, 8))
export const va = fa();
>va : Symbol(va, Decl(main.ts, 3, 12))
>fa : Symbol(fa, Decl(main.ts, 0, 8))
export const vb = fb();
>vb : Symbol(vb, Decl(main.ts, 4, 12))
>fb : Symbol(fb, Decl(main.ts, 1, 8))

View file

@ -0,0 +1,37 @@
[
"======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts'.",
"======== Module name 'ext/other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts'. ========"
]

View file

@ -0,0 +1,37 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
export function fa(): A;
>fa : () => A
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface B {}
export function fb(): B;
>fb : () => B
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export interface A {}
export function fa(): A;
>fa : () => A
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts ===
export interface B {}
export function fb(): B;
>fb : () => B
=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index").A
import { fb } from "ext/other";
>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other").B
export const va = fa();
>va : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index").A
>fa() : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index").A
>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index").A
export const vb = fb();
>vb : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other").B
>fb() : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other").B
>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other").B

View file

@ -0,0 +1,38 @@
tests/cases/conformance/declarationEmit/main.ts(1,10): error TS2305: Module '"tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index"' has no exported member 'fa'.
==== tests/cases/conformance/declarationEmit/tsconfig.json (0 errors) ====
{}
==== tests/cases/conformance/declarationEmit/node_modules/ext/package.json (0 errors) ====
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
==== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts (0 errors) ====
export interface A {}
export function fa(): A;
==== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts (0 errors) ====
export interface B {}
export function fb(): B;
==== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts (0 errors) ====
export * from "../";
==== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts (0 errors) ====
export * from "../other";
==== tests/cases/conformance/declarationEmit/main.ts (1 errors) ====
import { fa } from "ext";
~~
!!! error TS2305: Module '"tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index"' has no exported member 'fa'.
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();

View file

@ -0,0 +1,46 @@
//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
//// [index.d.ts]
export interface A {}
export function fa(): A;
//// [other.d.ts]
export interface B {}
export function fb(): B;
//// [index.d.ts]
export * from "../";
//// [other.d.ts]
export * from "../other";
//// [main.ts]
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
exports.va = ext_1.fa();
exports.vb = other_1.fb();
//// [main.d.ts]
export declare const va: any;
export declare const vb: import("ext/other").B;

View file

@ -0,0 +1,37 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
>A : Symbol(A, Decl(index.d.ts, 0, 0))
export function fa(): A;
>fa : Symbol(fa, Decl(index.d.ts, 0, 21))
>A : Symbol(A, Decl(index.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface B {}
>B : Symbol(B, Decl(other.d.ts, 0, 0))
export function fb(): B;
>fb : Symbol(fb, Decl(other.d.ts, 0, 21))
>B : Symbol(B, Decl(other.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export * from "../";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts ===
export * from "../other";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : Symbol(fa, Decl(main.ts, 0, 8))
import { fb } from "ext/other";
>fb : Symbol(fb, Decl(main.ts, 1, 8))
export const va = fa();
>va : Symbol(va, Decl(main.ts, 3, 12))
>fa : Symbol(fa, Decl(main.ts, 0, 8))
export const vb = fb();
>vb : Symbol(vb, Decl(main.ts, 4, 12))
>fb : Symbol(fb, Decl(main.ts, 1, 8))

View file

@ -0,0 +1,65 @@
[
"======== Resolving module '../' from 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/', target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/ndex/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"======== Module name '../' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== Resolving module '../other' from 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/other', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts' exist - use it as a name resolution result.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other.d.ts@1.0.0'.",
"======== Module name '../other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts'. ========",
"======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"Module name 'other', matched pattern '*'.",
"Trying substitution 'ts3.1/*', candidate module location: 'ts3.1/other'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts'.",
"======== Module name 'ext/other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts'. ========"
]

View file

@ -0,0 +1,33 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
export function fa(): A;
>fa : () => A
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface B {}
export function fb(): B;
>fb : () => B
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export * from "../";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/other.d.ts ===
export * from "../other";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : any
import { fb } from "ext/other";
>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").B
export const va = fa();
>va : any
>fa() : any
>fa : any
export const vb = fb();
>vb : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").B
>fb() : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").B
>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").B

View file

@ -0,0 +1,45 @@
//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFileBackReferenceToUnmapped.ts] ////
//// [package.json]
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": {
"index" : ["ts3.1/index"]
}
}
}
//// [index.d.ts]
export interface A {}
export function fa(): A;
//// [other.d.ts]
export interface A2 {}
export function fa(): A2;
//// [index.d.ts]
export * from "../other";
//// [main.ts]
import { fa } from "ext";
import { fa as fa2 } from "ext/other";
export const va = fa();
export const va2 = fa2();
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ext_1 = require("ext");
const other_1 = require("ext/other");
exports.va = ext_1.fa();
exports.va2 = other_1.fa();
//// [main.d.ts]
export declare const va: import("ext/other").A2;
export declare const va2: import("ext/other").A2;

View file

@ -0,0 +1,35 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
>A : Symbol(A, Decl(index.d.ts, 0, 0))
export function fa(): A;
>fa : Symbol(fa, Decl(index.d.ts, 0, 21))
>A : Symbol(A, Decl(index.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface A2 {}
>A2 : Symbol(A2, Decl(other.d.ts, 0, 0))
export function fa(): A2;
>fa : Symbol(fa, Decl(other.d.ts, 0, 22))
>A2 : Symbol(A2, Decl(other.d.ts, 0, 0))
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export * from "../other";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : Symbol(fa, Decl(main.ts, 0, 8))
import { fa as fa2 } from "ext/other";
>fa : Symbol(fa2, Decl(main.ts, 1, 8))
>fa2 : Symbol(fa2, Decl(main.ts, 1, 8))
export const va = fa();
>va : Symbol(va, Decl(main.ts, 3, 12))
>fa : Symbol(fa, Decl(main.ts, 0, 8))
export const va2 = fa2();
>va2 : Symbol(va2, Decl(main.ts, 4, 12))
>fa2 : Symbol(fa2, Decl(main.ts, 1, 8))

View file

@ -0,0 +1,44 @@
[
"======== Resolving module '../other' from 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/other', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts' exist - use it as a name resolution result.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other.d.ts@1.0.0'.",
"======== Module name '../other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts'. ========",
"======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'index'.",
"Module name 'index', matched pattern 'index'.",
"Trying substitution 'ts3.1/index', candidate module location: 'ts3.1/index'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index' does not exist.",
"Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index', target file type 'TypeScript'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'.",
"======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts'. ========",
"======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/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 a 'typesVersions' field with version-specific path mappings.",
"Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.",
"'package.json' has a 'typesVersions' entry '>=3.1.0-0' that matches compiler version '3.1.0-dev', looking for a pattern to match module name 'other'.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.ts' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.tsx' does not exist.",
"File 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts' exist - use it as a name resolution result.",
"Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts'.",
"======== Module name 'ext/other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts'. ========"
]

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts ===
export interface A {}
export function fa(): A;
>fa : () => A
=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts ===
export interface A2 {}
export function fa(): A2;
>fa : () => A2
=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.1/index.d.ts ===
export * from "../other";
No type information for this code.
No type information for this code.=== tests/cases/conformance/declarationEmit/main.ts ===
import { fa } from "ext";
>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
import { fa as fa2 } from "ext/other";
>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
>fa2 : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
export const va = fa();
>va : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
>fa() : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
export const va2 = fa2();
>va2 : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
>fa2() : import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2
>fa2 : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/other").A2

View file

@ -6,6 +6,7 @@
"File '/node_modules/jquery.tsx' does not exist.",
"File '/node_modules/jquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/jquery/package.json'.",
"File '/node_modules/@types/jquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.",
@ -19,6 +20,7 @@
"File '/node_modules/kquery.tsx' does not exist.",
"File '/node_modules/kquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/kquery/package.json'.",
"File '/node_modules/@types/kquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.",
@ -36,6 +38,7 @@
"File '/node_modules/lquery.tsx' does not exist.",
"File '/node_modules/lquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/lquery/package.json'.",
"File '/node_modules/@types/lquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.",
@ -51,6 +54,7 @@
"File '/node_modules/mquery.tsx' does not exist.",
"File '/node_modules/mquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/mquery/package.json'.",
"File '/node_modules/@types/mquery.d.ts' does not exist.",
"'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.",
@ -66,7 +70,9 @@
"======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
"Resolving with primary search path '/node_modules/@types'.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/jquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.",
"File '/node_modules/@types/jquery/jquery.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@types/jquery/jquery.d.ts', result '/node_modules/@types/jquery/jquery.d.ts'.",
@ -74,7 +80,9 @@
"======== Resolving type reference directive 'kquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
"Resolving with primary search path '/node_modules/@types'.",
"'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/kquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.",
"File '/node_modules/@types/kquery/kquery' does not exist.",
"Loading module as file / folder, candidate module location '/node_modules/@types/kquery/kquery', target file type 'TypeScript'.",
@ -86,7 +94,9 @@
"======== Resolving type reference directive 'lquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
"Resolving with primary search path '/node_modules/@types'.",
"'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/lquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.",
"File '/node_modules/@types/lquery/lquery' does not exist.",
"Loading module as file / folder, candidate module location '/node_modules/@types/lquery/lquery', target file type 'TypeScript'.",
@ -96,7 +106,9 @@
"======== Resolving type reference directive 'mquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
"Resolving with primary search path '/node_modules/@types'.",
"'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.",
"'package.json' does not have a 'typesVersions' field.",
"Found 'package.json' at '/node_modules/@types/mquery/package.json'.",
"'package.json' does not have a 'typesVersions' field.",
"'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.",
"File '/node_modules/@types/mquery/mquery' does not exist.",
"Loading module as file / folder, candidate module location '/node_modules/@types/mquery/mquery', target file type 'TypeScript'.",

View file

@ -0,0 +1,43 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @declaration: true
// @noImplicitReferences: true
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
// @filename: node_modules/ext/index.d.ts
declare module "ext" {
export interface A {}
export function fa(): A;
}
declare module "ext/other" {
export interface B {}
export function fb(): B;
}
// @filename: node_modules/ext/ts3.1/index.d.ts
declare module "ext" {
export interface A {}
export function fa(): A;
}
declare module "ext/other" {
export interface B {}
export function fb(): B;
}
// @filename: main.ts
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,39 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @declaration: true
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
// @filename: node_modules/ext/index.d.ts
export interface A {}
export function fa(): A;
// @filename: node_modules/ext/other.d.ts
export interface B {}
export function fb(): B;
// @filename: node_modules/ext/ts3.1/index.d.ts
export interface A {}
export function fa(): A;
// @filename: node_modules/ext/ts3.1/other.d.ts
export interface B {}
export function fb(): B;
// @filename: main.ts
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,37 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @declaration: true
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
// @filename: node_modules/ext/index.d.ts
export interface A {}
export function fa(): A;
// @filename: node_modules/ext/other.d.ts
export interface B {}
export function fb(): B;
// @filename: node_modules/ext/ts3.1/index.d.ts
export * from "../";
// @filename: node_modules/ext/ts3.1/other.d.ts
export * from "../other";
// @filename: main.ts
import { fa } from "ext";
import { fb } from "ext/other";
export const va = fa();
export const vb = fb();
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,36 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @declaration: true
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": {
"index" : ["ts3.1/index"]
}
}
}
// @filename: node_modules/ext/index.d.ts
export interface A {}
export function fa(): A;
// @filename: node_modules/ext/other.d.ts
export interface A2 {}
export function fa(): A2;
// @filename: node_modules/ext/ts3.1/index.d.ts
export * from "../other";
// @filename: main.ts
import { fa } from "ext";
import { fa as fa2 } from "ext/other";
export const va = fa();
export const va2 = fa2();
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,39 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @noImplicitReferences: true
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
// @filename: node_modules/ext/index.d.ts
declare module "ext" {
export const a = "default a";
}
declare module "ext/other" {
export const b = "default b";
}
// @filename: node_modules/ext/ts3.1/index.d.ts
declare module "ext" {
export const a = "ts3.1 a";
}
declare module "ext/other" {
export const b = "ts3.1 b";
}
// @filename: main.ts
import { a } from "ext";
import { b } from "ext/other";
const aa: "ts3.1 a" = a;
const bb: "ts3.1 b" = b;
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,34 @@
// @traceResolution: true
// @target: esnext
// @module: commonjs
// @filename: node_modules/ext/package.json
{
"name": "ext",
"version": "1.0.0",
"types": "index",
"typesVersions": {
">=3.1.0-0": { "*" : ["ts3.1/*"] }
}
}
// @filename: node_modules/ext/index.d.ts
export const a = "default a";
// @filename: node_modules/ext/other.d.ts
export const b = "default b";
// @filename: node_modules/ext/ts3.1/index.d.ts
export const a = "ts3.1 a";
// @filename: node_modules/ext/ts3.1/other.d.ts
export const b = "ts3.1 b";
// @filename: main.ts
import { a } from "ext";
import { b } from "ext/other";
const aa: "ts3.1 a" = a;
const bb: "ts3.1 b" = b;
// @filename: tsconfig.json
{}

View file

@ -0,0 +1,36 @@
/// <reference path='fourslash.ts' />
// Should give completions based on typesVersions
// @Filename: node_modules/ext/package.json
//// {
//// "name": "ext",
//// "version": "1.0.0",
//// "types": "index",
//// "typesVersions": {
//// "3.0": { "*" : ["ts3.0/*"] }
//// }
//// }
// @Filename: node_modules/ext/index.d.ts
//// export {};
// @Filename: node_modules/ext/aaa.d.ts
//// export {};
// @Filename: node_modules/ext/ts3.0/index.d.ts
//// export {};
// @Filename: node_modules/ext/ts3.0/zzz.d.ts
//// export {};
// @Filename: main.ts
//// import * as ext1 from "ext//*import_as0*/
//// import ext2 = require("ext//*import_equals0*/
//// var ext2 = require("ext//*require0*/
verify.completions({
marker: test.markerNames(),
exact: ["aaa", "index", "ts3.0", "zzz"],
isNewIdentifierLocation: true,
});