Skip to content

Commit

Permalink
fix(compartment-mapper): Take only first matching tag of package expo…
Browse files Browse the repository at this point in the history
…rts (#2275)

Closes: #2276

## Description

If a `package.json` `"exports"` is a list of ordered constraints, Endo’s
Compartment Mapper currently uses all of the accepted entries and not
just the first. This causes subsequent entries to override the first if
they produce matching paths. I believe the intended behavior is to use
the first that matches.

### Security Considerations

This amounts to a difference in behavior between Endo and Node in the
treatment of Package Exports.

### Scaling Considerations

None.

### Documentation Considerations

Fixing this issue will bring Endo into accord with Node.js’s somewhat
light documentation on this feature.

### Testing Considerations

Existing snapshot tests cover the behavior and must be updated to
reflect the correct interpretation.

### Compatibility Considerations

This will improve ecosystem compatibility. No known bundles depend on
the existing behavior, but we cannot rule out the possibility.

There is a possibility that this change will break existing bundles that
depend on the current erroneous behavior, for example preferring
`default` over an `endo` tag. I am considering this a bugfix and not a
breaking change since it is a bug to rely on the current behavior.

### Upgrade Considerations

Even if this behavior might break the bundling process for existing
contracts, it will not invalidate existing bundles. This change should
not break upgrades but may create a speed bump for upgrading tool
dependencies.
  • Loading branch information
kriskowal authored May 28, 2024
2 parents 8f14465 + 7e7654d commit bb6e908
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 22 deletions.
6 changes: 6 additions & 0 deletions packages/compartment-mapper/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
User-visible changes to the compartment mapper:

# Next release

- Fixes incompatible behavior with Node.js package conditional exports #2276.
Previously, the last matching tag would override all prior matches, often
causing a bundle to adopt the `default` instead of a more specific condition.

# 0.9.0 (2023-08-07)

- Introduces support for source map generation.
Expand Down
2 changes: 2 additions & 0 deletions packages/compartment-mapper/src/infer-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ function* interpretExports(name, exports, tags) {
}
} else if (tags.has(key)) {
yield* interpretExports(name, value, tags);
// Take only the first matching tag.
break;
}
}
}
Expand Down
44 changes: 22 additions & 22 deletions packages/compartment-mapper/test/snapshots/infer-exports.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'.': './underscore-umd.js',
'.': './underscore-node.mjs',
'./amd/*': './amd/*',
'./cjs/*': './cjs/*',
'./modules/*': './modules/*',
Expand All @@ -42,7 +42,7 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'.': './dist/vue.runtime.esm-bundler.js',
'.': './index.mjs',
'./compiler-sfc': './compiler-sfc/index.mjs',
'./dist/*': './dist/*',
'./macros': './macros.d.ts',
Expand All @@ -62,7 +62,7 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'.': './build/esm/index.js',
'.': './build/esm-debug/index.js',
'./dist/socket.io.js': './dist/socket.io.js',
'./dist/socket.io.js.map': './dist/socket.io.js.map',
'./package.json': './package.json',
Expand All @@ -78,7 +78,7 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'.': './lib/index.js',
'.': './esm/index.mjs',
'./package.json': './package.json',
},
types: {},
Expand All @@ -90,7 +90,7 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'.': './dist/index.exports.require.cjs.js',
'.': './dist/index.exports.import.es.mjs',
'./package.json': './package.json',
},
types: {
Expand All @@ -104,36 +104,36 @@ Generated by [AVA](https://avajs.dev).
{
exports: {
'./_sha2': './_sha2.js',
'./blake2b': './blake2b.js',
'./_sha2': './esm/_sha2.js',
'./blake2b': './esm/blake2b.js',
'./blake2b.d.ts': './blake2b.d.ts',
'./blake2s': './blake2s.js',
'./blake2s': './esm/blake2s.js',
'./blake2s.d.ts': './blake2s.d.ts',
'./blake3': './blake3.js',
'./blake3': './esm/blake3.js',
'./blake3.d.ts': './blake3.d.ts',
'./crypto': './crypto.js',
'./eskdf': './eskdf.js',
'./crypto': './esm/crypto.js',
'./eskdf': './esm/eskdf.js',
'./eskdf.d.ts': './eskdf.d.ts',
'./hkdf': './hkdf.js',
'./hkdf': './esm/hkdf.js',
'./hkdf.d.ts': './hkdf.d.ts',
'./hmac': './hmac.js',
'./hmac': './esm/hmac.js',
'./hmac.d.ts': './hmac.d.ts',
'./index': './index.js',
'./pbkdf2': './pbkdf2.js',
'./index': './esm/index.js',
'./pbkdf2': './esm/pbkdf2.js',
'./pbkdf2.d.ts': './pbkdf2.d.ts',
'./ripemd160': './ripemd160.js',
'./ripemd160': './esm/ripemd160.js',
'./ripemd160.d.ts': './ripemd160.d.ts',
'./scrypt': './scrypt.js',
'./scrypt': './esm/scrypt.js',
'./scrypt.d.ts': './scrypt.d.ts',
'./sha256': './sha256.js',
'./sha256': './esm/sha256.js',
'./sha256.d.ts': './sha256.d.ts',
'./sha3': './sha3.js',
'./sha3-addons': './sha3-addons.js',
'./sha3': './esm/sha3.js',
'./sha3-addons': './esm/sha3-addons.js',
'./sha3-addons.d.ts': './sha3-addons.d.ts',
'./sha3.d.ts': './sha3.d.ts',
'./sha512': './sha512.js',
'./sha512': './esm/sha512.js',
'./sha512.d.ts': './sha512.d.ts',
'./utils': './utils.js',
'./utils': './esm/utils.js',
'./utils.d.ts': './utils.d.ts',
},
types: {},
Expand Down
Binary file not shown.

0 comments on commit bb6e908

Please sign in to comment.