Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions packages/core/src/checkPackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getEntrypointResolutionProblems } from "./checks/entrypointResolutionPr
import { getFileProblems } from "./checks/fileProblems.js";
import { getResolutionBasedFileProblems } from "./checks/resolutionBasedFileProblems.js";
import type { Package } from "./createPackage.js";
import { createMultiCompilerHost, type MultiCompilerHost } from "./multiCompilerHost.js";
import { createCompilerHosts, type CompilerHosts, CompilerHostWrapper } from "./multiCompilerHost.js";
import type { CheckResult, EntrypointInfo, EntrypointResolutionAnalysis, Resolution, ResolutionKind } from "./types.js";

export async function checkPackage(pkg: Package): Promise<CheckResult> {
Expand All @@ -20,11 +20,11 @@ export async function checkPackage(pkg: Package): Promise<CheckResult> {
return { packageName, packageVersion, types };
}

const host = createMultiCompilerHost(pkg);
const entrypointResolutions = getEntrypointInfo(packageName, pkg, host);
const entrypointResolutionProblems = getEntrypointResolutionProblems(entrypointResolutions, host);
const resolutionBasedFileProblems = getResolutionBasedFileProblems(packageName, entrypointResolutions, host);
const fileProblems = getFileProblems(entrypointResolutions, host);
const hosts = createCompilerHosts(pkg);
const entrypointResolutions = getEntrypointInfo(packageName, pkg, hosts);
const entrypointResolutionProblems = getEntrypointResolutionProblems(entrypointResolutions, hosts);
const resolutionBasedFileProblems = getResolutionBasedFileProblems(packageName, entrypointResolutions, hosts);
const fileProblems = getFileProblems(entrypointResolutions, hosts);

return {
packageName,
Expand Down Expand Up @@ -62,7 +62,7 @@ function getProxyDirectories(rootDir: string, fs: Package) {
.filter((f) => f !== "./");
}

function getEntrypointInfo(packageName: string, fs: Package, host: MultiCompilerHost): Record<string, EntrypointInfo> {
function getEntrypointInfo(packageName: string, fs: Package, hosts: CompilerHosts): Record<string, EntrypointInfo> {
const packageJson = JSON.parse(fs.readFile(`/node_modules/${packageName}/package.json`));
const subpaths = getSubpaths(packageJson.exports);
const entrypoints = subpaths.length ? subpaths : ["."];
Expand All @@ -72,10 +72,10 @@ function getEntrypointInfo(packageName: string, fs: Package, host: MultiCompiler
const result: Record<string, EntrypointInfo> = {};
for (const entrypoint of entrypoints) {
const resolutions: Record<ResolutionKind, EntrypointResolutionAnalysis> = {
node10: getEntrypointResolution(packageName, "node10", entrypoint, host),
"node16-cjs": getEntrypointResolution(packageName, "node16-cjs", entrypoint, host),
"node16-esm": getEntrypointResolution(packageName, "node16-esm", entrypoint, host),
bundler: getEntrypointResolution(packageName, "bundler", entrypoint, host),
node10: getEntrypointResolution(packageName, hosts.node10, "node10", entrypoint),
"node16-cjs": getEntrypointResolution(packageName, hosts.node16, "node16-cjs", entrypoint),
"node16-esm": getEntrypointResolution(packageName, hosts.node16, "node16-esm", entrypoint),
bundler: getEntrypointResolution(packageName, hosts.bundler, "bundler", entrypoint),
};
result[entrypoint] = {
subpath: entrypoint,
Expand All @@ -89,16 +89,15 @@ function getEntrypointInfo(packageName: string, fs: Package, host: MultiCompiler

function getEntrypointResolution(
packageName: string,
host: CompilerHostWrapper,
resolutionKind: ResolutionKind,
entrypoint: string,
host: MultiCompilerHost
entrypoint: string
): EntrypointResolutionAnalysis {
if (entrypoint.includes("*")) {
return { name: entrypoint, resolutionKind, isWildcard: true };
}
const moduleSpecifier = packageName + entrypoint.substring(1); // remove leading . before slash
const importingFileName = resolutionKind === "node16-esm" ? "/index.mts" : "/index.ts";
const moduleResolution = resolutionKind === "node10" ? "node10" : resolutionKind === "bundler" ? "bundler" : "node16";
const resolutionMode = resolutionKind === "node16-esm" ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS;

const resolution = tryResolve();
Expand All @@ -107,7 +106,7 @@ function getEntrypointResolution(

const files = resolution
? host
.createProgram(moduleResolution, [resolution.fileName])
.createProgram([resolution.fileName])
.getSourceFiles()
.map((f) => f.fileName)
: undefined;
Expand All @@ -124,7 +123,6 @@ function getEntrypointResolution(
const { resolution, trace } = host.resolveModuleName(
moduleSpecifier,
importingFileName,
moduleResolution,
resolutionMode,
noDtsResolution
);
Expand All @@ -135,7 +133,7 @@ function getEntrypointResolution(

return {
fileName,
moduleKind: host.getModuleKindForFile(fileName, moduleResolution),
moduleKind: host.getModuleKindForFile(fileName),
isJson: resolution.resolvedModule.extension === ts.Extension.Json,
isTypeScript: ts.hasTSFileExtension(resolution.resolvedModule.resolvedFileName),
trace,
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/checks/entrypointResolutionProblems.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import ts from "typescript";
import type { EntrypointInfo, EntrypointResolutionProblem } from "../types.js";
import type { MultiCompilerHost } from "../multiCompilerHost.js";
import type { CompilerHosts } from "../multiCompilerHost.js";
import { resolvedThroughFallback, visitResolutions } from "../utils.js";

export function getEntrypointResolutionProblems(
entrypointResolutions: Record<string, EntrypointInfo>,
host: MultiCompilerHost
hosts: CompilerHosts
): EntrypointResolutionProblem[] {
const problems: EntrypointResolutionProblem[] = [];
visitResolutions(entrypointResolutions, (result, entrypoint) => {
Expand Down Expand Up @@ -71,12 +71,12 @@ export function getEntrypointResolutionProblems(
}

if (resolutionKind === "node16-esm" && resolution && implementationResolution) {
const typesSourceFile = host.getSourceFile(resolution.fileName, "node16");
const typesSourceFile = hosts.node16.getSourceFile(resolution.fileName);
if (typesSourceFile) {
ts.bindSourceFile(typesSourceFile, { target: ts.ScriptTarget.Latest, allowJs: true, checkJs: true });
}
const typesExports = typesSourceFile?.symbol?.exports;
const jsSourceFile = typesExports && host.getSourceFile(implementationResolution.fileName, "node16");
const jsSourceFile = typesExports && hosts.node16.getSourceFile(implementationResolution.fileName);
if (jsSourceFile) {
ts.bindSourceFile(jsSourceFile, { target: ts.ScriptTarget.Latest, allowJs: true, checkJs: true });
}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/checks/fileProblems.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import ts from "typescript";
import type { MultiCompilerHost } from "../multiCompilerHost.js";
import type { CompilerHosts } from "../multiCompilerHost.js";
import type { EntrypointInfo, FileProblem } from "../types.js";
import { isDefined } from "../utils.js";

export function getFileProblems(
entrypointResolutions: Record<string, EntrypointInfo>,
host: MultiCompilerHost
hosts: CompilerHosts
): FileProblem[] {
const problems: FileProblem[] = [];
const visibleFiles = new Set(
Expand All @@ -18,7 +18,7 @@ export function getFileProblems(

for (const fileName of visibleFiles) {
if (ts.hasJSFileExtension(fileName)) {
const sourceFile = host.getSourceFile(fileName, "node16")!;
const sourceFile = hosts.node16.getSourceFile(fileName)!;
if (
!sourceFile.externalModuleIndicator &&
sourceFile.commonJsModuleIndicator &&
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/checks/resolutionBasedFileProblems.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import ts from "typescript";
import type { MultiCompilerHost } from "../multiCompilerHost.js";
import type { CompilerHosts } from "../multiCompilerHost.js";
import type { EntrypointInfo, ResolutionBasedFileProblem } from "../types.js";
import { allResolutionOptions, getResolutionKinds } from "../utils.js";

export function getResolutionBasedFileProblems(
packageName: string,
entrypointResolutions: Record<string, EntrypointInfo>,
host: MultiCompilerHost
hosts: CompilerHosts
): ResolutionBasedFileProblem[] {
const result: ResolutionBasedFileProblem[] = [];
for (const resolutionOption of allResolutionOptions) {
Expand All @@ -24,7 +24,8 @@ export function getResolutionBasedFileProblems(
);

for (const fileName of visibleFiles) {
const sourceFile = host.getSourceFile(fileName, resolutionOption)!;
const host = hosts[resolutionOption];
const sourceFile = host.getSourceFile(fileName)!;

if (sourceFile.imports) {
for (const moduleSpecifier of sourceFile.imports) {
Expand Down Expand Up @@ -52,7 +53,7 @@ export function getResolutionBasedFileProblems(
pos: moduleSpecifier.pos,
end: moduleSpecifier.end,
resolutionMode,
trace: host.getTrace(resolutionOption, fileName, moduleSpecifier.text, resolutionMode)!,
trace: host.getTrace(fileName, moduleSpecifier.text, resolutionMode)!,
});
}
}
Expand All @@ -67,7 +68,7 @@ export function getResolutionBasedFileProblems(
// for looking for a JS file.
if (resolutionOption === "node16") {
if (ts.hasJSFileExtension(fileName)) {
const expectedModuleKind = host.getModuleKindForFile(fileName, resolutionOption);
const expectedModuleKind = host.getModuleKindForFile(fileName);
const syntaxImpliedModuleKind = sourceFile.externalModuleIndicator
? ts.ModuleKind.ESNext
: sourceFile.commonJsModuleIndicator
Expand Down
Loading