Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compartment mapper should take first matching of conditional exports #2276

Closed
kriskowal opened this issue May 8, 2024 · 1 comment · Fixed by #2275
Closed

Compartment mapper should take first matching of conditional exports #2276

kriskowal opened this issue May 8, 2024 · 1 comment · Fixed by #2275
Assignees
Labels
bug Something isn't working

Comments

@kriskowal
Copy link
Member

Describe the bug

Node.js package conditional imports should take the entries under the first matching tag and ignore all subsequent tags. This is hinted with the express advice that default must appear last if present.

Steps to reproduce

Create a bundle from a package that has conditional exports e.g., endo and default and note that default wins.

Expected behavior

The first match (node in the example) should win.

@kriskowal
Copy link
Member Author

This fix is necessary for progress toward native XS support #400.

kriskowal added a commit that referenced this issue May 28, 2024
…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.
kriskowal added a commit that referenced this issue Jul 30, 2024
# ses v1.6.0 (2024-07-30)

- *NOTICE*: This version introduces multiple features to converge upon a
more common standard for [Hardened JavaScript](https://hardenedjs.org).
  All code should begin migrating to these usage patterns as the older
patterns are now deprecated and will not be supported in a future major
  version of SES.

- To converge on a portable pattern for using `Compartment`, introduces
an
  `__options__` property for the first argument of the `Compartment`
constructor that must be `true` if present and indicates the object is
the
options bag and not the global endowments. All code going forward should
include this flag until the next major version of SES, when we plan for
it to
  become vesgitial and drop support for three-argument `Compartment`
  construction.

In the unlikely event that existing code names an endowment
`__options__`,
  that code will break and need to be adjusted to adopt this version.
  Because we rate this unlikely, we have elected not to mark this with
  a major version bump.

- Adds a `__noNamespaceBox__` option that aligns the behavior of the
`import`
method on SES `Compartment` with the behavior of XS and the behavior we
will
  champion for compartment standards.
All use of `Compartment` should migrate to use this option as the
standard
behavior will be enabled by default with the next major version of SES.

- Adds support for module descriptors better aligned with XS.
  Compartments use module desriptors to load and link modules.
The importHook, importNowHook, and moduleMapHook all return module
descriptors
  (sometimes promises for module descriptors).
The modules option or argument to the Compatment constructor has module
  descriptors for all its values.
  - `{record, specifier, compartment}` should become `{source: record,
    specifier, compartment}`.
  - `{specifier, compartment}` should become `{source: specifier,
    compartment}`.
  - `{record: compartment.module(specifier)}` should become `{namespace:
    specifier, compartment}`.

- When running transpiled code on Node, the SES error taming
gives line-numbers into the generated JavaScript, which often don't
match the
  the original lines. This happens even with the normal development-time
  lockdown options setting,
  ```js
  errorTaming: 'unsafe'
  ```
  or setting the environment variable
  ```sh
  $ export LOCKDOWN_ERROR_TAMING=unsafe
  ```
  To get the original line numbers, this release
  adds `'unsafe-debug'`. This `errorTaming: 'unsafe-debug'` setting
  should be used ***during development only*** when you can
sacrifice more security for a better debugging experience, as explained
at
[`errorTaming`
Options](https://github.com/endojs/endo/blob/master/packages/ses/docs/lockdown.md#errortaming-options).
With this setting, when running transpiled code on Node (e.g. tests
written
  in TypeScript),
  the stacktrace line-numbers point back into the original
  source, as they do on Node without SES.

# @endo/marshal v1.5.1 (2024-07-30)

- `deeplyFulfilled` moved from @endo/marshal to @endo/pass-style.
@endo/marshal still reexports it, to avoid breaking old importers. But
importers should be upgraded to import `deeplyFulfilled` directly from
@endo/pass-style.

# @endo/pass-style v1.4.1 (2024-07-30)

- `deeplyFulfilled` moved from @endo/marshal to @endo/pass-style.
@endo/marshal still reexports it, to avoid breaking old importers. But
importers should be upgraded to import `deeplyFulfilled` directly from
@endo/pass-style.

# @endo/bundle-source v3.3.0 (2024-07-30)

- Adds support for `--no-transforms` (`-T`) which generates bundles with
  original sources.
  A future version of `@endo/import-bundle` will be able to execute this
  kind of bundle on XS and in Node.js, but will remain opt-in because
  they cannot be made to run on the web without further work on module
  virtualization in the platform without entraining a client-side
  dependency on a JavaScript parser framework (namely Babel).
- Adds a `-f,--format` command flag to specify other module formats.
- Adds a new `endoScript` module format.
- Adds a no-cache, bundle-to-stdout mode.
- Adds a `-C,--condition` command flag to specify export/import
conditions like
  `"development"` or `"browser"`.
- The `-C development` condition now provides access to
`devDependencies` in
  the `package.json` of the entry package of a bundle.

# @endo/compartment-mapper v1.2.0 (2024-07-30)

- 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.
- Adds `parserForLanguage` and `languageForExtension` options to all
modes of
operation such that the compartment mapper can analyze and bundle
languages
  apart from the built-in languages, which include `esm` and `cjs`.
  The `languageForExtension` option provides defaults for the entire
  application and the `"parsers"` property in individual `package.json`
descriptors may extend or override using any of the configured or
built-in
  language parser names.
- Exports `import-lite.js`, `archive-lite.js`, `import-archive-lite.js`,
`import-parsers.js`, `archive-parsers.js`, `import-archive-parsers.js`,
and
  `node-modules.js`, allowing these to be mixed and matched.
The existing `import.js`, `archive.js`, and `import-archive.js` all
entrain
by import their corresponding default behaviors, where the new modules
do
  not.
  For example, `import-parsers.js` does not entrain Babel.
The new `import-lite.js` does not entrain `node-modules.js` and composes
  with potential alternative package discovery, storage, and locks.
- Adds JSON module support to `makeBundle`.
- Aliases and deprecates `tags` in favor of `conditions` to align with
Node.js
  terminology.
- `mapNodeModules` now infers that it should include `devDependencies`
from
the entry package from the presence of `"development"` in `conditions`,
  if the `dev` option is abseent.

# @endo/import-bundle v1.2.0 (2024-07-30)

- The `inescapableGlobalProperties` option is changed from supporting
only
string-named enumerable own properties to supporting all own properties
  whether string-named or symbol-named, and whether enumerable or not.
  But, see

https://github.com/endojs/endo/blob/master/packages/import-bundle/src/compartment-wrapper.md
  for the longer term plan.

# @endo/lockdown v1.0.8 (2024-07-30)

- Changed `@endo/lockdown/commit-debug.js` so that it now sets
  the `lockdown` option `errorTaming: 'unsafe-debug'` instead of
  just `errorTaming: 'unsafe'`. This is a further loss of safety in
exchange for a better development experience. For testing and debugging
  purposes during development, this is usually the right tradeoff.

  In particular,
  `errorTaming: 'unsafe'` endangered only confidentiality, whereas
  `errorTaming: 'unsafe-debug'` also endangers integrity, essentially by
  directly exposing the (non-standard and dangerous) v8 `Error`
  constructor API.

In exchange, stack traces will more often have accurate line numbers
into
  the sources of transpiled code, such as TypeScript sources. See
[`errorTaming`
Options](https://github.com/endojs/endo/blob/master/packages/ses/docs/lockdown.md#errortaming-options)
for more on these tradeoffs.

# @endo/module-source v1.0.0 (2024-07-30)

- Renamed from `@endo/static-module-record` to `@endo/module-source`
exporting
  `ModuleSource` instead of `StaticModuleRecord`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant