Repository navigation
Conversation
The runtime build already ships dual entries (lib/index.cjs with module.exports = Schema, lib/index.mjs with a default export), but package.json has no exports map and the only declaration file uses the CJS export assignment shape, so NodeNext/bundler consumers cannot describe the ESM entry. - package.json (core): add type:module, types, and an exports map wiring index.d.mts to the import condition and index.d.cts to the require condition. - scripts/dual-types.mjs: derive index.d.cts (verbatim, keeps export = Schema) and index.d.mts (export default Schema + type-only export of the Schema alias) from the tsc-emitted index.d.ts. - package.json (root): run the dual-types step as part of build.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
schemastery@3.18.0 has no exports map, no types field and no type:module.
Its only declaration file ends with
export = Schemawhile the ESM entry(lib/index.mjs) exposes Schema as its default export, so ESM consumers
cannot describe the runtime they get. Full evidence matrix: see the linked
issue #77.
Approach
Runtime and source stay untouched. Add an exports map that wires each
condition to a declaration matching its runtime shape:
Both files are derived from the tsc-emitted index.d.ts by the new
scripts/dual-types.mjs, which fails loudly if the expected trailing
export = Schema;is ever absent. The top-level types field points atindex.d.cts, so legacy resolvers see the same shape as today. type:module
is safe: the package ships no bare .js files.
Why not a manifest-only exports map (single index.d.ts)? Measured result:
default imports regress to TS1192 and
import = requireto TS1471 - anexport =declaration cannot describe an ESM entry, so the dualdeclarations are required.
Why not change the source to
export default Schema? That would change theemitted JS: esbuild would wrap the CJS output so require() consumers get
{ default: Schema } instead of Schema. Splitting only the declaration layer
avoids every runtime change.
Evidence (measured, not assumed)
Red, current 3.18.0 tarball, tsc 5.9.3, strict + verbatimModuleSyntax:
Green, packed build from this branch (tsc 5.9.3 + esbuild 0.28, the repo's
own build settings, then npm pack):
Checklist
yarn is not installed in this environment; I validated with
npx tsc --build packages/core + esbuild + npm pack instead)
Note
Named exports from the ESM entry remain unavailable (the .mjs exposes only
a default export). Adding them needs a source export refactor - left out of
this PR by design; see issue #77 for the follow-up.