Skip to content

Commit 691b217

Browse files
committed
fix(compartment-mapper): infer module type from the import key in package.json exports
1 parent 47864ca commit 691b217

File tree

12 files changed

+61
-1069
lines changed

12 files changed

+61
-1069
lines changed

packages/compartment-mapper/src/infer-exports.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ function* interpretBrowserField(name, browser, main = 'index.js') {
6363
* @param {object} exports - the `exports` field from a package.json.
6464
* @param {Set<string>} conditions - build conditions about the target environment
6565
* for selecting relevant exports, e.g., "browser" or "node".
66+
* @param {LanguageForExtension} types - an object to populate
67+
* with any recognized module's type, if implied by a tag.
6668
* @yields {[string, string]}
6769
* @returns {Generator<[string, string]>}
6870
*/
69-
function* interpretExports(name, exports, conditions) {
71+
function* interpretExports(name, exports, conditions, types) {
7072
if (isArray(exports)) {
7173
for (const section of exports) {
72-
const results = [...interpretExports(name, section, conditions)];
74+
const results = [...interpretExports(name, section, conditions, types)];
7375
if (results.length > 0) {
7476
yield* results;
7577
break;
@@ -93,12 +95,20 @@ function* interpretExports(name, exports, conditions) {
9395
continue; // or no-op
9496
} else if (key.startsWith('./') || key === '.') {
9597
if (name === '.') {
96-
yield* interpretExports(key, value, conditions);
98+
yield* interpretExports(key, value, conditions, types);
9799
} else {
98-
yield* interpretExports(join(name, key), value, conditions);
100+
yield* interpretExports(join(name, key), value, conditions, types);
99101
}
100102
} else if (conditions.has(key)) {
101-
yield* interpretExports(name, value, conditions);
103+
if (types && key === 'import' && typeof value === 'string') {
104+
// In this one case, the key "import" has carried a hint that the
105+
// referenced module is an ECMASCript module, and that hint may be
106+
// necessary to override whatever type might be inferred from the module
107+
// specifier extension.
108+
const spec = relativize(value);
109+
types[spec] = 'mjs';
110+
}
111+
yield* interpretExports(name, value, conditions, types);
102112
// Take only the first matching tag.
103113
break;
104114
}
@@ -141,7 +151,7 @@ export const inferExportsEntries = function* inferExportsEntries(
141151
yield ['.', relativize(main)];
142152
}
143153
if (exports !== undefined) {
144-
yield* interpretExports('.', exports, conditions);
154+
yield* interpretExports('.', exports, conditions, types);
145155
}
146156
// TODO Otherwise, glob 'files' for all '.js', '.cjs', and '.mjs' entry
147157
// modules, taking care to exclude node_modules.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
// eslint-disable-next-line no-undef
12
const { sha256 } = require('@noble/hashes/sha2');
23

34
// Example data to hash
45
const textData = new TextEncoder().encode('Hello, world!');
56

67
// SHA256 hashing
78
const hash256 = sha256(textData);
8-
console.log('SHA256:', hash256);
9+
console.log('SHA256 Hash:', hash256);

0 commit comments

Comments
 (0)