From 2a2bf1c34ef918ea8f60d311f1834cf539666a62 Mon Sep 17 00:00:00 2001 From: naugtur Date: Wed, 30 Mar 2022 11:15:46 +0200 Subject: [PATCH] fix(compartment-mapper): add support for alternatives in exports definitions --- .../compartment-mapper/src/infer-exports.js | 9 ++++++++ .../src/parse-cjs-shared-export-wrapper.js | 2 +- .../node_modules/app/index.js | 10 +++++++++ .../node_modules/app/package.json | 4 +++- .../node_modules/nested-export/README.md | 1 + .../node_modules/nested-export/callBound.js | 1 + .../node_modules/nested-export/index.js | 1 + .../node_modules/nested-export/package.json | 22 +++++++++++++++++++ .../node_modules/nested-file/README.md | 1 + .../node_modules/nested-file/main.js | 1 + .../node_modules/nested-file/nested.js | 1 + .../node_modules/nested-file/package.json | 4 ++++ .../test/test-cjs-compat.js | 1 + 13 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/README.md create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/callBound.js create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/index.js create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/package.json create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/README.md create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/main.js create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/nested.js create mode 100644 packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/package.json diff --git a/packages/compartment-mapper/src/infer-exports.js b/packages/compartment-mapper/src/infer-exports.js index 2bc104a901..ffd26a7447 100644 --- a/packages/compartment-mapper/src/infer-exports.js +++ b/packages/compartment-mapper/src/infer-exports.js @@ -5,6 +5,7 @@ import { join, relativize } from './node-module-specifier.js'; const { entries, fromEntries } = Object; +const { isArray } = Array; /** * @param {string} name - the name of the referrer package. @@ -34,6 +35,14 @@ function* interpretBrowserExports(name, exports) { * @yields {[string, string]} */ function* interpretExports(name, exports, tags) { + if (isArray(exports)) { + yield* interpretExports( + name, + // Find one that produces non-empty result, discard result and use again + exports.find(ex => !interpretExports(name, ex, tags).next().done), + tags, + ); + } if (typeof exports === 'string') { yield [name, relativize(exports)]; return; diff --git a/packages/compartment-mapper/src/parse-cjs-shared-export-wrapper.js b/packages/compartment-mapper/src/parse-cjs-shared-export-wrapper.js index f8b5f5dcc4..f018d61460 100644 --- a/packages/compartment-mapper/src/parse-cjs-shared-export-wrapper.js +++ b/packages/compartment-mapper/src/parse-cjs-shared-export-wrapper.js @@ -95,7 +95,7 @@ export const wrap = (moduleEnvironmentRecord, compartment, resolvedImports) => { // the lexer. if (exportsHaveBeenOverwritten) { moduleEnvironmentRecord.default = finalExports; - keys(moduleEnvironmentRecord.default).forEach(prop => { + keys(moduleEnvironmentRecord.default || {}).forEach(prop => { if (prop !== 'default') moduleEnvironmentRecord[prop] = moduleEnvironmentRecord.default[prop]; }); diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/index.js b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/index.js index 0e374c46ca..8c02cf9d5c 100644 --- a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/index.js +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/index.js @@ -7,6 +7,8 @@ const defineprop = require('defineprop'); const parserStruggles = require('parser-struggles'); const afterExec = require('after-exec'); require('default-difficulties'); +const nestedFile = require('nested-file/nested'); +const nestedExport = require('nested-export/callBound'); // Generated by running v16.13.2: node assertion-generators/expected.cjs // I chose this behavior because: @@ -28,6 +30,14 @@ function assertInteropNameCollisions({ moduleReference, expect, name }) { } module.exports.assertions = { + packageNestedFile() { + if(!nestedFile.isOk){ + throw Error('Expected nested-file/nested to have been resolved based on path') + } + if(!nestedExport.isOk){ + throw Error('Expected nested-export/callBound to have been resolved based on exports defined in package.json') + } + }, defaultChangesAfterExec() { if (!afterExec.isOk) { throw Error('Expected a.js to be the same thing when required twice'); diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/package.json b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/package.json index d111d59c8c..6099662907 100644 --- a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/package.json +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/app/package.json @@ -8,6 +8,8 @@ "interops": "^1.0.0", "parser-struggles": "^1.0.0", "default-difficulties": "^1.0.0", - "after-exec": "^1.0.0" + "after-exec": "^1.0.0", + "nested-file": "^1.0.0", + "nested-export": "^1.0.0" } } diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/README.md b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/README.md new file mode 100644 index 0000000000..bf160cbc2f --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/README.md @@ -0,0 +1 @@ +This package reproduces the issue with nested exports failing to load from the `call-bind` npm package \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/callBound.js b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/callBound.js new file mode 100644 index 0000000000..1dd2311fe5 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/callBound.js @@ -0,0 +1 @@ +exports.isOk = 2; \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/index.js b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/index.js new file mode 100644 index 0000000000..009118fb8c --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/index.js @@ -0,0 +1 @@ +exports.isOk = 1; \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/package.json b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/package.json new file mode 100644 index 0000000000..3f759a287c --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-export/package.json @@ -0,0 +1,22 @@ +{ + "name": "nested-export", + "main": "index.js", + "exports": { + ".": [ + { + "default": "./index.js" + }, + "./index.js" + ], + "./callBound": [ + { + "deno": "./this-gets-skipped" + }, + { + "default": "./callBound.js" + }, + "./this-is-never-reached" + ], + "./package.json": "./package.json" + } +} \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/README.md b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/README.md new file mode 100644 index 0000000000..57436e8aa4 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/README.md @@ -0,0 +1 @@ +This is a package that has a nested file which can be used directly. \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/main.js b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/main.js new file mode 100644 index 0000000000..009118fb8c --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/main.js @@ -0,0 +1 @@ +exports.isOk = 1; \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/nested.js b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/nested.js new file mode 100644 index 0000000000..4198dd8caf --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/nested.js @@ -0,0 +1 @@ +exports.isOk = 1 \ No newline at end of file diff --git a/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/package.json b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/package.json new file mode 100644 index 0000000000..46029f1129 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-cjs-compat/node_modules/nested-file/package.json @@ -0,0 +1,4 @@ +{ + "name": "nested-file", + "main": "./main.js" +} diff --git a/packages/compartment-mapper/test/test-cjs-compat.js b/packages/compartment-mapper/test/test-cjs-compat.js index b05962a691..4be2712824 100644 --- a/packages/compartment-mapper/test/test-cjs-compat.js +++ b/packages/compartment-mapper/test/test-cjs-compat.js @@ -18,6 +18,7 @@ const assertFixture = (t, { namespace }) => { assertions.parserStruggles(); assertions.moduleWithCycle(); assertions.defaultChangesAfterExec(); + assertions.packageNestedFile(); t.pass(); };