feat(compartment-mapper): allow transforms to process unknown languages
MODIFY
packages/compartment-mapper/src/link.js
packages/compartment-mapper/src/link.js
@@ -95,12 +95,7 @@ const makeExtensionParser = (
) {
language = languageForModuleSpecifier[specifier];
} else {
- if (!has(languageForExtension, extension)) {
- throw new Error(
- `Cannot parse module ${specifier} at ${location}, no parser configured for extension ${extension}`,
- );
- }
- language = languageForExtension[extension];
+ language = languageForExtension[extension] || extension;
}
if (has(moduleTransforms, language)) {

ADD
packages/compartment-mapper/test/fixtures-0/node_modules/language-unknown/README.md
+This package covers the behavior of a package that has modules in a language unknown to compartment-mapper and must be handled via a transform.

ADD
packages/compartment-mapper/test/fixtures-0/node_modules/language-unknown/main.xyz
+!! this module is in an unknown language that must be converted by a ModuleTransform
+
+provide lambda(a, b): a add b
\ No newline at end of file

ADD
packages/compartment-mapper/test/fixtures-0/node_modules/language-unknown/package.json
+{
+ "name": "language-unknown",
+ "exports": "./main.xyz",
+ "scripts": {
+ "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1"
+ }
+}

MODIFY
packages/compartment-mapper/test/test-transform.js
packages/compartment-mapper/test/test-transform.js
@@ -155,3 +155,35 @@ test('module transforms can be used to translate JSON to JS', async t => {
const { default: value } = namespace;
t.is(value, 42, 'JSON module transformed');
});
+
+test('module transforms can be used for extensions where the language is not known', async t => {
+ t.plan(2);
+
+ const fixture = new URL(
+ 'fixtures-0/node_modules/language-unknown/main.xyz',
+ import.meta.url,
+ ).toString();
+
+ const archive = await makeArchive(read, fixture, {
+ moduleTransforms: {
+ xyz: async sourceBytes => {
+ t.is(1, 1); // plan + 1
+ const source = new TextDecoder().decode(sourceBytes);
+ const output = source
+ .replace('!! ', '// ')
+ .replace('provide ', 'export default ')
+ .replace('lambda(', '(')
+ .replace('): ', ') => ')
+ .replace(' add ', ' + ');
+ console.log('done:\n', output);
+ const objectBytes = new TextEncoder().encode(output);
+ return { bytes: objectBytes, parser: 'mjs' };
+ },
+ },
+ });
+ const application = await parseArchive(archive, fixture);
+ const { namespace } = await application.import();
+ const { default: addFn } = namespace;
+ const value = addFn(40, 2);
+ t.is(value, 42, 'unknown language module transformed');
+});

feat(compartment-mapper): allow transforms to process unknown languages