diff --git a/package.json b/package.json index c6c7ea0..af9d4c7 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,9 @@ "import-meta-resolve": "^1.1.1", "jiti": "^1.12.5", "mocha": "^9.1.2", + "pathe": "^0.2.0", + "pkg-types": "^0.3.1", "standard-version": "latest", - "unbuild": "^0.5.7", - "pathe": "^0.2.0" + "unbuild": "^0.5.7" } } diff --git a/src/syntax.ts b/src/syntax.ts index 206b491..3b6c18f 100644 --- a/src/syntax.ts +++ b/src/syntax.ts @@ -1,5 +1,12 @@ +import { promises as fsp } from 'fs' +import { extname } from 'pathe' +import { readPackageJSON } from 'pkg-types' +import { ResolveOptions, resolvePath } from './resolve' + const ESM_RE = /([\s;]|^)(import[\s'"*{]|export\b|import\.meta\b)/m +const BUILTIN_EXTENSIONS = new Set(['.mjs', '.cjs', '.node', '.wasm']) + export function hasESMSyntax (code: string): boolean { return ESM_RE.test(code) } @@ -19,3 +26,27 @@ export function detectSyntax (code: string) { isMixed: hasESM && hasCJS } } + +export async function isValidNodeImport (id: string, opts: ResolveOptions & { code?: string } = {}): Promise { + const resolvedPath = await resolvePath(id, opts) + const extension = extname(resolvedPath) + + if (BUILTIN_EXTENSIONS.has(extension)) { + return true + } + + if (extension !== '.js') { + return false + } + + if (resolvedPath.match(/\.(\w+-)?esm?(-\w+)?\.js$/)) { + return false + } + + const pkg = await readPackageJSON(resolvedPath).catch(() => null) + if (pkg?.type === 'module') { return true } + + const code = opts.code || await fsp.readFile(resolvedPath, 'utf-8').catch(() => null) + + return !hasESMSyntax(code) +} diff --git a/yarn.lock b/yarn.lock index 4424b01..6f4d5a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2485,6 +2485,11 @@ mlly@^0.2.6: dependencies: import-meta-resolve "^1.1.1" +mlly@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-0.3.6.tgz#639867d616569d12a4aa1dff99f18a5e63126941" + integrity sha512-mSEVMwiNEjppuRmhfzWQgzZtC/N2eWiDAhIfTM1U4fO0zJjacJRDnaT//qNlmNbeWQn3fzDSA5UC6jsvAfL4AA== + mocha@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" @@ -2801,6 +2806,15 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-types@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-0.3.1.tgz#d7a8b69efb8777a05afc5aabfc259a29a5d6d159" + integrity sha512-BjECNgz/tsyqg0/T4Z/U7WbFQXUT24nfkxPbALcrk/uHVeZf9MrGG4tfvYtu+jsrHCFMseLQ6woQddDEBATw3A== + dependencies: + jsonc-parser "^3.0.0" + mlly "^0.3.6" + pathe "^0.2.0" + pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"