diff --git a/packages/compartment-mapper/NEWS.md b/packages/compartment-mapper/NEWS.md index 968df14ef1..085ebe73ff 100644 --- a/packages/compartment-mapper/NEWS.md +++ b/packages/compartment-mapper/NEWS.md @@ -2,6 +2,19 @@ User-visible changes to `@endo/compartment-mapper`: # Next version +- Adds options `languageForExtension`, `moduleLanguageForExtension`, + `commonjsLanguageForExtension`, and `languages` to `mapNodeModules` and + `compartmentMapForNodeModules` allowing for certain mappings from extension + (e.g., `ts`) to language (e.g., `mts` or `cts`) to depend on the each + package’s `type` in the way we already vary `js` between `cjs` and `mjs`. + These options enter through the high level functions including `makeArchive` + and `importLocation`. +- The new options `workspaceLanguageForExtension`, + `workspaceModuleLanguageForExtension`, and + `workspaceCommonjsLanguageForExtension` apply like the above except more + specifically and for packages that are not physically located under a + `node_modules` directory, indicating that JavaScript has not yet been + generated from any non-JavaScript source files. - Omits unused module descriptors from `compartment-map.json` in archived applications, potentially reducing file sizes. - Fixes an issue where errors thrown from exit module hooks (`importHook`) would diff --git a/packages/compartment-mapper/README.md b/packages/compartment-mapper/README.md index 4013b692ec..6cfbdfb6b9 100644 --- a/packages/compartment-mapper/README.md +++ b/packages/compartment-mapper/README.md @@ -204,6 +204,8 @@ does not exist, to the `index.js` file in the directory with the same name. > `fetch` global, in conjunction with usable values for `import.meta.url` in > ECMAScript modules or `__dirname` and `__filename` in CommonJS modules. +## Language Extensions + Officially beginning with Node.js 14, Node.js treats `.mjs` files as ECMAScript modules and `.cjs` files as CommonJS modules. The `.js` extension indicates a CommonJS module by default, to maintain @@ -211,30 +213,6 @@ backward compatibility. However, packages that have a `type` property that explicitly says `module` will treat a `.js` file as an ECMAScript module. -This unforunately conflicts with packages written to work with the ECMAScript -module system emulator in the `esm` package on npm, which allows every file -with the `js` extension to be an ECMAScript module that presents itself to -Node.js as a CommonJS module. -To overcome such obstacles, the compartment mapper will accept a non-standard -`parsers` property in `package.json` that maps file extensions, specifically -`js` to the corresponding language name, one of `mjs` for ECMAScript modules, -`cjs` for CommonJS modules, and `json` for JSON modules. -All other language names are reserved and the defaults for files with the -extensions `cjs`, `mjs`, `json`, `text`, and `bytes` default to the language of -the same name unless overridden. -JSON modules export a default object resulting from the conventional JSON.parse -of the module's UTF-8 encoded bytes. -Text modules export a default string from the module's UTF-8 encoded bytes. -Bytes modules export a default ArrayBuffer capturing the module's bytes. -If compartment mapper sees `parsers`, it ignores `type`, so these can -contradict where using the `esm` emulator requires. - -```json -{ - "parsers": {"js": "mjs"} -} -``` - Many Node.js applications using CommonJS modules expect to be able to `require` a JSON file like `package.json`. The compartment mapper supports loading JSON modules from any type of module. @@ -252,9 +230,54 @@ As of Node.js 14, Node does not support loading ECMAScript modules from CommonJS modules, so using this feature may limit compatibility with the Node.js platform. -> TODO A future version may introduce language plugins, so a package may state -> that files with a particular extension are either parsed or linked with -> another module. +The compartment mapper supports language plugins. +The languages supported by default are: + +- `mjs` for ECMAScript modules, +- `cjs` for CommonJS modules, +- `json` for JSON modules, +- `text` for UTF-8 encoded text files, +- `bytes` for any file, exporting a `Uint8Array` as `default`, +- `pre-mjs-json` for pre-compiled ECMAScript modules captured as JSON in + archives, and +- `pre-cjs-json` for pre-compiled CommonJS modules captured as JSON in + archives. + +The compartment mapper accepts extensions to this set of languages with +the `parserForLanguage` option supported by many functions. +See `src/types/external.ts` for the type and expected behavior for +parsers. + +These language identifiers are keys for the `moduleTransforms` and +`syncModuleTransforms` options, which may map each language to a transform +function. +The language identifiers are also the values for a `languageForExtension`, +`moduleLanguageForExtension`, and `commonjsLanguageForExtension` options to +configure additional extension-to-language mappings for a module and its +transitive dependencies. + +For any package that has `type` set to `"module"` in its `package.json`, +`moduleLangaugeForExtension` will precede `languageForExtension`. +Packages with `type` set to `"commonjs"` or simply not set, +`commonjsLanguageForExtension` will precede `languageForExtension`. +This provides an hook for mapping TypeScript's `.ts` to either `.cts` or +`.mts`. + +The analogous `workspaceLanguageForExtension`, +`workspaceCommonjsLanguageForExtension`, and +`workspaceModuleLanguageForExtension` options apply more specifically for +packages that are not under a `node_modules` directory, indicating that they +are in the set of linked workspaces and have not been built or published to +npm. + +In the scope any given package, the `parsers` property in `package.json` may +override the extension-to-language mapping. + +```json +{ + "parsers": { "png": "bytes" } +} +``` > TODO > diff --git a/packages/compartment-mapper/src/archive-lite.js b/packages/compartment-mapper/src/archive-lite.js index 85f02d48c4..4822bc4170 100644 --- a/packages/compartment-mapper/src/archive-lite.js +++ b/packages/compartment-mapper/src/archive-lite.js @@ -322,15 +322,11 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => { policy = undefined, sourceMapHook = undefined, parserForLanguage: parserForLanguageOption = {}, - languageForExtension: languageForExtensionOption = {}, } = options; const parserForLanguage = freeze( assign(create(null), parserForLanguageOption), ); - const languageForExtension = freeze( - assign(create(null), languageForExtensionOption), - ); const { read, computeSha512 } = unpackReadPowers(powers); @@ -365,7 +361,6 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => { makeImportHook, moduleTransforms, parserForLanguage, - languageForExtension, archiveOnly: true, }); await compartment.load(entryModuleSpecifier); diff --git a/packages/compartment-mapper/src/archive.js b/packages/compartment-mapper/src/archive.js index fafb0615be..b9b4af7837 100644 --- a/packages/compartment-mapper/src/archive.js +++ b/packages/compartment-mapper/src/archive.js @@ -47,7 +47,8 @@ const assignParserForLanguage = (options = {}) => { const parserForLanguage = freeze( assign(create(null), defaultParserForLanguage, parserForLanguageOption), ); - return { ...rest, parserForLanguage }; + const languages = Object.keys(parserForLanguage); + return { ...rest, parserForLanguage, languages }; }; /** @@ -61,12 +62,16 @@ export const makeAndHashArchive = async ( moduleLocation, options = {}, ) => { - const compartmentMap = await mapNodeModules(powers, moduleLocation, options); - return makeAndHashArchiveFromMap( - powers, - compartmentMap, - assignParserForLanguage(options), - ); + const { parserForLanguage, languages, ...otherOptions } = + assignParserForLanguage(options); + const compartmentMap = await mapNodeModules(powers, moduleLocation, { + languages, + ...otherOptions, + }); + return makeAndHashArchiveFromMap(powers, compartmentMap, { + parserForLanguage, + ...otherOptions, + }); }; /** @@ -76,20 +81,41 @@ export const makeAndHashArchive = async ( * @returns {Promise} */ export const makeArchive = async (powers, moduleLocation, options = {}) => { - const { dev, tags, conditions = tags, commonDependencies, policy } = options; - + const { + dev, + tags, + conditions = tags, + commonDependencies, + policy, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + parserForLanguage, + languages, + ...otherOptions + } = assignParserForLanguage(options); const compartmentMap = await mapNodeModules(powers, moduleLocation, { dev, conditions, commonDependencies, policy, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + languages, }); - return makeArchiveFromMap( - powers, - compartmentMap, - assignParserForLanguage(options), - ); + return makeArchiveFromMap(powers, compartmentMap, { + parserForLanguage, + policy, + ...otherOptions, + }); }; /** @@ -99,16 +125,42 @@ export const makeArchive = async (powers, moduleLocation, options = {}) => { * @returns {Promise} */ export const mapLocation = async (powers, moduleLocation, options = {}) => { - const { dev, tags, conditions = tags, commonDependencies, policy } = options; + const { + dev, + tags, + conditions = tags, + commonDependencies, + policy, + parserForLanguage, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...otherOptions + } = assignParserForLanguage(options); const compartmentMap = await mapNodeModules(powers, moduleLocation, { dev, conditions, commonDependencies, policy, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, }); - return mapFromMap(powers, compartmentMap, assignParserForLanguage(options)); + return mapFromMap(powers, compartmentMap, { + parserForLanguage, + policy, + ...otherOptions, + }); }; /** @@ -118,16 +170,42 @@ export const mapLocation = async (powers, moduleLocation, options = {}) => { * @returns {Promise} */ export const hashLocation = async (powers, moduleLocation, options = {}) => { - const { dev, tags, conditions = tags, commonDependencies, policy } = options; + const { + dev, + tags, + conditions = tags, + commonDependencies, + policy, + parserForLanguage, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...otherOptions + } = assignParserForLanguage(options); const compartmentMap = await mapNodeModules(powers, moduleLocation, { dev, conditions, commonDependencies, policy, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, }); - return hashFromMap(powers, compartmentMap, assignParserForLanguage(options)); + return hashFromMap(powers, compartmentMap, { + parserForLanguage, + policy, + ...otherOptions, + }); }; /** @@ -144,18 +222,40 @@ export const writeArchive = async ( moduleLocation, options = {}, ) => { - const { dev, tags, conditions = tags, commonDependencies, policy } = options; + const { + dev, + tags, + conditions = tags, + commonDependencies, + policy, + parserForLanguage, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...otherOptions + } = assignParserForLanguage(options); const compartmentMap = await mapNodeModules(readPowers, moduleLocation, { dev, conditions, commonDependencies, policy, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + languages, }); return writeArchiveFromMap( write, readPowers, archiveLocation, compartmentMap, - assignParserForLanguage(options), + { policy, parserForLanguage, ...otherOptions }, ); }; diff --git a/packages/compartment-mapper/src/bundle.js b/packages/compartment-mapper/src/bundle.js index 29f5d60e78..fe63135f1b 100644 --- a/packages/compartment-mapper/src/bundle.js +++ b/packages/compartment-mapper/src/bundle.js @@ -235,6 +235,13 @@ export const makeBundle = async (readPowers, moduleLocation, options) => { sourceMapHook = undefined, parserForLanguage: parserForLanguageOption = {}, languageForExtension: languageForExtensionOption = {}, + commonjsLanguageForExtension: commonjsLanguageForExtensionOption = {}, + moduleLanguageForExtension: moduleLanguageForExtensionOption = {}, + workspaceLanguageForExtension: workspaceLanguageForExtensionOption = {}, + workspaceCommonjsLanguageForExtension: + workspaceCommonjsLanguageForExtensionOption = {}, + workspaceModuleLanguageForExtension: + workspaceModuleLanguageForExtensionOption = {}, } = options || {}; const conditions = new Set(conditionsOption); @@ -248,6 +255,27 @@ export const makeBundle = async (readPowers, moduleLocation, options) => { const languageForExtension = Object.freeze( Object.assign(Object.create(null), languageForExtensionOption), ); + const commonjsLanguageForExtension = Object.freeze( + Object.assign(Object.create(null), commonjsLanguageForExtensionOption), + ); + const moduleLanguageForExtension = Object.freeze( + Object.assign(Object.create(null), moduleLanguageForExtensionOption), + ); + const workspaceLanguageForExtension = Object.freeze( + Object.assign(Object.create(null), workspaceLanguageForExtensionOption), + ); + const workspaceCommonjsLanguageForExtension = Object.freeze( + Object.assign( + Object.create(null), + workspaceCommonjsLanguageForExtensionOption, + ), + ); + const workspaceModuleLanguageForExtension = Object.freeze( + Object.assign( + Object.create(null), + workspaceModuleLanguageForExtensionOption, + ), + ); const { packageLocation, @@ -266,7 +294,16 @@ export const makeBundle = async (readPowers, moduleLocation, options) => { conditions, packageDescriptor, moduleSpecifier, - { dev, commonDependencies }, + { + dev, + commonDependencies, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + }, ); const { @@ -291,7 +328,6 @@ export const makeBundle = async (readPowers, moduleLocation, options) => { makeImportHook, moduleTransforms, parserForLanguage, - languageForExtension, }); await compartment.load(entryModuleSpecifier); diff --git a/packages/compartment-mapper/src/capture-lite.js b/packages/compartment-mapper/src/capture-lite.js index 9513e9b973..20da5b58b0 100644 --- a/packages/compartment-mapper/src/capture-lite.js +++ b/packages/compartment-mapper/src/capture-lite.js @@ -263,22 +263,19 @@ const captureCompartmentMap = (compartmentMap, sources) => { export const captureFromMap = async (powers, compartmentMap, options = {}) => { const { moduleTransforms, + syncModuleTransforms, modules: exitModules = {}, searchSuffixes = undefined, importHook: exitModuleImportHook = undefined, policy = undefined, sourceMapHook = undefined, parserForLanguage: parserForLanguageOption = {}, - languageForExtension: languageForExtensionOption = {}, Compartment = defaultCompartment, } = options; const parserForLanguage = freeze( assign(create(null), parserForLanguageOption), ); - const languageForExtension = freeze( - assign(create(null), languageForExtensionOption), - ); const { read, computeSha512 } = unpackReadPowers(powers); @@ -312,8 +309,8 @@ export const captureFromMap = async (powers, compartmentMap, options = {}) => { resolve, makeImportHook, moduleTransforms, + syncModuleTransforms, parserForLanguage, - languageForExtension, archiveOnly: true, Compartment, }); diff --git a/packages/compartment-mapper/src/import-archive-lite.js b/packages/compartment-mapper/src/import-archive-lite.js index b05c6b79ac..5c50c41358 100644 --- a/packages/compartment-mapper/src/import-archive-lite.js +++ b/packages/compartment-mapper/src/import-archive-lite.js @@ -46,8 +46,6 @@ import { assertCompartmentMap } from './compartment-map.js'; import { exitModuleImportHookMaker } from './import-hook.js'; import { attenuateModuleHook, enforceModulePolicy } from './policy.js'; -const DefaultCompartment = Compartment; - const { Fail, quote: q } = assert; const textDecoder = new TextDecoder(); @@ -255,19 +253,15 @@ export const parseArchive = async ( expectedSha512 = undefined, computeSourceLocation = undefined, computeSourceMapLocation = undefined, - Compartment = DefaultCompartment, + Compartment: CompartmentParseOption = Compartment, modules = undefined, importHook: exitModuleImportHook = undefined, parserForLanguage: parserForLanguageOption = {}, - languageForExtension: languageForExtensionOption = {}, } = options; const parserForLanguage = freeze( assign(create(null), parserForLanguageOption), ); - const languageForExtension = freeze( - assign(create(null), languageForExtensionOption), - ); const archive = new ZipReader(archiveBytes, { name: archiveLocation }); @@ -343,13 +337,12 @@ export const parseArchive = async ( const { compartment, pendingJobsPromise } = link(compartmentMap, { makeImportHook, parserForLanguage, - languageForExtension, modules: Object.fromEntries( Object.keys(modules || {}).map(specifier => { return [specifier, { namespace: {} }]; }), ), - Compartment, + Compartment: CompartmentParseOption, }); await pendingJobsPromise; @@ -368,7 +361,7 @@ export const parseArchive = async ( modules, transforms, __shimTransforms__, - Compartment, + Compartment: CompartmentOption = CompartmentParseOption, importHook: exitModuleImportHook, } = options || {}; @@ -390,12 +383,11 @@ export const parseArchive = async ( const { compartment, pendingJobsPromise } = link(compartmentMap, { makeImportHook, parserForLanguage, - languageForExtension, globals, modules, transforms, __shimTransforms__, - Compartment, + Compartment: CompartmentOption, }); await pendingJobsPromise; @@ -425,7 +417,6 @@ export const loadArchive = async ( modules, computeSourceMapLocation, parserForLanguage, - languageForExtension, } = options; const archiveBytes = await read(archiveLocation); return parseArchive(archiveBytes, archiveLocation, { @@ -435,7 +426,6 @@ export const loadArchive = async ( modules, computeSourceMapLocation, parserForLanguage, - languageForExtension, }); }; diff --git a/packages/compartment-mapper/src/import-lite.js b/packages/compartment-mapper/src/import-lite.js index 39118c5d36..71d748f992 100644 --- a/packages/compartment-mapper/src/import-lite.js +++ b/packages/compartment-mapper/src/import-lite.js @@ -95,15 +95,12 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => { const { searchSuffixes = undefined, parserForLanguage: parserForLanguageOption = {}, - languageForExtension: languageForExtensionOption = {}, + Compartment: LoadCompartmentOption = Compartment, } = options; const parserForLanguage = freeze( assign(create(null), parserForLanguageOption), ); - const languageForExtension = freeze( - assign(create(null), languageForExtensionOption), - ); /** * Object containing options and read powers that fulfills all requirements @@ -154,7 +151,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => { modules, transforms, __shimTransforms__, - Compartment, + Compartment: CompartmentOption = LoadCompartmentOption, importHook: exitModuleImportHook, } = options; const compartmentExitModuleImportHook = exitModuleImportHookMaker({ @@ -199,12 +196,11 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => { makeImportHook, makeImportNowHook, parserForLanguage, - languageForExtension, globals, transforms, syncModuleTransforms, __shimTransforms__, - Compartment, + Compartment: CompartmentOption, })); } else { // sync module transforms are allowed, because they are "compatible" @@ -213,13 +209,12 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => { ({ compartment, pendingJobsPromise } = link(compartmentMap, { makeImportHook, parserForLanguage, - languageForExtension, globals, transforms, moduleTransforms, syncModuleTransforms, __shimTransforms__, - Compartment, + Compartment: CompartmentOption, })); } diff --git a/packages/compartment-mapper/src/import.js b/packages/compartment-mapper/src/import.js index 754d94987b..1c6c3cedef 100644 --- a/packages/compartment-mapper/src/import.js +++ b/packages/compartment-mapper/src/import.js @@ -42,7 +42,8 @@ const assignParserForLanguage = (options = {}) => { const parserForLanguage = freeze( assign(create(null), defaultParserForLanguage, parserForLanguageOption), ); - return { ...rest, parserForLanguage }; + const languages = Object.keys(parserForLanguage); + return { ...rest, parserForLanguage, languages }; }; /** @@ -72,7 +73,21 @@ export const loadLocation = async ( moduleLocation, options = {}, ) => { - const { dev, tags, commonDependencies, policy } = options; + const { + dev, + tags, + commonDependencies, + policy, + parserForLanguage, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...otherOptions + } = assignParserForLanguage(options); // conditions are not present in SyncArchiveOptions const conditions = 'conditions' in options ? options.conditions || tags : tags; @@ -81,12 +96,18 @@ export const loadLocation = async ( conditions, commonDependencies, policy, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + languages, + }); + return loadFromMap(readPowers, compartmentMap, { + parserForLanguage, + ...otherOptions, }); - return loadFromMap( - readPowers, - compartmentMap, - assignParserForLanguage(options), - ); }; /** diff --git a/packages/compartment-mapper/src/link.js b/packages/compartment-mapper/src/link.js index 42e4c842c5..b2b1414f5d 100644 --- a/packages/compartment-mapper/src/link.js +++ b/packages/compartment-mapper/src/link.js @@ -11,15 +11,14 @@ /** * @import {ModuleMapHook} from 'ses' * @import { - * AsyncParseFn, * CompartmentDescriptor, * CompartmentMapDescriptor, * ImportNowHookMaker, - * LanguageForExtension, * LinkOptions, * LinkResult, * ModuleDescriptor, * ParseFn, + * AsyncParseFn, * ParserForLanguage, * ParserImplementation, * ShouldDeferError, @@ -254,7 +253,6 @@ export const link = ( makeImportHook, makeImportNowHook = impossibleImportNowHookMaker, parserForLanguage: parserForLanguageOption = {}, - languageForExtension: languageForExtensionOption = {}, globals = {}, transforms = [], moduleTransforms, @@ -279,10 +277,6 @@ export const link = ( const pendingJobs = []; - /** @type {LanguageForExtension} */ - const defaultLanguageForExtension = freeze( - assign(create(null), languageForExtensionOption), - ); /** @type {ParserForLanguage} */ const parserForLanguage = freeze( assign(create(null), parserForLanguageOption), @@ -300,7 +294,7 @@ export const link = ( const { location, name, - parsers: languageForExtensionOverrides = {}, + parsers: languageForExtension = {}, types: languageForModuleSpecifier = {}, } = compartmentDescriptor; @@ -314,14 +308,6 @@ export const link = ( // The `moduleMapHook` writes back to the compartment map. compartmentDescriptor.modules = modules; - /** @type {LanguageForExtension} */ - const languageForExtension = freeze( - assign( - create(null), - defaultLanguageForExtension, - languageForExtensionOverrides, - ), - ); // TS is kind of dumb about this, so we can use a type assertion to avoid a // pointless ternary. const parse = /** @type {ParseFn|AsyncParseFn} */ ( diff --git a/packages/compartment-mapper/src/map-parser.js b/packages/compartment-mapper/src/map-parser.js index 74dc243c0e..49b2acfa66 100644 --- a/packages/compartment-mapper/src/map-parser.js +++ b/packages/compartment-mapper/src/map-parser.js @@ -101,6 +101,14 @@ const makeExtensionParser = ( ) { language = languageForModuleSpecifier[specifier]; } else { + // We should revisit this design decision: + // Defaulting the language to the extension conflates those namespaces. + // So, a transform keyed by extension can be used to coerce a language + // (e.g., .mts to mjs) as a shorthand for configuring a parser for that + // extension that pre-processes the file before handing off to the + // parser. + // But, this forces us to support the case of using weird language + // names like pre-mjs-json as valid, unconfigured extensions. language = languageForExtension[extension] || extension; } diff --git a/packages/compartment-mapper/src/node-modules.js b/packages/compartment-mapper/src/node-modules.js index 1a0803e07a..a3f41ace75 100644 --- a/packages/compartment-mapper/src/node-modules.js +++ b/packages/compartment-mapper/src/node-modules.js @@ -57,6 +57,15 @@ * modules. */ +/** + * @typedef {object} LanguageOptions + * @property {LanguageForExtension} commonjsLanguageForExtension + * @property {LanguageForExtension} moduleLanguageForExtension + * @property {LanguageForExtension} workspaceCommonjsLanguageForExtension + * @property {LanguageForExtension} workspaceModuleLanguageForExtension + * @property {Set} languages + */ + /** * @typedef {Record} CommonDependencyDescriptors */ @@ -189,83 +198,83 @@ const findPackage = async (readDescriptor, canonical, directory, name) => { } }; -const defaultLanguages = /** @type {const} */ ([ - 'mjs', - 'cjs', - 'json', - 'text', - 'bytes', -]); -const defaultUncontroversialParsers = /** @type {const} */ ({ - cjs: 'cjs', +const defaultLanguageForExtension = /** @type {const} */ ({ mjs: 'mjs', + cjs: 'cjs', json: 'json', text: 'text', bytes: 'bytes', }); -const defaultCommonParsers = /** @type {const} */ ({ +const defaultCommonjsLanguageForExtension = /** @type {const} */ ({ js: 'cjs', - ...defaultUncontroversialParsers, }); -const defaultModuleParsers = /** @type {const} */ ({ +const defaultModuleLanguageForExtension = /** @type {const} */ ({ js: 'mjs', - ...defaultUncontroversialParsers, }); /** * @param {object} descriptor * @param {string} location - * @param {object} [options] - * @param {readonly string[]|string[]} [options.languages] - * @param {Record} [options.uncontroversialParsers] - * @param {Record} [options.commonParsers] - * @param {Record} [options.moduleParsers] + * @param {LanguageOptions} languageOptions * @returns {Record} */ -const inferParsers = ( - descriptor, - location, - { - languages = defaultLanguages, - uncontroversialParsers = defaultUncontroversialParsers, - commonParsers = defaultCommonParsers, - moduleParsers = defaultModuleParsers, - } = {}, -) => { - const { type, module, parsers } = descriptor; - let additionalParsers = Object.create(null); - if (parsers !== undefined) { - if (typeof parsers !== 'object') { - throw Error( - `Cannot interpret parser map ${JSON.stringify( - parsers, - )} of package at ${location}, must be an object mapping file extensions to corresponding languages (mjs for ECMAScript modules, cjs for CommonJS modules, or json for JSON modules`, - ); - } - const invalidLanguages = values(parsers).filter( - language => !languages.includes(language), +const inferParsers = (descriptor, location, languageOptions) => { + let { moduleLanguageForExtension, commonjsLanguageForExtension } = + languageOptions; + const { + languages, + workspaceModuleLanguageForExtension, + workspaceCommonjsLanguageForExtension, + } = languageOptions; + + // Select languageForExtension options based on whether they are physically + // under node_modules, indicating that they have not been built for npm, + // so any languages that compile to JavaScript may need additional parsers. + if (!location.includes('/node_modules/')) { + moduleLanguageForExtension = workspaceModuleLanguageForExtension; + commonjsLanguageForExtension = workspaceCommonjsLanguageForExtension; + } + + const { + type, + module, + parsers: packageLanguageForExtension = {}, + } = descriptor; + + // Validate package-local "parsers" + if ( + typeof packageLanguageForExtension !== 'object' || + packageLanguageForExtension === null + ) { + throw Error( + `Cannot interpret parser map ${JSON.stringify( + packageLanguageForExtension, + )} of package at ${location}, must be an object mapping file extensions to corresponding languages (for example, mjs for ECMAScript modules, cjs for CommonJS modules, or json for JSON modules`, + ); + } + const invalidLanguages = values(packageLanguageForExtension).filter( + language => !languages.has(language), + ); + if (invalidLanguages.length > 0) { + throw Error( + `Cannot interpret parser map language values ${JSON.stringify( + invalidLanguages, + )} of package at ${location}, must be an object mapping file extensions to corresponding languages (for example, mjs for ECMAScript modules, cjs for CommonJS modules, or json for JSON modules`, ); - if (invalidLanguages.length > 0) { - throw Error( - `Cannot interpret parser map language values ${JSON.stringify( - invalidLanguages, - )} of package at ${location}, must be an object mapping file extensions to corresponding languages (mjs for ECMAScript modules, cjs for CommonJS modules, or json for JSON modules`, - ); - } - additionalParsers = { ...uncontroversialParsers, ...parsers }; } + if (type === 'module' || module !== undefined) { - return { ...moduleParsers, ...additionalParsers }; + return { ...moduleLanguageForExtension, ...packageLanguageForExtension }; } if (type === 'commonjs') { - return { ...commonParsers, ...additionalParsers }; + return { ...commonjsLanguageForExtension, ...packageLanguageForExtension }; } if (type !== undefined) { throw Error( `Cannot infer parser map for package of type ${type} at ${location}`, ); } - return { ...commonParsers, ...additionalParsers }; + return { ...commonjsLanguageForExtension, ...packageLanguageForExtension }; }; /** @@ -286,6 +295,7 @@ const inferParsers = ( * @param {Set} conditions * @param {boolean | undefined} dev * @param {CommonDependencyDescriptors} commonDependencyDescriptors + * @param {LanguageOptions} languageOptions * @param {Map>} preferredPackageLogicalPathMap * @param {Array} logicalPath * @returns {Promise} @@ -299,6 +309,7 @@ const graphPackage = async ( conditions, dev, commonDependencyDescriptors, + languageOptions, preferredPackageLogicalPathMap = new Map(), logicalPath = [], ) => { @@ -368,6 +379,7 @@ const graphPackage = async ( name, conditions, preferredPackageLogicalPathMap, + languageOptions, childLogicalPath, optional, commonDependencyDescriptors, @@ -399,6 +411,12 @@ const graphPackage = async ( types, ); + const parsers = inferParsers( + packageDescriptor, + packageLocation, + languageOptions, + ); + Object.assign(result, { name, path: logicalPath, @@ -408,7 +426,7 @@ const graphPackage = async ( internalAliases, dependencyLocations, types, - parsers: inferParsers(packageDescriptor, packageLocation), + parsers, }); await Promise.all( @@ -462,6 +480,7 @@ const graphPackage = async ( * @param {string} name - name of the package of interest. * @param {Set} conditions * @param {Map>} preferredPackageLogicalPathMap + * @param {LanguageOptions} languageOptions * @param {Array} [childLogicalPath] * @param {boolean} [optional] - whether the dependency is optional * @param {object} [commonDependencyDescriptors] - dependencies to be added to all packages @@ -475,6 +494,7 @@ const gatherDependency = async ( name, conditions, preferredPackageLogicalPathMap, + languageOptions, childLogicalPath = [], optional = false, commonDependencyDescriptors = undefined, @@ -511,6 +531,7 @@ const gatherDependency = async ( conditions, false, commonDependencyDescriptors, + languageOptions, preferredPackageLogicalPathMap, childLogicalPath, ); @@ -533,7 +554,8 @@ const gatherDependency = async ( * package.json, which was already read when searching for the package.json. * @param {boolean|undefined} dev - whether to use devDependencies from this package (and * only this package). - * @param {Record} [commonDependencies] - dependencies to be added to all packages + * @param {Record} commonDependencies - dependencies to be added to all packages + * @param {LanguageOptions} languageOptions */ const graphPackages = async ( maybeRead, @@ -542,7 +564,8 @@ const graphPackages = async ( conditions, mainPackageDescriptor, dev, - commonDependencies = {}, + commonDependencies, + languageOptions, ) => { const memo = create(null); /** @@ -599,6 +622,7 @@ const graphPackages = async ( conditions, dev, commonDependencyDescriptors, + languageOptions, ); return graph; }; @@ -754,6 +778,74 @@ const translateGraph = ( }; }; +/** + * @param {Pick} options + */ +const makeLanguageOptions = ({ + languageForExtension: additionalLanguageForExtension = {}, + moduleLanguageForExtension: additionalModuleLanguageForExtension = {}, + commonjsLanguageForExtension: additionalCommonjsLanguageForExtension = {}, + workspaceLanguageForExtension: additionalWorkspaceLanguageForExtension = {}, + workspaceModuleLanguageForExtension: + additionalWorkspaceModuleLanguageForExtension = {}, + workspaceCommonjsLanguageForExtension: + additionalWorkspaceCommonjsLanguageForExtension = {}, + languages: additionalLanguages = [], +}) => { + const commonjsLanguageForExtension = { + ...defaultLanguageForExtension, + ...additionalLanguageForExtension, + ...defaultCommonjsLanguageForExtension, + ...additionalCommonjsLanguageForExtension, + }; + const moduleLanguageForExtension = { + ...defaultLanguageForExtension, + ...additionalLanguageForExtension, + ...defaultModuleLanguageForExtension, + ...additionalModuleLanguageForExtension, + }; + const workspaceCommonjsLanguageForExtension = { + ...defaultLanguageForExtension, + ...additionalLanguageForExtension, + ...defaultCommonjsLanguageForExtension, + ...additionalCommonjsLanguageForExtension, + ...additionalWorkspaceLanguageForExtension, + ...additionalWorkspaceCommonjsLanguageForExtension, + }; + const workspaceModuleLanguageForExtension = { + ...defaultLanguageForExtension, + ...additionalLanguageForExtension, + ...defaultModuleLanguageForExtension, + ...additionalModuleLanguageForExtension, + ...additionalWorkspaceLanguageForExtension, + ...additionalWorkspaceModuleLanguageForExtension, + }; + + const languages = new Set([ + ...Object.values(moduleLanguageForExtension), + ...Object.values(commonjsLanguageForExtension), + ...Object.values(workspaceModuleLanguageForExtension), + ...Object.values(workspaceCommonjsLanguageForExtension), + ...additionalLanguages, + ]); + + return { + languages, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + }; +}; + /** * @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers * @param {string} packageLocation @@ -771,8 +863,10 @@ export const compartmentMapForNodeModules = async ( moduleSpecifier, options = {}, ) => { - const { dev = undefined, commonDependencies, policy } = options; + const { dev = undefined, commonDependencies = {}, policy } = options; const { maybeRead, canonical } = unpackReadPowers(readPowers); + const languageOptions = makeLanguageOptions(options); + const graph = await graphPackages( maybeRead, canonical, @@ -781,6 +875,7 @@ export const compartmentMapForNodeModules = async ( packageDescriptor, dev, commonDependencies, + languageOptions, ); if (policy) { @@ -821,13 +916,7 @@ export const mapNodeModules = async ( moduleLocation, options = {}, ) => { - const { - tags = new Set(), - conditions = tags, - dev = undefined, - commonDependencies, - policy, - } = options; + const { tags = new Set(), conditions = tags, ...otherOptions } = options; const { packageLocation, @@ -847,6 +936,6 @@ export const mapNodeModules = async ( conditions, packageDescriptor, moduleSpecifier, - { dev, commonDependencies, policy }, + otherOptions, ); }; diff --git a/packages/compartment-mapper/src/parse-json.js b/packages/compartment-mapper/src/parse-json.js index 54fe440c9f..6d9119facc 100644 --- a/packages/compartment-mapper/src/parse-json.js +++ b/packages/compartment-mapper/src/parse-json.js @@ -20,6 +20,7 @@ const textDecoder = new TextDecoder(); /** @type {ParseFn} */ export const parseJson = (bytes, _specifier, location, _packageLocation) => { const source = textDecoder.decode(bytes); + /** @type {Array} */ const imports = freeze([]); /** diff --git a/packages/compartment-mapper/src/types/external.ts b/packages/compartment-mapper/src/types/external.ts index c1282763bc..d0de4e9916 100644 --- a/packages/compartment-mapper/src/types/external.ts +++ b/packages/compartment-mapper/src/types/external.ts @@ -42,7 +42,6 @@ export type ParseArchiveOptions = Partial<{ ModulesOption & CompartmentOption & ParserForLanguageOption & - LanguageForExtensionOption & ExitModuleImportHookOption; export type LoadArchiveOptions = ParseArchiveOptions; @@ -72,6 +71,22 @@ type MapNodeModulesOptionsOmitPolicy = Partial<{ commonDependencies: Record; /** Maps extensions to languages for all packages, like `txt` to `text` */ languageForExtension: LanguageForExtension; + /** Maps additional extensions to languages for all type=module packages */ + moduleLanguageForExtension: LanguageForExtension; + /** Maps additional extensions to languages for all type=commonjs packages (default) */ + commonjsLanguageForExtension: LanguageForExtension; + /** Maps extensions to languages for packages not under node_modules */ + workspaceLanguageForExtension: LanguageForExtension; + /** + * Maps additional extensions to languages for all type=module packages that + * are not under node_modules + */ + workspaceModuleLanguageForExtension: LanguageForExtension; + /** + * Maps additional extensions to languages for all type=commonjs packages + * (default) + */ + workspaceCommonjsLanguageForExtension: LanguageForExtension; /** * Accounts for languages not present as values in any of the extension to * language mappings. @@ -200,7 +215,6 @@ type SyncImportingOptions = ModulesOption & type LinkingOptions = ParserForLanguageOption & CompartmentOption & - LanguageForExtensionOption & SyncModuleTransformsOption & ModuleTransformsOption; diff --git a/packages/compartment-mapper/src/types/internal.ts b/packages/compartment-mapper/src/types/internal.ts index 2fd8c37afe..8cce0cd5f4 100644 --- a/packages/compartment-mapper/src/types/internal.ts +++ b/packages/compartment-mapper/src/types/internal.ts @@ -26,7 +26,6 @@ import type { CompartmentSources, ExecuteOptions, ExitModuleImportNowHook, - LanguageForExtensionOption, ModuleTransforms, ParseFn, ParserForLanguage, @@ -45,8 +44,7 @@ export type LinkOptions = { moduleTransforms?: ModuleTransforms; syncModuleTransforms?: SyncModuleTransforms; archiveOnly?: boolean; -} & ExecuteOptions & - LanguageForExtensionOption; +} & ExecuteOptions; export type LinkResult = { compartment: Compartment; diff --git a/packages/compartment-mapper/test/_parse-jsonp.js b/packages/compartment-mapper/test/_parse-jsonp.js new file mode 100644 index 0000000000..5bb7448742 --- /dev/null +++ b/packages/compartment-mapper/test/_parse-jsonp.js @@ -0,0 +1,45 @@ +/** @module Provides joke language support for importing JSONP modules. */ + +/** + * @import {ParseFn, ParserImplementation} from '../src/types.js' + */ + +const textDecoder = new TextDecoder(); + +/** @type {ParseFn} */ +export const parseJsonp = (bytes, _specifier, _location, _packageLocation) => { + // Presumes that all JSONP module bytes are retrieved with ?callback=exports. + const source = textDecoder.decode(bytes); + const imports = harden([]); + + /** + * @param {object} exports + */ + const execute = exports => { + const compartment = new Compartment({ + __options__: true, + globals: harden({ + exports(value) { + exports.default = value; + }, + }), + }); + compartment.evaluate(source); + }; + return { + parser: 'jsonp', + bytes, + record: harden({ + imports, + exports: ['default'], + execute, + }), + }; +}; + +/** @type {ParserImplementation} */ +export default { + parse: parseJsonp, + heuristicImports: false, + synchronous: true, +}; diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/package.json new file mode 100644 index 0000000000..cec862f1c0 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "type": "commonjs", + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/package.json new file mode 100644 index 0000000000..68d335f7bd --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "type": "module", + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/package.json new file mode 100644 index 0000000000..8004f6bd58 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/node_modules/parsers-app/package.json @@ -0,0 +1,9 @@ +{ + "name": "app", + "parsers": { + "xsonp": "jsonp" + }, + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/package.json new file mode 100644 index 0000000000..cec862f1c0 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/commonjs-app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "type": "commonjs", + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/package.json new file mode 100644 index 0000000000..68d335f7bd --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/module-app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "type": "module", + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/module.xsonp b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/module.xsonp new file mode 100644 index 0000000000..f1dad2cdf6 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/module.xsonp @@ -0,0 +1 @@ +exports({ meaning: 42 }); diff --git a/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/package.json b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/package.json new file mode 100644 index 0000000000..8004f6bd58 --- /dev/null +++ b/packages/compartment-mapper/test/fixtures-language-for-extension/packages/parsers-app/package.json @@ -0,0 +1,9 @@ +{ + "name": "app", + "parsers": { + "xsonp": "jsonp" + }, + "scripts": { + "preinstall": "echo DO NOT INSTALL TEST FIXTURES; exit -1" + } +} diff --git a/packages/compartment-mapper/test/language-for-extension.test.js b/packages/compartment-mapper/test/language-for-extension.test.js new file mode 100644 index 0000000000..6e6d3ae4c6 --- /dev/null +++ b/packages/compartment-mapper/test/language-for-extension.test.js @@ -0,0 +1,260 @@ +import 'ses'; +import test from 'ava'; +import { scaffold, sanitizePaths } from './scaffold.js'; +import jsonp from './_parse-jsonp.js'; + +// The JSONP parser uses harden, as a bit. +lockdown({ + errorTaming: 'unsafe', + errorTrapping: 'none', +}); + +const meaningfulModule = { + default: { + meaning: 42, + }, + __proto__: { + __proto__: null, + [Symbol.toStringTag]: 'Module', + }, +}; + +const assertions = (t, { namespace }) => { + t.deepEqual(namespace, meaningfulModule); +}; + +const assertionCount = 1; + +scaffold( + 'languageForExtension', + test, + new URL( + 'fixtures-language-for-extension/node_modules/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + languageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'moduleLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/node_modules/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + moduleLanguageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'moduleLanguageForExtension should not be available in commonjs package', + test, + new URL( + 'fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + moduleLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'commonjsLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + commonjsLanguageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'commonjsLanguageForExtension should not be available in module package', + test, + new URL( + 'fixtures-language-for-extension/node_modules/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + commonjsLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'package.json parsers override languageForExtension', + test, + new URL( + 'fixtures-language-for-extension/node_modules/parsers-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + languageForExtension: { xsonp: 'text' }, + }, +); + +scaffold( + 'workspaceLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/packages/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + workspaceLanguageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'workspaceModuleLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/packages/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + workspaceModuleLanguageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'workspaceModuleLanguageForExtension should not be available in commonjs package', + test, + new URL( + 'fixtures-language-for-extension/package/commonjs-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + workspaceModuleLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'workspaceModuleLanguageForExtension should not be available under node_modules', + test, + new URL( + 'fixtures-language-for-extension/node_modules/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + workspaceModuleLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'workspaceCommonjsLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/packages/commonjs-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + workspaceCommonjsLanguageForExtension: { xsonp: 'jsonp' }, + }, +); + +scaffold( + 'workspaceCommonjsLanguageForExtension should not be available in module package', + test, + new URL( + 'fixtures-language-for-extension/packages/module-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + workspaceCommonjsLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'workspaceCommonjsLanguageForExtension should not be available under node_modules', + test, + new URL( + 'fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp', + import.meta.url, + ).href, + assertions, + 1, // expected number of assertions + { + parserForLanguage: { jsonp }, + workspaceCommonjsLanguageForExtension: { xsonp: 'jsonp' }, + shouldFailBeforeArchiveOperations: true, + onError(t, { error }) { + t.snapshot(sanitizePaths(error.message)); + }, + }, +); + +scaffold( + 'package.json parsers override workspaceLanguageForExtension', + test, + new URL( + 'fixtures-language-for-extension/packages/parsers-app/module.xsonp', + import.meta.url, + ).href, + assertions, + assertionCount, + { + parserForLanguage: { jsonp }, + workspaceLanguageForExtension: { xsonp: 'text' }, + }, +); diff --git a/packages/compartment-mapper/test/missing-entry.test.js b/packages/compartment-mapper/test/missing-entry.test.js index f53cff9bdd..4c2f70becc 100644 --- a/packages/compartment-mapper/test/missing-entry.test.js +++ b/packages/compartment-mapper/test/missing-entry.test.js @@ -1,6 +1,5 @@ import 'ses'; import test from 'ava'; -import path from 'path'; import fs from 'fs'; import url from 'url'; import crypto from 'crypto'; @@ -11,9 +10,10 @@ import { makeReadPowers } from '../node-powers.js'; const readPowers = makeReadPowers({ fs, url, crypto }); test('missing entry', async t => { - const entry = url.pathToFileURL( - path.resolve('i-solemnly-swear-i-do-not-exist.js'), - ); + const entry = new URL( + 'fixtures-missing/i-solemnly-swear-i-do-not-exist.js', + import.meta.url, + ).href; await t.throwsAsync( makeAndHashArchive(readPowers, entry, {}).then(() => {}), { diff --git a/packages/compartment-mapper/test/scaffold.js b/packages/compartment-mapper/test/scaffold.js index 467d965ff1..00ee4ea127 100644 --- a/packages/compartment-mapper/test/scaffold.js +++ b/packages/compartment-mapper/test/scaffold.js @@ -13,6 +13,13 @@ import { importArchive, hashLocation, } from '../index.js'; + +import { mapNodeModules } from '../src/node-modules.js'; +import { loadFromMap, importFromMap } from '../src/import-lite.js'; +import { makeArchiveFromMap } from '../src/archive-lite.js'; +import { defaultParserForLanguage } from '../src/import-parsers.js'; +import { defaultParserForLanguage as defaultArchiveParserForLanguage } from '../src/archive-parsers.js'; + import { makeReadPowers } from '../src/node-powers.js'; export const readPowers = makeReadPowers({ @@ -90,6 +97,13 @@ export function scaffold( conditions = tags, searchSuffixes = undefined, commonDependencies = undefined, + parserForLanguage = undefined, + languageForExtension = undefined, + commonjsLanguageForExtension = undefined, + moduleLanguageForExtension = undefined, + workspaceLanguageForExtension = undefined, + workspaceCommonjsLanguageForExtension = undefined, + workspaceModuleLanguageForExtension = undefined, additionalOptions = {}, } = {}, ) { @@ -133,6 +147,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); const { namespace } = await application.import({ @@ -144,6 +165,99 @@ export function scaffold( return namespace; }); + wrap(test, 'Location')( + `${name} / mapNodeModules / importFromMap`, + async (t, Compartment) => { + t.plan(fixtureAssertionCount); + await setup(); + + const languages = Object.keys({ + ...defaultParserForLanguage, + ...parserForLanguage, + }); + + const map = await mapNodeModules(readPowers, fixture, { + languages, + policy, + modules, + Compartment, + conditions: new Set(['development', ...(conditions || [])]), + commonDependencies, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...additionalOptions, + }); + + const { namespace } = await importFromMap(readPowers, map, { + globals: { ...globals, ...addGlobals }, + policy, + modules, + Compartment, + searchSuffixes, + parserForLanguage: { + ...defaultParserForLanguage, + ...parserForLanguage, + }, + ...additionalOptions, + }); + + return namespace; + }, + ); + + wrap(test, 'Location')( + `${name} / mapNodeModules / loadFromMap / import`, + async (t, Compartment) => { + t.plan(fixtureAssertionCount); + await setup(); + + const languages = Object.keys({ + ...defaultParserForLanguage, + ...parserForLanguage, + }); + + const map = await mapNodeModules(readPowers, fixture, { + languages, + policy, + modules, + Compartment, + conditions: new Set(['development', ...(conditions || [])]), + commonDependencies, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...additionalOptions, + }); + + const app = await loadFromMap(readPowers, map, { + policy, + Compartment, + searchSuffixes, + parserForLanguage: { + ...defaultParserForLanguage, + ...parserForLanguage, + }, + ...additionalOptions, + }); + + const { namespace } = await app.import({ + globals: { ...globals, ...addGlobals }, + modules, + Compartment, + ...additionalOptions, + }); + + return namespace; + }, + ); + wrap(test, 'Location')(`${name} / importLocation`, async (t, Compartment) => { t.plan(fixtureAssertionCount); await setup(); @@ -156,6 +270,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); return namespace; @@ -173,6 +294,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); const application = await parseArchive(archive, '', { @@ -185,6 +313,8 @@ export function scaffold( }), ), Compartment, + parserForLanguage, + ...additionalOptions, }); const { namespace } = await application.import({ globals: { ...globals, ...addGlobals }, @@ -209,6 +339,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); const prefixArchive = new Uint8Array(archive.length + 10); @@ -217,6 +354,8 @@ export function scaffold( const application = await parseArchive(prefixArchive, '', { modules, Compartment, + parserForLanguage, + ...additionalOptions, }); const { namespace } = await application.import({ globals: { ...globals, ...addGlobals }, @@ -253,11 +392,20 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); const application = await loadArchive(fakeRead, 'app.agar', { modules, Compartment, + parserForLanguage, + ...additionalOptions, }); const { namespace } = await application.import({ globals: { ...globals, ...addGlobals }, @@ -306,6 +454,13 @@ export function scaffold( searchSuffixes, commonDependencies, sourceMapHook, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); @@ -314,6 +469,7 @@ export function scaffold( modules, Compartment, computeSourceMapLocation, + parserForLanguage, ...additionalOptions, }); @@ -330,6 +486,64 @@ export function scaffold( }, ); + wrap(test, 'Archive')( + `${name} / mapNodeModules / makeArchiveFromMap / importArchive`, + async (t, Compartment) => { + t.plan(fixtureAssertionCount); + await setup(); + + const languages = Object.keys({ + ...defaultArchiveParserForLanguage, + ...parserForLanguage, + }); + + const map = await mapNodeModules(readPowers, fixture, { + policy, + conditions: new Set(['development', ...(conditions || [])]), + commonDependencies, + languages, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, + ...additionalOptions, + }); + + const archive = await makeArchiveFromMap(readPowers, map, { + modules, + policy, + searchSuffixes, + parserForLanguage: { + ...defaultArchiveParserForLanguage, + ...parserForLanguage, + }, + ...additionalOptions, + }); + const application = await parseArchive(archive, '', { + modules: Object.fromEntries( + Object.keys(modules).map((specifier, index) => { + // Replacing the namespace with an arbitrary index ensures that the + // parse phase does not depend on the type or values of the exit module + // set. + return [specifier, index]; + }), + ), + Compartment, + parserForLanguage, + ...additionalOptions, + }); + const { namespace } = await application.import({ + globals: { ...globals, ...addGlobals }, + modules, + Compartment, + ...additionalOptions, + }); + return namespace; + }, + ); + if (!onError) { test(`${name} / makeArchive / parseArchive / hashArchive consistency`, async (t, Compartment) => { t.plan(1); @@ -341,6 +555,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); @@ -349,6 +570,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); @@ -361,6 +589,7 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), computeSha512, expectedSha512, + parserForLanguage, ...additionalOptions, }, ); @@ -378,6 +607,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); @@ -386,6 +622,13 @@ export function scaffold( conditions: new Set(['development', ...(conditions || [])]), searchSuffixes, commonDependencies, + parserForLanguage, + languageForExtension, + commonjsLanguageForExtension, + moduleLanguageForExtension, + workspaceLanguageForExtension, + workspaceCommonjsLanguageForExtension, + workspaceModuleLanguageForExtension, ...additionalOptions, }); @@ -403,6 +646,7 @@ export function scaffold( parseArchive(corruptArchive, 'app.agar', { computeSha512, expectedSha512, + parserForLanguage, ...additionalOptions, }), { diff --git a/packages/compartment-mapper/test/snapshots/error-handling.test.js.md b/packages/compartment-mapper/test/snapshots/error-handling.test.js.md index be0ed22671..efd4c6c1e4 100644 --- a/packages/compartment-mapper/test/snapshots/error-handling.test.js.md +++ b/packages/compartment-mapper/test/snapshots/error-handling.test.js.md @@ -6,6 +6,26 @@ Generated by [AVA](https://avajs.dev). ## fixtures-error-handling / esm / loadLocation +> Snapshot 1 + + `TypeError: Failed to load module "./main.js" in package "file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/" (1 underlying failures: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/␊ + at throwAggregateError (file://.../ses/src/module-load.js:…)␊ + at load (file://.../ses/src/module-load.js:…)␊ + at async file://.../compartment-mapper/test/scaffold.js:…␊ + at async file://.../compartment-mapper/test/scaffold.js:…` + +## fixtures-error-handling / esm / mapNodeModules / importFromMap + +> Snapshot 1 + + `TypeError: Failed to load module "./main.js" in package "file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/" (1 underlying failures: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/␊ + at throwAggregateError (file://.../ses/src/module-load.js:…)␊ + at load (file://.../ses/src/module-load.js:…)␊ + at async file://.../compartment-mapper/test/scaffold.js:…␊ + at async file://.../compartment-mapper/test/scaffold.js:…` + +## fixtures-error-handling / esm / mapNodeModules / loadFromMap / import + > Snapshot 1 `TypeError: Failed to load module "./main.js" in package "file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/" (1 underlying failures: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/␊ @@ -78,8 +98,45 @@ Generated by [AVA](https://avajs.dev). at async file://.../compartment-mapper/test/scaffold.js:…␊ at async file://.../compartment-mapper/test/scaffold.js:…` +## fixtures-error-handling / esm / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + `TypeError: Failed to load module "./main.js" in package "file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/" (1 underlying failures: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/esm/␊ + at throwAggregateError (file://.../ses/src/module-load.js:…)␊ + at load (file://.../ses/src/module-load.js:…)␊ + at async digestFromMap (file://.../compartment-mapper/src/archive-lite.js:…)␊ + at async makeAndHashArchiveFromMap (file://.../compartment-mapper/src/archive-lite.js:…)␊ + at async makeArchiveFromMap (file://.../compartment-mapper/src/archive-lite.js:…)␊ + at async file://.../compartment-mapper/test/scaffold.js:…␊ + at async file://.../compartment-mapper/test/scaffold.js:…` + ## fixtures-error-handling / cjs / loadLocation +> Snapshot 1 + + `Error: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/cjs/␊ + at importHook (file://.../compartment-mapper/src/import-hook.js:…)␊ + at async asyncTrampoline (file://.../ses/src/module-load.js:…)␊ + at async drainQueue (file://.../ses/src/module-load.js:…)␊ + at async load (file://.../ses/src/module-load.js:…)␊ + at async file://.../compartment-mapper/test/scaffold.js:…␊ + at async file://.../compartment-mapper/test/scaffold.js:…` + +## fixtures-error-handling / cjs / mapNodeModules / importFromMap + +> Snapshot 1 + + `Error: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/cjs/␊ + at importHook (file://.../compartment-mapper/src/import-hook.js:…)␊ + at async asyncTrampoline (file://.../ses/src/module-load.js:…)␊ + at async drainQueue (file://.../ses/src/module-load.js:…)␊ + at async load (file://.../ses/src/module-load.js:…)␊ + at async file://.../compartment-mapper/test/scaffold.js:…␊ + at async file://.../compartment-mapper/test/scaffold.js:…` + +## fixtures-error-handling / cjs / mapNodeModules / loadFromMap / import + > Snapshot 1 `Error: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/cjs/␊ @@ -165,3 +222,19 @@ Generated by [AVA](https://avajs.dev). at execute (file://.../ses/src/module-instance.js:…)␊ at compartmentImportNow (file://.../ses/src/compartment.js:…)␊ at file://.../ses/src/compartment.js:…` + +## fixtures-error-handling / cjs / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + `Error: Cannot find external module "missing" in package file://.../compartment-mapper/test/fixtures-error-handling/node_modules/cjs/␊ + at Object.execute (file://.../compartment-mapper/src/import-archive-lite.js:…)␊ + at execute (file://.../ses/src/module-instance.js:…)␊ + at compartmentImportNow (file://.../ses/src/compartment.js:…)␊ + at Compartment.importNow (file://.../ses/src/compartment.js:…)␊ + at require (file://.../compartment-mapper/src/parse-cjs-shared-export-wrapper.js:…)␊ + at Proxy.eval (eval at (eval at makeEvaluate (file://.../ses/src/make-evaluate.js:…)), :…)␊ + at Object.execute (file://.../compartment-mapper/src/parse-pre-cjs.js:…)␊ + at execute (file://.../ses/src/module-instance.js:…)␊ + at compartmentImportNow (file://.../ses/src/compartment.js:…)␊ + at file://.../ses/src/compartment.js:…` diff --git a/packages/compartment-mapper/test/snapshots/error-handling.test.js.snap b/packages/compartment-mapper/test/snapshots/error-handling.test.js.snap index d5b62f7381..dd06112fd3 100644 Binary files a/packages/compartment-mapper/test/snapshots/error-handling.test.js.snap and b/packages/compartment-mapper/test/snapshots/error-handling.test.js.snap differ diff --git a/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.md b/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.md new file mode 100644 index 0000000000..684f541900 --- /dev/null +++ b/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.md @@ -0,0 +1,329 @@ +# Snapshot report for `test/language-for-extension.test.js` + +The actual snapshot is saved in `language-for-extension.test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## moduleLanguageForExtension should not be available in commonjs package / loadLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / importLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## moduleLanguageForExtension should not be available in commonjs package / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / loadLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / importLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## commonjsLanguageForExtension should not be available in module package / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / loadLocation + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / importLocation + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available in commonjs package / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" in package "file://.../compartment-mapper/" (1 underlying failures: Cannot find file for internal module "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp" (with candidates "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp.node", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.js", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.json", "./test/fixtures-language-for-extension/package/commonjs-app/module.xsonp/index.node") in package file://.../compartment-mapper/' + +## workspaceModuleLanguageForExtension should not be available under node_modules / loadLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / importLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceModuleLanguageForExtension should not be available under node_modules / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / loadLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / importLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available in module package / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../module-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../module-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / loadLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / mapNodeModules / loadFromMap / import + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / importLocation + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / makeArchive / parseArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / makeArchive / parseArchive with a prefix + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / writeArchive / loadArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / writeArchive / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' + +## workspaceCommonjsLanguageForExtension should not be available under node_modules / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Failed to load module "./module.xsonp" in package "file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/" (1 underlying failures: Cannot parse module ./module.xsonp at file://.../compartment-mapper/test/fixtures-language-for-extension/node_modules/commonjs-app/module.xsonp, no parser configured for the language xsonp' diff --git a/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.snap b/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.snap new file mode 100644 index 0000000000..35fa4cc350 Binary files /dev/null and b/packages/compartment-mapper/test/snapshots/language-for-extension.test.js.snap differ diff --git a/packages/compartment-mapper/test/snapshots/policy.test.js.md b/packages/compartment-mapper/test/snapshots/policy.test.js.md index a74af4324b..54570ac6ad 100644 --- a/packages/compartment-mapper/test/snapshots/policy.test.js.md +++ b/packages/compartment-mapper/test/snapshots/policy.test.js.md @@ -6,6 +6,18 @@ Generated by [AVA](https://avajs.dev). ## policy - attack - browser alias - with alias hint / loadLocation +> Snapshot 1 + + 'Failed to load module "./attack.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (1 underlying failures: Importing "dan" in "eve-v1.0.0" was not allowed by packages policy {"dan":true} (info: Blocked in linking. "dan" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/hackity/".)' + +## policy - attack - browser alias - with alias hint / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./attack.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (1 underlying failures: Importing "dan" in "eve-v1.0.0" was not allowed by packages policy {"dan":true} (info: Blocked in linking. "dan" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/hackity/".)' + +## policy - attack - browser alias - with alias hint / mapNodeModules / loadFromMap / import + > Snapshot 1 'Failed to load module "./attack.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (1 underlying failures: Importing "dan" in "eve-v1.0.0" was not allowed by packages policy {"dan":true} (info: Blocked in linking. "dan" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/hackity/".)' @@ -36,12 +48,30 @@ Generated by [AVA](https://avajs.dev). ## policy - attack - browser alias - with alias hint / writeArchive / importArchive +> Snapshot 1 + + 'Failed to load module "./attack.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (1 underlying failures: Importing "dan" in "eve-v1.0.0" was not allowed by packages policy {"dan":true} (info: Blocked in linking. "dan" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/hackity/".)' + +## policy - attack - browser alias - with alias hint / mapNodeModules / makeArchiveFromMap / importArchive + > Snapshot 1 'Failed to load module "./attack.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (1 underlying failures: Importing "dan" in "eve-v1.0.0" was not allowed by packages policy {"dan":true} (info: Blocked in linking. "dan" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/hackity/".)' ## policy - disallowed package with error hint / loadLocation +> Snapshot 1 + + 'Failed to load module "./index.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (2 underlying failures: Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".), Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".)' + +## policy - disallowed package with error hint / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Failed to load module "./index.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (2 underlying failures: Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".), Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".)' + +## policy - disallowed package with error hint / mapNodeModules / loadFromMap / import + > Snapshot 1 'Failed to load module "./index.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (2 underlying failures: Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".), Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".)' @@ -72,12 +102,30 @@ Generated by [AVA](https://avajs.dev). ## policy - disallowed package with error hint / writeArchive / importArchive +> Snapshot 1 + + 'Failed to load module "./index.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (2 underlying failures: Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".), Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".)' + +## policy - disallowed package with error hint / mapNodeModules / makeArchiveFromMap / importArchive + > Snapshot 1 'Failed to load module "./index.js" in package "file://.../compartment-mapper/test/fixtures-policy/node_modules/app/" (2 underlying failures: Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".), Importing "carol" in "alice-v1.0.0" was not allowed by packages policy {"alice>carol":false} (info: Blocked in linking. "carol" is part of the compartment map and resolves to "file://.../compartment-mapper/test/fixtures-policy/node_modules/alice/node_modules/carol/".)' ## policy - attenuator error aggregation / loadLocation +> Snapshot 1 + + 'Globals attenuation errors: Error while attenuating globals for "alice" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "carol" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "app" with "myattenuator": "I attenuate, I throw."' + +## policy - attenuator error aggregation / mapNodeModules / importFromMap + +> Snapshot 1 + + 'Globals attenuation errors: Error while attenuating globals for "alice" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "carol" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "app" with "myattenuator": "I attenuate, I throw."' + +## policy - attenuator error aggregation / mapNodeModules / loadFromMap / import + > Snapshot 1 'Globals attenuation errors: Error while attenuating globals for "alice" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "carol" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "app" with "myattenuator": "I attenuate, I throw."' @@ -111,3 +159,9 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 'Globals attenuation errors: Error while attenuating globals for "alice" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "app" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "carol" with "myattenuator": "I attenuate, I throw."' + +## policy - attenuator error aggregation / mapNodeModules / makeArchiveFromMap / importArchive + +> Snapshot 1 + + 'Globals attenuation errors: Error while attenuating globals for "alice" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "app" with "myattenuator": "I attenuate, I throw.", Error while attenuating globals for "carol" with "myattenuator": "I attenuate, I throw."' diff --git a/packages/compartment-mapper/test/snapshots/policy.test.js.snap b/packages/compartment-mapper/test/snapshots/policy.test.js.snap index a541d7c800..40cd9b14ea 100644 Binary files a/packages/compartment-mapper/test/snapshots/policy.test.js.snap and b/packages/compartment-mapper/test/snapshots/policy.test.js.snap differ