Skip to content

fix: resolve CJS type declarations via exports require condition#29

Merged
ben-vargas merged 1 commit into
mainfrom
claude/adoring-banzai-a50adb
Jun 11, 2026
Merged

fix: resolve CJS type declarations via exports require condition#29
ben-vargas merged 1 commit into
mainfrom
claude/adoring-banzai-a50adb

Conversation

@ben-vargas

Copy link
Copy Markdown
Owner

Problem

Both publint and @arethetypeswrong/cli flag the package exports: exports["."] had a single "types": "./dist/index.d.ts" (ESM declarations) alongside "require": "./dist/index.cjs". TypeScript consumers using CommonJS under node16/nodenext module resolution got "Masquerading as ESM" (FalseESM) — the types claim ESM but the runtime file is CJS.

The build (tsup) already emits ./dist/index.d.cts; it just wasn't wired up.

Fix

Split the exports["."] conditions so each runtime format resolves matching declarations:

".": {
  "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
  "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
}

./package.json export and top-level main/module/types (node10 resolution) unchanged. No build changes needed.

Also adds a CHANGELOG entry under the unreleased 3.0.5 section.

Verification

  • npm run build — emits index.js, index.cjs, index.d.ts, index.d.cts
  • npx publintAll good!
  • npx @arethetypeswrong/cli --pack .No problems found, all green including node16-from-CJS (previously 🥸 FalseESM)
  • Smoke test: installed the packed tarball in a temp dir; both require() and import load the full API, and tsc --module node16 --moduleResolution node16 --strict --skipLibCheck passes for both .cts and .mts consumers
  • npm run ci — typecheck, lint, 358/358 tests pass

Note (pre-existing, out of scope)

With skipLibCheck: false, node16 CJS consumers still hit TS1479 inside dist/index.d.cts because it imports types from @opencode-ai/sdk/v2, which is ESM-only upstream (no require condition; that's also why index.cjs loads it via dynamic import() at runtime). Invisible to standard configs (skipLibCheck: true) and not fixable in this package's exports.

Split the exports["."] entry into import/require condition blocks so
require resolves the CommonJS declarations (./dist/index.d.cts) that
tsup already emits, instead of the ESM ./dist/index.d.ts. Fixes the
"Masquerading as ESM" (FalseESM) finding from @arethetypeswrong/cli
for TypeScript consumers using require() under node16/nodenext module
resolution. publint and attw --pack are now clean across all
resolution modes.
@ben-vargas
ben-vargas merged commit 0e807d1 into main Jun 11, 2026
3 checks passed
@ben-vargas
ben-vargas deleted the claude/adoring-banzai-a50adb branch June 11, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant