diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ceb99b65eefab..3d4f288f1293b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -50764,7 +50764,7 @@ export function signatureHasLiteralTypes(s: Signature) { return !!(s.flags & SignatureFlags.HasLiteralTypes); } -function createBasicNodeBuilderModuleSpecifierResolutionHost(host: TypeCheckerHost): ModuleSpecifierResolutionHost & { getCommonSourceDirectory(): string; } { +function createBasicNodeBuilderModuleSpecifierResolutionHost(host: TypeCheckerHost): ModuleSpecifierResolutionHost { return { getCommonSourceDirectory: !!(host as Program).getCommonSourceDirectory ? () => (host as Program).getCommonSourceDirectory() : () => "", getCurrentDirectory: () => host.getCurrentDirectory(), diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 21eae040ba922..9738920df7527 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2400,9 +2400,13 @@ function levenshteinWithMax(s1: string, s2: string, max: number): number | undef } /** @internal */ -export function endsWith(str: string, suffix: string): boolean { +export function endsWith(str: string, suffix: string, ignoreCase?: boolean): boolean { const expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; + return expectedPos >= 0 && ( + ignoreCase + ? equateStringsCaseInsensitive(str.slice(expectedPos), suffix) + : str.indexOf(suffix, expectedPos) === expectedPos + ); } /** @internal */ @@ -2579,8 +2583,10 @@ export function findBestPatternMatch(values: readonly T[], getPattern: (value } /** @internal */ -export function startsWith(str: string, prefix: string): boolean { - return str.lastIndexOf(prefix, 0) === 0; +export function startsWith(str: string, prefix: string, ignoreCase?: boolean): boolean { + return ignoreCase + ? equateStringsCaseInsensitive(str.slice(0, prefix.length), prefix) + : str.lastIndexOf(prefix, 0) === 0; } /** @internal */ diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9e8f97a248c7e..3f17986359c37 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -583,35 +583,50 @@ export function getOutputExtension(fileName: string, options: CompilerOptions): Extension.Js; } -function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined, getCommonSourceDirectory?: () => string) { +function getOutputPathWithoutChangingExt( + inputFileName: string, + ignoreCase: boolean, + outputDir: string | undefined, + getCommonSourceDirectory: () => string, +): string { return outputDir ? resolvePath( outputDir, - getRelativePathFromDirectory(getCommonSourceDirectory ? getCommonSourceDirectory() : getCommonSourceDirectoryOfConfig(configFile, ignoreCase), inputFileName, ignoreCase), + getRelativePathFromDirectory(getCommonSourceDirectory(), inputFileName, ignoreCase), ) : inputFileName; } /** @internal */ -export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { +export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) { + return getOutputDeclarationFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory); +} + +/** @internal */ +export function getOutputDeclarationFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string) { return changeExtension( - getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir, getCommonSourceDirectory), + getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.declarationDir || options.outDir, getCommonSourceDirectory), getDeclarationEmitExtensionForPath(inputFileName), ); } -function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { +function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) { if (configFile.options.emitDeclarationOnly) return undefined; const isJsonFile = fileExtensionIs(inputFileName, Extension.Json); - const outputFileName = changeExtension( - getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir, getCommonSourceDirectory), - getOutputExtension(inputFileName, configFile.options), - ); + const outputFileName = getOutputJSFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory); return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== Comparison.EqualTo ? outputFileName : undefined; } +/** @internal */ +export function getOutputJSFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string): string { + return changeExtension( + getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.outDir, getCommonSourceDirectory), + getOutputExtension(inputFileName, options), + ); +} + function createAddOutput() { let outputs: string[] | undefined; return { addOutput, getOutputs }; diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 67f821b09213b..4f128f1e6aa11 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -915,6 +915,11 @@ export function isPackageJsonInfo(entry: PackageJsonInfoCacheEntry | undefined): return !!(entry as PackageJsonInfo | undefined)?.contents; } +/** @internal */ +export function isMissingPackageJsonInfo(entry: PackageJsonInfoCacheEntry | undefined): entry is MissingPackageJsonInfo { + return !!entry && !(entry as PackageJsonInfo).contents; +} + export interface PackageJsonInfoCache { /** @internal */ getPackageJsonInfo(packageJsonPath: string): PackageJsonInfoCacheEntry | undefined; /** @internal */ setPackageJsonInfo(packageJsonPath: string, info: PackageJsonInfoCacheEntry): void; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 2dddc47d30c69..1da0c9e834be3 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -42,6 +42,8 @@ import { getModuleSpecifierEndingPreference, getNodeModulePathParts, getNormalizedAbsolutePath, + getOutputDeclarationFileNameWorker, + getOutputJSFileNameWorker, getOwnKeys, getPackageJsonTypesVersionsPaths, getPackageNameFromTypesPackageName, @@ -49,18 +51,21 @@ import { getRelativePathFromDirectory, getRelativePathToDirectoryOrUrl, getResolvePackageJsonExports, + getResolvePackageJsonImports, getSourceFileOfModule, getSupportedExtensions, getTextOfIdentifierOrLiteral, hasJSFileExtension, hasTSFileExtension, hostGetCanonicalFileName, + hostUsesCaseSensitiveFileNames, Identifier, isAmbientModule, isApplicableVersionedTypesKey, isDeclarationFileName, isExternalModuleAugmentation, isExternalModuleNameRelative, + isMissingPackageJsonInfo, isModuleBlock, isModuleDeclaration, isNonGlobalAmbientModule, @@ -107,6 +112,7 @@ import { SymbolFlags, toPath, tryGetExtensionFromPath, + tryParseJson, tryParsePatterns, TypeChecker, UserPreferences, @@ -485,7 +491,7 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt const allowedEndings = getAllowedEndingsInPrefererredOrder(importMode); const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, allowedEndings, compilerOptions) || processEnding(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), allowedEndings, compilerOptions); - if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) { + if (!baseUrl && !paths && !getResolvePackageJsonImports(compilerOptions) || relativePreference === RelativePreference.Relative) { return pathsOnly ? undefined : relativePath; } @@ -495,12 +501,14 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt return pathsOnly ? undefined : relativePath; } - const fromPaths = paths && tryGetModuleNameFromPaths(relativeToBaseUrl, paths, allowedEndings, host, compilerOptions); + const fromPackageJsonImports = pathsOnly ? undefined : tryGetModuleNameFromPackageJsonImports(moduleFileName, sourceDirectory, compilerOptions, host, importMode); + + const fromPaths = pathsOnly || fromPackageJsonImports === undefined ? paths && tryGetModuleNameFromPaths(relativeToBaseUrl, paths, allowedEndings, host, compilerOptions) : undefined; if (pathsOnly) { return fromPaths; } - const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? processEnding(relativeToBaseUrl, allowedEndings, compilerOptions) : fromPaths; + const maybeNonRelative = fromPackageJsonImports ?? (fromPaths === undefined && baseUrl !== undefined ? processEnding(relativeToBaseUrl, allowedEndings, compilerOptions) : fromPaths); if (!maybeNonRelative) { return relativePath; } @@ -567,8 +575,8 @@ function getNearestAncestorDirectoryWithPackageJson(host: ModuleSpecifierResolut if (host.getNearestAncestorDirectoryWithPackageJson) { return host.getNearestAncestorDirectoryWithPackageJson(fileName); } - return !!forEachAncestorDirectory(fileName, directory => { - return host.fileExists(combinePaths(directory, "package.json")) ? true : undefined; + return forEachAncestorDirectory(fileName, directory => { + return host.fileExists(combinePaths(directory, "package.json")) ? directory : undefined; }); } @@ -843,64 +851,79 @@ const enum MatchingMode { Pattern, } -function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode = MatchingMode.Exact): { moduleFileToTry: string; } | undefined { +function tryGetModuleNameFromExportsOrImports(options: CompilerOptions, host: ModuleSpecifierResolutionHost, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode: MatchingMode, isImports: boolean): { moduleFileToTry: string; } | undefined { if (typeof exports === "string") { + const ignoreCase = !hostUsesCaseSensitiveFileNames(host); + const getCommonSourceDirectory = () => host.getCommonSourceDirectory(); + const outputFile = isImports && getOutputJSFileNameWorker(targetFilePath, options, ignoreCase, getCommonSourceDirectory); + const declarationFile = isImports && getOutputDeclarationFileNameWorker(targetFilePath, options, ignoreCase, getCommonSourceDirectory); + const pathOrPattern = getNormalizedAbsolutePath(combinePaths(packageDirectory, exports), /*currentDirectory*/ undefined); const extensionSwappedTarget = hasTSFileExtension(targetFilePath) ? removeFileExtension(targetFilePath) + tryGetJSExtensionForFile(targetFilePath, options) : undefined; + switch (mode) { case MatchingMode.Exact: - if (comparePaths(targetFilePath, pathOrPattern) === Comparison.EqualTo || (extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern) === Comparison.EqualTo)) { + if ( + extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern, ignoreCase) === Comparison.EqualTo || + comparePaths(targetFilePath, pathOrPattern, ignoreCase) === Comparison.EqualTo || + outputFile && comparePaths(outputFile, pathOrPattern, ignoreCase) === Comparison.EqualTo || + declarationFile && comparePaths(declarationFile, pathOrPattern, ignoreCase) === Comparison.EqualTo + ) { return { moduleFileToTry: packageName }; } break; case MatchingMode.Directory: - if (containsPath(pathOrPattern, targetFilePath)) { + if (extensionSwappedTarget && containsPath(pathOrPattern, extensionSwappedTarget, ignoreCase)) { + const fragment = getRelativePathFromDirectory(pathOrPattern, extensionSwappedTarget, /*ignoreCase*/ false); + return { moduleFileToTry: getNormalizedAbsolutePath(combinePaths(combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) }; + } + if (containsPath(pathOrPattern, targetFilePath, ignoreCase)) { const fragment = getRelativePathFromDirectory(pathOrPattern, targetFilePath, /*ignoreCase*/ false); return { moduleFileToTry: getNormalizedAbsolutePath(combinePaths(combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) }; } + if (outputFile && containsPath(pathOrPattern, outputFile, ignoreCase)) { + const fragment = getRelativePathFromDirectory(pathOrPattern, outputFile, /*ignoreCase*/ false); + return { moduleFileToTry: combinePaths(packageName, fragment) }; + } + if (declarationFile && containsPath(pathOrPattern, declarationFile, ignoreCase)) { + const fragment = getRelativePathFromDirectory(pathOrPattern, declarationFile, /*ignoreCase*/ false); + return { moduleFileToTry: combinePaths(packageName, fragment) }; + } break; case MatchingMode.Pattern: const starPos = pathOrPattern.indexOf("*"); const leadingSlice = pathOrPattern.slice(0, starPos); const trailingSlice = pathOrPattern.slice(starPos + 1); - if (startsWith(targetFilePath, leadingSlice) && endsWith(targetFilePath, trailingSlice)) { + if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice, ignoreCase) && endsWith(extensionSwappedTarget, trailingSlice, ignoreCase)) { + const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length); + return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) }; + } + if (startsWith(targetFilePath, leadingSlice, ignoreCase) && endsWith(targetFilePath, trailingSlice, ignoreCase)) { const starReplacement = targetFilePath.slice(leadingSlice.length, targetFilePath.length - trailingSlice.length); return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) }; } - if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice) && endsWith(extensionSwappedTarget, trailingSlice)) { - const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length); + if (outputFile && startsWith(outputFile, leadingSlice, ignoreCase) && endsWith(outputFile, trailingSlice, ignoreCase)) { + const starReplacement = outputFile.slice(leadingSlice.length, outputFile.length - trailingSlice.length); + return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) }; + } + if (declarationFile && startsWith(declarationFile, leadingSlice, ignoreCase) && endsWith(declarationFile, trailingSlice, ignoreCase)) { + const starReplacement = declarationFile.slice(leadingSlice.length, declarationFile.length - trailingSlice.length); return { moduleFileToTry: replaceFirstStar(packageName, starReplacement) }; } break; } } else if (Array.isArray(exports)) { - return forEach(exports, e => tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, e, conditions)); + return forEach(exports, e => tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, e, conditions, mode, isImports)); } else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null - if (allKeysStartWithDot(exports as MapLike)) { - // sub-mappings - // 3 cases: - // * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode)) - // * pattern mappings (contains a *) - // * exact mappings (no *, does not end with /) - return forEach(getOwnKeys(exports as MapLike), k => { - const subPackageName = getNormalizedAbsolutePath(combinePaths(packageName, k), /*currentDirectory*/ undefined); - const mode = endsWith(k, "/") ? MatchingMode.Directory - : k.includes("*") ? MatchingMode.Pattern - : MatchingMode.Exact; - return tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, subPackageName, (exports as MapLike)[k], conditions, mode); - }); - } - else { - // conditional mapping - for (const key of getOwnKeys(exports as MapLike)) { - if (key === "default" || conditions.includes(key) || isApplicableVersionedTypesKey(conditions, key)) { - const subTarget = (exports as MapLike)[key]; - const result = tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, subTarget, conditions, mode); - if (result) { - return result; - } + // conditional mapping + for (const key of getOwnKeys(exports as MapLike)) { + if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) { + const subTarget = (exports as MapLike)[key]; + const result = tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, subTarget, conditions, mode, isImports); + if (result) { + return result; } } } @@ -908,6 +931,53 @@ function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: s return undefined; } +function tryGetModuleNameFromExports(options: CompilerOptions, host: ModuleSpecifierResolutionHost, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[]): { moduleFileToTry: string; } | undefined { + if (typeof exports === "object" && exports !== null && !Array.isArray(exports) && allKeysStartWithDot(exports as MapLike)) { // eslint-disable-line no-null/no-null + // sub-mappings + // 3 cases: + // * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode)) + // * pattern mappings (contains a *) + // * exact mappings (no *, does not end with /) + return forEach(getOwnKeys(exports as MapLike), k => { + const subPackageName = getNormalizedAbsolutePath(combinePaths(packageName, k), /*currentDirectory*/ undefined); + const mode = endsWith(k, "/") ? MatchingMode.Directory + : k.includes("*") ? MatchingMode.Pattern + : MatchingMode.Exact; + return tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, subPackageName, (exports as MapLike)[k], conditions, mode, /*isImports*/ false); + }); + } + return tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, exports, conditions, MatchingMode.Exact, /*isImports*/ false); +} + +function tryGetModuleNameFromPackageJsonImports(moduleFileName: string, sourceDirectory: string, options: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode) { + if (!host.readFile || !getResolvePackageJsonImports(options)) { + return undefined; + } + + const ancestorDirectoryWithPackageJson = getNearestAncestorDirectoryWithPackageJson(host, sourceDirectory); + if (!ancestorDirectoryWithPackageJson) { + return undefined; + } + const packageJsonPath = combinePaths(ancestorDirectoryWithPackageJson, "package.json"); + const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath); + if (isMissingPackageJsonInfo(cachedPackageJson) || !host.fileExists(packageJsonPath)) { + return undefined; + } + const packageJsonContent = cachedPackageJson?.contents.packageJsonContent || tryParseJson(host.readFile(packageJsonPath)!); + const imports = packageJsonContent?.imports; + if (!imports) { + return undefined; + } + const conditions = getConditions(options, importMode); + return forEach(getOwnKeys(imports as MapLike), k => { + if (!startsWith(k, "#") || k === "#" || startsWith(k, "#/")) return undefined; + const mode = endsWith(k, "/") ? MatchingMode.Directory + : k.includes("*") ? MatchingMode.Pattern + : MatchingMode.Exact; + return tryGetModuleNameFromExportsOrImports(options, host, moduleFileName, ancestorDirectoryWithPackageJson, k, (imports as MapLike)[k], conditions, mode, /*isImports*/ true); + })?.moduleFileToTry; +} + function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, allowedEndings: readonly ModuleSpecifierEnding[], compilerOptions: CompilerOptions): string | undefined { const normalizedTargetPaths = getPathsRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPaths === undefined) { @@ -995,7 +1065,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan let maybeBlockedByTypesVersions = false; const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath); if (isPackageJsonInfo(cachedPackageJson) || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) { - const packageJsonContent = cachedPackageJson?.contents.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!); + const packageJsonContent: Record | undefined = cachedPackageJson?.contents.packageJsonContent || tryParseJson(host.readFile!(packageJsonPath)!); const importMode = overrideMode || importingSourceFile.impliedNodeFormat; if (getResolvePackageJsonExports(options)) { // The package name that we found in node_modules could be different from the package @@ -1004,20 +1074,17 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan const nodeModulesDirectoryName = packageRootPath.substring(parts.topLevelPackageNameIndex + 1); const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName); const conditions = getConditions(options, importMode); - const fromExports = packageJsonContent.exports - ? tryGetModuleNameFromExports(options, path, packageRootPath, packageName, packageJsonContent.exports, conditions) + const fromExports = packageJsonContent?.exports + ? tryGetModuleNameFromExports(options, host, path, packageRootPath, packageName, packageJsonContent.exports, conditions) : undefined; if (fromExports) { - const withJsExtension = !hasTSFileExtension(fromExports.moduleFileToTry) - ? fromExports - : { moduleFileToTry: removeFileExtension(fromExports.moduleFileToTry) + tryGetJSExtensionForFile(fromExports.moduleFileToTry, options) }; - return { ...withJsExtension, verbatimFromExports: true }; + return { ...fromExports, verbatimFromExports: true }; } - if (packageJsonContent.exports) { + if (packageJsonContent?.exports) { return { moduleFileToTry: path, blockedByExports: true }; } } - const versionPaths = packageJsonContent.typesVersions + const versionPaths = packageJsonContent?.typesVersions ? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions) : undefined; if (versionPaths) { @@ -1037,7 +1104,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan } } // If the file is the main module, it can be imported by the package name - const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main || "index.js"; + const mainFileRelative = packageJsonContent?.typings || packageJsonContent?.types || packageJsonContent?.main || "index.js"; if (isString(mainFileRelative) && !(maybeBlockedByTypesVersions && matchPatternOrExact(tryParsePatterns(versionPaths!.paths), mainFileRelative))) { // The 'main' file is also subject to mapping through typesVersions, and we couldn't come up with a path // explicitly through typesVersions, so if it matches a key in typesVersions now, it's not reachable. @@ -1052,7 +1119,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan return { packageRootPath, moduleFileToTry }; } else if ( - packageJsonContent.type !== "module" && + packageJsonContent?.type !== "module" && !fileExtensionIsOneOf(canonicalModuleFileToTry, extensionsNotSupportingExtensionlessResolution) && startsWith(canonicalModuleFileToTry, mainExportFile) && getDirectoryPath(canonicalModuleFileToTry) === removeTrailingDirectorySeparator(mainExportFile) && diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b8aab9a8563c4..e56bba5ab4859 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -9690,6 +9690,7 @@ export interface ModuleSpecifierResolutionHost { getProjectReferenceRedirect(fileName: string): string | undefined; isSourceOfProjectReferenceRedirect(fileName: string): boolean; getFileIncludeReasons(): MultiMap; + getCommonSourceDirectory(): string; } /** @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 347be386b6b32..398b7f1e61305 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7484,6 +7484,16 @@ export function readJson(path: string, host: { readFile(fileName: string): strin return readJsonOrUndefined(path, host) || {}; } +/** @internal */ +export function tryParseJson(text: string) { + try { + return JSON.parse(text); + } + catch { + return undefined; + } +} + /** @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean; }): boolean { // if host does not support 'directoryExists' assume that directory will exist diff --git a/src/services/utilities.ts b/src/services/utilities.ts index bb505008bedb8..2f065b1a39cf0 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -362,6 +362,7 @@ import { tokenToString, toPath, tryCast, + tryParseJson, Type, TypeChecker, TypeFlags, @@ -2473,6 +2474,7 @@ export function createModuleSpecifierResolutionHost(program: Program, host: Lang isSourceOfProjectReferenceRedirect: fileName => program.isSourceOfProjectReferenceRedirect(fileName), getNearestAncestorDirectoryWithPackageJson: maybeBind(host, host.getNearestAncestorDirectoryWithPackageJson), getFileIncludeReasons: () => program.getFileIncludeReasons(), + getCommonSourceDirectory: () => program.getCommonSourceDirectory(), }; } @@ -3895,15 +3897,6 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: } } -function tryParseJson(text: string) { - try { - return JSON.parse(text); - } - catch { - return undefined; - } -} - /** @internal */ export function consumesNodeCoreModules(sourceFile: SourceFile): boolean { return some(sourceFile.imports, ({ text }) => JsTyping.nodeCoreModules.has(text)); diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap1.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap1.js new file mode 100644 index 0000000000000..28bbf58340b78 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap1.js @@ -0,0 +1,357 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/package.json] +{ + "type": "module", + "imports": { + "#is-browser": { + "browser": "./dist/env/browser.js", + "default": "./dist/env/node.js" + } + } +} + +//// [/src/a.ts] +isBrowser + +//// [/src/env/browser.ts] +export const isBrowser = true; + +//// [/src/env/node.ts] +export const isBrowser = false; + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rootDir": "src", + "outDir": "dist" + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /tsconfig.json :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/src/a.ts", + "/src/env/browser.ts", + "/src/env/node.ts" + ], + "options": { + "module": 199, + "rootDir": "/src", + "outDir": "/dist", + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/env/browser.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/env/node.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /lib.d.ts Text-1 lib.d.ts-Text + /src/a.ts Text-1 "isBrowser" + /src/env/browser.ts Text-1 "export const isBrowser = true;" + /src/env/node.ts Text-1 "export const isBrowser = false;" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + src/a.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/env/browser.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/env/node.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"rootDir\": \"src\",\n \"outDir\": \"dist\"\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/package.json: *new* + {"pollingInterval":250} +/src/a.ts: *new* + {"pollingInterval":500} +/src/env/browser.ts: *new* + {"pollingInterval":500} +/src/env/node.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +: *new* + {} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'isBrowser'.", + "start": 0, + "length": 9, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 10 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 10, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [ + { + "fixName": "import", + "description": "Add import from \"./env/browser.js\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { isBrowser } from \"./env/browser.js\";\r\n\r\n" + } + ] + } + ] + }, + { + "fixName": "import", + "description": "Add import from \"#is-browser\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { isBrowser } from \"#is-browser\";\r\n\r\n" + } + ] + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap2.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap2.js new file mode 100644 index 0000000000000..0faa37e2e0945 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap2.js @@ -0,0 +1,321 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/package.json] +{ + "type": "module", + "imports": { + "#internal/*": "./dist/internal/*" + } +} + +//// [/src/a.ts] +something + +//// [/src/internal/foo.ts] +export function something(name: string) {} + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rootDir": "src", + "outDir": "dist" + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /tsconfig.json :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/src/a.ts", + "/src/internal/foo.ts" + ], + "options": { + "module": 199, + "rootDir": "/src", + "outDir": "/dist", + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/internal/foo.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /lib.d.ts Text-1 lib.d.ts-Text + /src/a.ts Text-1 "something" + /src/internal/foo.ts Text-1 "export function something(name: string) {}" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + src/a.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/internal/foo.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"rootDir\": \"src\",\n \"outDir\": \"dist\"\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/package.json: *new* + {"pollingInterval":250} +/src/a.ts: *new* + {"pollingInterval":500} +/src/internal/foo.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +: *new* + {} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'something'.", + "start": 0, + "length": 9, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 10 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 10, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [ + { + "fixName": "import", + "description": "Add import from \"#internal/foo.js\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { something } from \"#internal/foo.js\";\r\n\r\n" + } + ] + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap3.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap3.js new file mode 100644 index 0000000000000..b2621096bd175 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap3.js @@ -0,0 +1,321 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/package.json] +{ + "type": "module", + "imports": { + "#internal/": "./dist/internal/" + } +} + +//// [/src/a.ts] +something + +//// [/src/internal/foo.ts] +export function something(name: string) {} + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rootDir": "src", + "outDir": "dist" + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /tsconfig.json :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/src/a.ts", + "/src/internal/foo.ts" + ], + "options": { + "module": 199, + "rootDir": "/src", + "outDir": "/dist", + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/internal/foo.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /lib.d.ts Text-1 lib.d.ts-Text + /src/a.ts Text-1 "something" + /src/internal/foo.ts Text-1 "export function something(name: string) {}" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + src/a.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/internal/foo.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"rootDir\": \"src\",\n \"outDir\": \"dist\"\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/package.json: *new* + {"pollingInterval":250} +/src/a.ts: *new* + {"pollingInterval":500} +/src/internal/foo.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +: *new* + {} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'something'.", + "start": 0, + "length": 9, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 10 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 10, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [ + { + "fixName": "import", + "description": "Add import from \"#internal/foo.js\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { something } from \"#internal/foo.js\";\r\n\r\n" + } + ] + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap4.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap4.js new file mode 100644 index 0000000000000..e25af521ae67b --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap4.js @@ -0,0 +1,324 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/package.json] +{ + "type": "module", + "imports": { + "#is-browser": { + "types": "./dist/env/browser.d.ts", + "default": "./dist/env/browser.js" + } + } +} + +//// [/src/a.ts] +isBrowser + +//// [/src/env/browser.ts] +export const isBrowser = true; + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rootDir": "src", + "outDir": "dist" + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /tsconfig.json :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/src/a.ts", + "/src/env/browser.ts" + ], + "options": { + "module": 199, + "rootDir": "/src", + "outDir": "/dist", + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/env/browser.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /lib.d.ts Text-1 lib.d.ts-Text + /src/a.ts Text-1 "isBrowser" + /src/env/browser.ts Text-1 "export const isBrowser = true;" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + src/a.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/env/browser.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"rootDir\": \"src\",\n \"outDir\": \"dist\"\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/package.json: *new* + {"pollingInterval":250} +/src/a.ts: *new* + {"pollingInterval":500} +/src/env/browser.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +: *new* + {} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'isBrowser'.", + "start": 0, + "length": 9, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 10 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 10, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [ + { + "fixName": "import", + "description": "Add import from \"#is-browser\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { isBrowser } from \"#is-browser\";\r\n\r\n" + } + ] + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap5.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap5.js new file mode 100644 index 0000000000000..9440f3f24757c --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_importsMap5.js @@ -0,0 +1,341 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/package.json] +{ + "type": "module", + "imports": { + "#is-browser": { + "types": "./types/env/browser.d.ts", + "default": "./not-dist-on-purpose/env/browser.js" + } + } +} + +//// [/src/a.ts] +isBrowser + +//// [/src/env/browser.ts] +export const isBrowser = true; + +//// [/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rootDir": "src", + "outDir": "dist", + "declarationDir": "types", + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /tsconfig.json :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/lib.d.ts", + "/lib.decorators.d.ts", + "/lib.decorators.legacy.d.ts", + "/src/a.ts", + "/src/env/browser.ts" + ], + "options": { + "module": 199, + "rootDir": "/src", + "outDir": "/dist", + "declarationDir": "/types", + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: 1 undefined Config: /tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /src/env/browser.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /lib.d.ts Text-1 lib.d.ts-Text + /src/a.ts Text-1 "isBrowser" + /src/env/browser.ts Text-1 "export const isBrowser = true;" + + + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + Matched by default include pattern '**/*' + lib.d.ts + Matched by default include pattern '**/*' + src/a.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + src/env/browser.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tsconfig.json", + "configFile": "/tsconfig.json", + "diagnostics": [ + { + "start": { + "line": 6, + "offset": 5 + }, + "end": { + "line": 6, + "offset": 21 + }, + "text": "Option 'declarationDir' cannot be specified without specifying option 'declaration' or option 'composite'.", + "code": 5069, + "category": "error", + "fileName": "/tsconfig.json" + } + ] + } + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"rootDir\": \"src\",\n \"outDir\": \"dist\",\n \"declarationDir\": \"types\",\n }\n}" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/package.json: *new* + {"pollingInterval":250} +/src/a.ts: *new* + {"pollingInterval":500} +/src/env/browser.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +: *new* + {} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "preferences": { + "includeCompletionsForModuleExports": true, + "includeCompletionsWithInsertText": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [ + { + "message": "Cannot find name 'isBrowser'.", + "start": 0, + "length": 9, + "category": "error", + "code": 2304, + "startLocation": { + "line": 1, + "offset": 1 + }, + "endLocation": { + "line": 1, + "offset": 10 + } + } + ] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "includeLinePosition": true + }, + "command": "suggestionDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "suggestionDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/src/a.ts", + "startLine": 1, + "startOffset": 1, + "endLine": 1, + "endOffset": 10, + "errorCodes": [ + 2304 + ] + }, + "command": "getCodeFixes" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getCodeFixes", + "request_seq": 5, + "success": true, + "body": [ + { + "fixName": "import", + "description": "Add import from \"#is-browser\"", + "changes": [ + { + "fileName": "/src/a.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { isBrowser } from \"#is-browser\";\r\n\r\n" + } + ] + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/cases/fourslash/autoImportPackageJsonExportsSpecifierEndsInTs.ts b/tests/cases/fourslash/autoImportPackageJsonExportsSpecifierEndsInTs.ts new file mode 100644 index 0000000000000..7784b0334f929 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonExportsSpecifierEndsInTs.ts @@ -0,0 +1,27 @@ +/// + +// @module: nodenext + +// @Filename: /node_modules/pkg/package.json +//// { +//// "name": "pkg", +//// "version": "1.0.0", +//// "exports": { +//// "./something.ts": "./a.js" +//// } +//// } + +// @Filename: /node_modules/pkg/a.d.ts +//// export function foo(): void; + +// @Filename: /package.json +//// { +//// "dependencies": { +//// "pkg": "*" +//// } +//// } + +// @Filename: /index.ts +//// foo/**/ + +verify.importFixModuleSpecifiers("", ["pkg/something.ts"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsConditions.ts b/tests/cases/fourslash/autoImportPackageJsonImportsConditions.ts new file mode 100644 index 0000000000000..71fd139167ca9 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsConditions.ts @@ -0,0 +1,22 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#thing": { +//// "types": { "import": "./types-esm/thing.d.mts", "require": "./types/thing.d.ts" }, +//// "default": { "import": "./esm/thing.mjs", "require": "./dist/thing.js" } +//// } +//// } +//// } + + +// @Filename: /src/.ts +//// something/*a*/ + +// @Filename: /types/thing.d.ts +//// export function something(name: string): any; + +verify.importFixModuleSpecifiers("a", ["#thing"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsLength1.ts b/tests/cases/fourslash/autoImportPackageJsonImportsLength1.ts new file mode 100644 index 0000000000000..ae0999fb7a3b0 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsLength1.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/a/b/c/something.ts +//// export function something(name: string): any; + +// @Filename: /src/a/b/c/d.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["./something"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsLength2.ts b/tests/cases/fourslash/autoImportPackageJsonImportsLength2.ts new file mode 100644 index 0000000000000..5b54f6b3149c4 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsLength2.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/a/b/c/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#a/b/c/something"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern.ts new file mode 100644 index 0000000000000..70aeabcfdaaea --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something.js"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js.ts new file mode 100644 index 0000000000000..a5955a65c9275 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.js" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js_ts.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js_ts.ts new file mode 100644 index 0000000000000..bf9b3305d77bb --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_js_ts.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*.js": "./src/*.ts" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something.js"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts.ts new file mode 100644 index 0000000000000..a48ef7d4bc720 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_js.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_js.ts new file mode 100644 index 0000000000000..701b8fbd978b8 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_js.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*.ts": "./src/*.js" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something.ts"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_ts.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_ts.ts new file mode 100644 index 0000000000000..19171deea3b58 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPattern_ts_ts.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*.ts": "./src/*.ts" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#something.ts"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPreference1.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPreference1.ts new file mode 100644 index 0000000000000..dfac2a3ab55d0 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPreference1.ts @@ -0,0 +1,20 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/a/b/c/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["./src/a/b/c/something"], { + importModuleSpecifierPreference: "relative" +}); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPreference2.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPreference2.ts new file mode 100644 index 0000000000000..affd548cfa3ce --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPreference2.ts @@ -0,0 +1,20 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/a/b/c/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["./src/a/b/c/something"], { + importModuleSpecifierPreference: "project-relative" +}); diff --git a/tests/cases/fourslash/autoImportPackageJsonImportsPreference3.ts b/tests/cases/fourslash/autoImportPackageJsonImportsPreference3.ts new file mode 100644 index 0000000000000..3113af1bab627 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImportsPreference3.ts @@ -0,0 +1,20 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#*": "./src/*.ts" +//// } +//// } + +// @Filename: /src/a/b/c/something.ts +//// export function something(name: string): any; + +// @Filename: /src/a/b/c/d.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#a/b/c/something"], { + importModuleSpecifierPreference: "non-relative" +}); diff --git a/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath1.ts b/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath1.ts new file mode 100644 index 0000000000000..81b698ebd4d4c --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath1.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /Dev/package.json +//// { +//// "imports": { +//// "#thing": "./src/something.js" +//// } +//// } + +// @Filename: /Dev/src/something.ts +//// export function something(name: string): any; + +// @Filename: /Dev/a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#thing"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath2.ts b/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath2.ts new file mode 100644 index 0000000000000..eb0b0f6838140 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImports_capsInPath2.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /Dev/package.json +//// { +//// "imports": { +//// "#thing/*": "./src/*.js" +//// } +//// } + +// @Filename: /Dev/src/something.ts +//// export function something(name: string): any; + +// @Filename: /Dev/a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#thing/something"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImports_js.ts b/tests/cases/fourslash/autoImportPackageJsonImports_js.ts new file mode 100644 index 0000000000000..1056d13dd5076 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImports_js.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#thing": "./src/something.js" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#thing"]); diff --git a/tests/cases/fourslash/autoImportPackageJsonImports_ts.ts b/tests/cases/fourslash/autoImportPackageJsonImports_ts.ts new file mode 100644 index 0000000000000..a8e8b13b3d6e4 --- /dev/null +++ b/tests/cases/fourslash/autoImportPackageJsonImports_ts.ts @@ -0,0 +1,18 @@ +/// + +// @module: nodenext + +// @Filename: /package.json +//// { +//// "imports": { +//// "#thing": "./src/something.ts" +//// } +//// } + +// @Filename: /src/something.ts +//// export function something(name: string): any; + +// @Filename: /a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#thing"]); diff --git a/tests/cases/fourslash/server/autoImportProvider_importsMap1.ts b/tests/cases/fourslash/server/autoImportProvider_importsMap1.ts new file mode 100644 index 0000000000000..02f6072753d16 --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider_importsMap1.ts @@ -0,0 +1,32 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rootDir": "src", +//// "outDir": "dist" +//// } +//// } + +// @Filename: /package.json +//// { +//// "type": "module", +//// "imports": { +//// "#is-browser": { +//// "browser": "./dist/env/browser.js", +//// "default": "./dist/env/node.js" +//// } +//// } +//// } + +// @Filename: /src/env/browser.ts +//// export const isBrowser = true; + +// @Filename: /src/env/node.ts +//// export const isBrowser = false; + +// @Filename: /src/a.ts +//// isBrowser/**/ + +verify.importFixModuleSpecifiers("", ["./env/browser.js", "#is-browser"]); \ No newline at end of file diff --git a/tests/cases/fourslash/server/autoImportProvider_importsMap2.ts b/tests/cases/fourslash/server/autoImportProvider_importsMap2.ts new file mode 100644 index 0000000000000..934823091e79b --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider_importsMap2.ts @@ -0,0 +1,26 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rootDir": "src", +//// "outDir": "dist" +//// } +//// } + +// @Filename: /package.json +//// { +//// "type": "module", +//// "imports": { +//// "#internal/*": "./dist/internal/*" +//// } +//// } + +// @Filename: /src/internal/foo.ts +//// export function something(name: string) {} + +// @Filename: /src/a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#internal/foo.js"]); \ No newline at end of file diff --git a/tests/cases/fourslash/server/autoImportProvider_importsMap3.ts b/tests/cases/fourslash/server/autoImportProvider_importsMap3.ts new file mode 100644 index 0000000000000..d10e697685315 --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider_importsMap3.ts @@ -0,0 +1,26 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rootDir": "src", +//// "outDir": "dist" +//// } +//// } + +// @Filename: /package.json +//// { +//// "type": "module", +//// "imports": { +//// "#internal/": "./dist/internal/" +//// } +//// } + +// @Filename: /src/internal/foo.ts +//// export function something(name: string) {} + +// @Filename: /src/a.ts +//// something/**/ + +verify.importFixModuleSpecifiers("", ["#internal/foo.js"]); \ No newline at end of file diff --git a/tests/cases/fourslash/server/autoImportProvider_importsMap4.ts b/tests/cases/fourslash/server/autoImportProvider_importsMap4.ts new file mode 100644 index 0000000000000..11921f3fe52e6 --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider_importsMap4.ts @@ -0,0 +1,29 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rootDir": "src", +//// "outDir": "dist" +//// } +//// } + +// @Filename: /package.json +//// { +//// "type": "module", +//// "imports": { +//// "#is-browser": { +//// "types": "./dist/env/browser.d.ts", +//// "default": "./dist/env/browser.js" +//// } +//// } +//// } + +// @Filename: /src/env/browser.ts +//// export const isBrowser = true; + +// @Filename: /src/a.ts +//// isBrowser/**/ + +verify.importFixModuleSpecifiers("", ["#is-browser"]); \ No newline at end of file diff --git a/tests/cases/fourslash/server/autoImportProvider_importsMap5.ts b/tests/cases/fourslash/server/autoImportProvider_importsMap5.ts new file mode 100644 index 0000000000000..6f360f6b3bf51 --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider_importsMap5.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rootDir": "src", +//// "outDir": "dist", +//// "declarationDir": "types", +//// } +//// } + +// @Filename: /package.json +//// { +//// "type": "module", +//// "imports": { +//// "#is-browser": { +//// "types": "./types/env/browser.d.ts", +//// "default": "./not-dist-on-purpose/env/browser.js" +//// } +//// } +//// } + +// @Filename: /src/env/browser.ts +//// export const isBrowser = true; + +// @Filename: /src/a.ts +//// isBrowser/**/ + +verify.importFixModuleSpecifiers("", ["#is-browser"]); \ No newline at end of file