diff --git a/packages/endo/src/archive.js b/packages/endo/src/archive.js index 99df29e9d4..bcceb75785 100644 --- a/packages/endo/src/archive.js +++ b/packages/endo/src/archive.js @@ -6,6 +6,7 @@ import { parseExtension } from "./extension.js"; import { compartmentMapForNodeModules } from "./compartmap.js"; import { search } from "./search.js"; import { assemble } from "./assemble.js"; +import * as json from "./json.js"; const { entries, freeze, fromEntries, values } = Object; @@ -165,10 +166,14 @@ export const makeArchive = async (read, moduleLocation) => { const { packageLocation, packageDescriptorText, + packageDescriptorLocation, moduleSpecifier } = await search(read, moduleLocation); - const packageDescriptor = JSON.parse(packageDescriptorText); + const packageDescriptor = json.parse( + packageDescriptorText, + packageDescriptorLocation + ); const compartmentMap = await compartmentMapForNodeModules( read, packageLocation, diff --git a/packages/endo/src/compartmap.js b/packages/endo/src/compartmap.js index e8b36e18fc..8231ecb213 100644 --- a/packages/endo/src/compartmap.js +++ b/packages/endo/src/compartmap.js @@ -1,6 +1,7 @@ /* eslint no-shadow: 0 */ import { inferExports } from "./infer-exports.js"; +import * as json from "./json.js"; const { create, entries, keys, values } = Object; @@ -9,7 +10,7 @@ const decoder = new TextDecoder(); // q, as in quote, for enquoting strings in error messages. const q = JSON.stringify; -const resolve = (rel, abs) => new URL(rel, abs).toString(); +const resolveLocation = (rel, abs) => new URL(rel, abs).toString(); const basename = location => { const { pathname } = new URL(location); @@ -21,13 +22,15 @@ const basename = location => { }; const readDescriptor = async (read, packageLocation) => { - const descriptorPath = resolve("package.json", packageLocation); - const descriptorBytes = await read(descriptorPath).catch(_error => undefined); + const descriptorLocation = resolveLocation("package.json", packageLocation); + const descriptorBytes = await read(descriptorLocation).catch( + _error => undefined + ); if (descriptorBytes === undefined) { return undefined; } const descriptorText = decoder.decode(descriptorBytes); - const descriptor = JSON.parse(descriptorText); + const descriptor = json.parse(descriptorText, descriptorLocation); return descriptor; }; @@ -49,14 +52,14 @@ const readDescriptorWithMemo = async (memo, read, packageLocation) => { // find it efficiently. const findPackage = async (readDescriptor, directory, name) => { for (;;) { - const packageLocation = resolve(`node_modules/${name}/`, directory); + const packageLocation = resolveLocation(`node_modules/${name}/`, directory); // eslint-disable-next-line no-await-in-loop const packageDescriptor = await readDescriptor(packageLocation); if (packageDescriptor !== undefined) { return { packageLocation, packageDescriptor }; } - const parent = resolve("../", directory); + const parent = resolveLocation("../", directory); if (parent === directory) { return undefined; } @@ -64,7 +67,7 @@ const findPackage = async (readDescriptor, directory, name) => { const base = basename(directory); if (base === "node_modules") { - directory = resolve("../", directory); + directory = resolveLocation("../", directory); if (parent === directory) { return undefined; } diff --git a/packages/endo/src/import-archive.js b/packages/endo/src/import-archive.js index 819670ca20..d14ca2d41e 100644 --- a/packages/endo/src/import-archive.js +++ b/packages/endo/src/import-archive.js @@ -3,6 +3,7 @@ import { readZip } from "./zip.js"; import { assemble } from "./assemble.js"; import { parserForLanguage } from "./parse.js"; +import * as json from "./json.js"; const decoder = new TextDecoder(); @@ -35,7 +36,7 @@ export const parseArchive = async (archiveBytes, archiveLocation) => { const compartmentMapBytes = await archive.read("compartmap.json"); const compartmentMapText = decoder.decode(compartmentMapBytes); - const compartmentMap = JSON.parse(compartmentMapText); + const compartmentMap = json.parse(compartmentMapText, "compartmap.json"); const execute = (endowments, modules) => { const { compartments, entry: moduleSpecifier } = compartmentMap; diff --git a/packages/endo/src/import.js b/packages/endo/src/import.js index 98df4105f1..5cdf03a245 100644 --- a/packages/endo/src/import.js +++ b/packages/endo/src/import.js @@ -4,6 +4,7 @@ import { compartmentMapForNodeModules } from "./compartmap.js"; import { search } from "./search.js"; import { assemble } from "./assemble.js"; import { parseExtension } from "./extension.js"; +import * as json from "./json.js"; const decoder = new TextDecoder(); @@ -72,10 +73,14 @@ export const loadLocation = async (read, moduleLocation) => { const { packageLocation, packageDescriptorText, + packageDescriptorLocation, moduleSpecifier } = await search(read, moduleLocation); - const packageDescriptor = JSON.parse(packageDescriptorText); + const packageDescriptor = json.parse( + packageDescriptorText, + packageDescriptorLocation + ); const compartmentMap = await compartmentMapForNodeModules( read, packageLocation, diff --git a/packages/endo/src/json.js b/packages/endo/src/json.js new file mode 100644 index 0000000000..c14f22cf5c --- /dev/null +++ b/packages/endo/src/json.js @@ -0,0 +1,7 @@ +export const parse = (source, location) => { + try { + return JSON.parse(source); + } catch (error) { + throw new SyntaxError(`Cannot parse JSON from ${location}, ${error}`); + } +}; diff --git a/packages/endo/src/parse.js b/packages/endo/src/parse.js index 9cd7c3a992..c54cf3b6bc 100644 --- a/packages/endo/src/parse.js +++ b/packages/endo/src/parse.js @@ -2,6 +2,7 @@ import { parseRequires } from "./parse-requires.js"; import { parseExtension } from "./extension.js"; +import * as json from "./json.js"; const { entries, freeze, fromEntries } = Object; @@ -73,13 +74,7 @@ export const parseCjs = (source, _specifier, location, packageLocation) => { export const parseJson = (source, _specifier, location, _packageLocation) => { const imports = freeze([]); const execute = exports => { - try { - exports.default = JSON.parse(source); - } catch (error) { - throw new SyntaxError( - `Cannot parse JSON module at ${location}, ${error}` - ); - } + exports.default = json.parse(source, location); }; return { parser: "json", diff --git a/packages/endo/src/search.js b/packages/endo/src/search.js index fbc9f5b52b..7ec881b07c 100644 --- a/packages/endo/src/search.js +++ b/packages/endo/src/search.js @@ -29,6 +29,7 @@ export const search = async (read, moduleLocation) => { return { packageLocation: directory, packageDescriptorText, + packageDescriptorLocation, moduleSpecifier: relativize(relative(directory, moduleLocation)) }; }