From 4696aadc8d696702d877836d6f6bda86a784c2f8 Mon Sep 17 00:00:00 2001 From: seveibar Date: Mon, 1 Dec 2025 11:17:35 -0800 Subject: [PATCH 1/2] importName eval --- lib/eval/import-eval-path.ts | 69 ++++++++----------- ...kage.ts => import-npm-package-from-cdn.ts} | 23 ++----- lib/eval/index.ts | 2 +- 3 files changed, 34 insertions(+), 60 deletions(-) rename lib/eval/{import-npm-package.ts => import-npm-package-from-cdn.ts} (72%) diff --git a/lib/eval/import-eval-path.ts b/lib/eval/import-eval-path.ts index 34b274d7..8071819c 100644 --- a/lib/eval/import-eval-path.ts +++ b/lib/eval/import-eval-path.ts @@ -4,7 +4,7 @@ import { importSnippet } from "./import-snippet" import { resolveFilePath } from "lib/runner/resolveFilePath" import { resolveNodeModule } from "lib/utils/resolve-node-module" import { importNodeModule } from "./import-node-module" -import { importNpmPackage } from "./import-npm-package" +import { importNpmPackageFromCdn as importNpmPackageFromCdn } from "./import-npm-package-from-cdn" import { getTsConfig, matchesTsconfigPathPattern, @@ -24,7 +24,6 @@ export async function importEvalPath( depth = 0, opts: { cwd?: string - fromJsDelivr?: boolean } = {}, ) { debug("importEvalPath called with:", { @@ -97,12 +96,8 @@ export async function importEvalPath( `Cannot find module "${pkgName}". The package is not available in the local environment.\n\n${ctx.logger.stringifyLogs()}`, ) } - ctx.logger.info(`importNpmPackage("${pkgName}")`) - // /npm/ paths are always transitive dependencies from jsDelivr - await importNpmPackage( - { importName: pkgName, depth, fromJsDelivr: true }, - ctx, - ) + ctx.logger.info(`importNpmPackageFromCdn("${pkgName}")`) + await importNpmPackageFromCdn({ importName: pkgName, depth }, ctx) const pkg = preSuppliedImports[pkgName] if (pkg) { preSuppliedImports[importName] = pkg @@ -198,41 +193,38 @@ export async function importEvalPath( } if (!importName.startsWith(".") && !importName.startsWith("/")) { - // Validation steps for node modules (before jsDelivr fallback) - if (!opts.fromJsDelivr) { - // Step 1: Check if package is declared in package.json - if (!isPackageDeclaredInPackageJson(importName, ctx.fsMap)) { - throw new Error( - `Node module imported but not in package.json "${importName}"\n\n${ctx.logger.stringifyLogs()}`, - ) - } + // Step 1: Check if package is declared in package.json + if (!isPackageDeclaredInPackageJson(importName, ctx.fsMap)) { + throw new Error( + `Node module imported but not in package.json "${importName}"\n\n${ctx.logger.stringifyLogs()}`, + ) + } - // Step 2: Check if node_modules directory exists (only if not found locally yet) - // Only validate if CDN loading is disabled (i.e., no fallback to jsDelivr available) - const nodeModuleDir = getNodeModuleDirectory(importName, ctx.fsMap) - if (!nodeModuleDir && disableCdnLoading) { + // Step 2: Check if node_modules directory exists (only if not found locally yet) + // Only validate if CDN loading is disabled (i.e., no fallback to jsDelivr available) + const nodeModuleDir = getNodeModuleDirectory(importName, ctx.fsMap) + if (!nodeModuleDir && disableCdnLoading) { + throw new Error( + `Node module "${importName}" has no files in the node_modules directory\n\n${ctx.logger.stringifyLogs()}`, + ) + } + + // Step 3: Check if main entrypoint is a TypeScript file (only if dir exists) + if (nodeModuleDir) { + const entrypoint = getPackageJsonEntrypoint(importName, ctx.fsMap) + if (isTypeScriptEntrypoint(entrypoint)) { throw new Error( - `Node module "${importName}" has no files in the node_modules directory\n\n${ctx.logger.stringifyLogs()}`, + `Node module "${importName}" has a typescript entrypoint that is unsupported\n\n${ctx.logger.stringifyLogs()}`, ) } - // Step 3: Check if main entrypoint is a TypeScript file (only if dir exists) - if (nodeModuleDir) { - const entrypoint = getPackageJsonEntrypoint(importName, ctx.fsMap) - if (isTypeScriptEntrypoint(entrypoint)) { + // Step 4: Check if dist directory is empty when main points to dist + if (entrypoint?.startsWith("dist/")) { + if (isDistDirEmpty(importName, ctx.fsMap)) { throw new Error( - `Node module "${importName}" has a typescript entrypoint that is unsupported\n\n${ctx.logger.stringifyLogs()}`, + `Node module "${importName}" has no files in dist, did you forget to transpile?\n\n${ctx.logger.stringifyLogs()}`, ) } - - // Step 4: Check if dist directory is empty when main points to dist - if (entrypoint && entrypoint.startsWith("dist/")) { - if (isDistDirEmpty(importName, ctx.fsMap)) { - throw new Error( - `Node module "${importName}" has no files in dist, did you forget to transpile?\n\n${ctx.logger.stringifyLogs()}`, - ) - } - } } } @@ -241,11 +233,8 @@ export async function importEvalPath( `Cannot find module "${importName}". The package is not available in the local environment.\n\n${ctx.logger.stringifyLogs()}`, ) } - ctx.logger.info(`importNpmPackage("${importName}")`) - return importNpmPackage( - { importName, depth, fromJsDelivr: opts.fromJsDelivr }, - ctx, - ) + ctx.logger.info(`importNpmPackageFromCdn("${importName}")`) + return importNpmPackageFromCdn({ importName, depth }, ctx) } throw new Error( diff --git a/lib/eval/import-npm-package.ts b/lib/eval/import-npm-package-from-cdn.ts similarity index 72% rename from lib/eval/import-npm-package.ts rename to lib/eval/import-npm-package-from-cdn.ts index e785b996..b71f7315 100644 --- a/lib/eval/import-npm-package.ts +++ b/lib/eval/import-npm-package-from-cdn.ts @@ -5,7 +5,6 @@ import Debug from "debug" import { getImportsFromCode } from "lib/utils/get-imports-from-code" import { importEvalPath } from "./import-eval-path" import { transformWithSucrase } from "lib/transpile/transform-with-sucrase" -import { isPackageDeclaredInPackageJson } from "./isPackageDeclaredInPackageJson" const debug = Debug("tsci:eval:import-npm-package") @@ -17,28 +16,15 @@ function extractPackagePathFromJSDelivr(url: string) { return url } -export async function importNpmPackage( - { - importName, - depth = 0, - fromJsDelivr = false, - }: { importName: string; depth?: number; fromJsDelivr?: boolean }, +export async function importNpmPackageFromCdn( + { importName, depth = 0 }: { importName: string; depth?: number }, ctx: ExecutionContext, ) { - debug(`importing npm package: ${importName}`) - const { preSuppliedImports, fsMap } = ctx + debug(`importing npm package from CDN: ${importName}`) + const { preSuppliedImports } = ctx if (preSuppliedImports[importName]) return - // Check if the package is declared in package.json before fetching from jsDelivr - // Skip this check for transitive dependencies (sub-imports from jsDelivr packages) - if (!fromJsDelivr && !isPackageDeclaredInPackageJson(importName, fsMap)) { - throw new Error( - `Package "${importName}" is not declared in package.json. ` + - `Add it to dependencies or devDependencies before importing.\n\n${ctx.logger.stringifyLogs()}`, - ) - } - const npmCdnUrl = `https://cdn.jsdelivr.net/npm/${importName}/+esm` let finalUrl: string | undefined @@ -67,7 +53,6 @@ export async function importNpmPackage( if (!preSuppliedImports[subImportName]) { await importEvalPath(subImportName, ctx, depth + 1, { cwd, - fromJsDelivr: true, }) } } diff --git a/lib/eval/index.ts b/lib/eval/index.ts index 5534700f..7449813b 100644 --- a/lib/eval/index.ts +++ b/lib/eval/index.ts @@ -10,7 +10,7 @@ export { importEvalPath } from "./import-eval-path" export { importLocalFile } from "./import-local-file" export { importSnippet } from "./import-snippet" export { importNodeModule } from "./import-node-module" -export { importNpmPackage } from "./import-npm-package" +export { importNpmPackageFromCdn as importNpmPackage } from "./import-npm-package-from-cdn" export { evalCompiledJs } from "./eval-compiled-js" export { transformWithSucrase } from "lib/transpile/transform-with-sucrase" export { extractBasePackageName } from "./extractBasePackageName" From 68266a9fc7367ebc99d44af744f17e03c531d9a8 Mon Sep 17 00:00:00 2001 From: Severin Ibarluzea Date: Mon, 1 Dec 2025 11:35:41 -0800 Subject: [PATCH 2/2] Update lib/eval/import-eval-path.ts --- lib/eval/import-eval-path.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/eval/import-eval-path.ts b/lib/eval/import-eval-path.ts index 8071819c..61d55339 100644 --- a/lib/eval/import-eval-path.ts +++ b/lib/eval/import-eval-path.ts @@ -4,7 +4,7 @@ import { importSnippet } from "./import-snippet" import { resolveFilePath } from "lib/runner/resolveFilePath" import { resolveNodeModule } from "lib/utils/resolve-node-module" import { importNodeModule } from "./import-node-module" -import { importNpmPackageFromCdn as importNpmPackageFromCdn } from "./import-npm-package-from-cdn" +import { importNpmPackageFromCdn } from "./import-npm-package-from-cdn" import { getTsConfig, matchesTsconfigPathPattern,