Skip to content

Commit af7a75b

Browse files
committed
Fix ESM wrapper interop with libsodium factory exports
1 parent 7230467 commit af7a75b

5 files changed

Lines changed: 9578 additions & 11 deletions

File tree

dist/modules-esm/libsodium-wrappers.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/modules-sumo-esm/libsodium-sumo.mjs

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

dist/modules-sumo-esm/libsodium-wrappers.mjs

Lines changed: 9516 additions & 1 deletion
Large diffs are not rendered by default.

test/esm-interop.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { expect, test } from "bun:test";
2+
import { readFileSync } from "node:fs";
3+
4+
const generatedEsmWrappers = [
5+
"dist/modules-esm/libsodium-wrappers.mjs",
6+
"dist/modules-sumo-esm/libsodium-wrappers.mjs",
7+
];
8+
9+
for (const wrapperPath of generatedEsmWrappers) {
10+
test(`${wrapperPath} supports both ESM export shapes`, () => {
11+
const wrapper = readFileSync(wrapperPath, "utf8");
12+
13+
expect(wrapper).toContain('Unsupported libsodium ESM export shape');
14+
expect(wrapper).toContain('.default');
15+
expect(wrapper).toContain('.default.ready');
16+
expect(wrapper).toContain('.ready.then(function');
17+
expect(wrapper).toMatch(/return (n|moduleInstance)/);
18+
});
19+
}

wrapper/wrap-esm-template.js

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,55 @@
11
"use strict";
22

3-
import createLibsodium from "/*{{libsodium}}*/";
3+
import libsodiumModuleOrFactory from "/*{{libsodium}}*/";
44

55
const output_format = "uint8array";
66

77
let libsodium;
88
const exports = {};
99

10+
function _get_sodium_initializer(moduleOrFactory) {
11+
if (typeof moduleOrFactory === "function") {
12+
return moduleOrFactory;
13+
}
14+
if (moduleOrFactory != null && typeof moduleOrFactory.default === "function") {
15+
return moduleOrFactory.default;
16+
}
17+
return null;
18+
}
19+
20+
function _get_sodium_module(moduleOrFactory) {
21+
if (moduleOrFactory != null && typeof moduleOrFactory.ready !== "undefined") {
22+
return moduleOrFactory;
23+
}
24+
if (moduleOrFactory != null && moduleOrFactory.default != null && typeof moduleOrFactory.default.ready !== "undefined") {
25+
return moduleOrFactory.default;
26+
}
27+
return null;
28+
}
29+
1030
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function") {
1131
throw new Error("globalThis.crypto.getRandomValues is not available. The ESM build of libsodium requires a secure random source (available in all browsers and Node.js 19+).");
1232
}
1333

14-
const ready = createLibsodium({
15-
getRandomValue: function() {
16-
var buf = new Uint32Array(1);
17-
globalThis.crypto.getRandomValues(buf);
18-
return buf[0] >>> 0;
19-
}
20-
}).then(function (libsodiumModule) {
34+
const getRandomValue = function() {
35+
var buf = new Uint32Array(1);
36+
globalThis.crypto.getRandomValues(buf);
37+
return buf[0] >>> 0;
38+
};
39+
40+
const initializer = _get_sodium_initializer(libsodiumModuleOrFactory);
41+
const moduleInstance = _get_sodium_module(libsodiumModuleOrFactory);
42+
43+
const ready = (initializer != null
44+
? initializer({
45+
getRandomValue: getRandomValue
46+
})
47+
: moduleInstance != null
48+
? moduleInstance.ready.then(function () {
49+
return moduleInstance;
50+
})
51+
: Promise.reject(new Error("Unsupported libsodium ESM export shape"))
52+
).then(function (libsodiumModule) {
2153
libsodium = libsodiumModule;
2254
exports.libsodium = libsodium;
2355

0 commit comments

Comments
 (0)