From 5fe0f9233f0637a70d4ce1980a2ad9dda70ca7c7 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Mon, 29 Jan 2024 16:40:55 -0800 Subject: [PATCH] feat(compartment-mapper): expose loadCompartmentForArchive This extracts a function, `loadCompartmentForArchive()`, from `digestLocation()` in `archive.js`, and exposes it. This function returns archival-ready data structures, in addition to a record of the compartment renames which `makeArchiveCompartmentMap()` performs. The intent is to leverage the module resolution performed by the function, which is reflected in its output. A consumer can use the information therein to perform additional operations on the tree (e.g., parse ASTs). # Conflicts: # packages/compartment-mapper/src/types.js --- packages/compartment-mapper/index.js | 1 + packages/compartment-mapper/src/archive.js | 80 +++++++++++++++------- packages/compartment-mapper/src/types.js | 26 +++++++ packages/compartment-mapper/types.d.ts | 1 + 4 files changed, 83 insertions(+), 25 deletions(-) diff --git a/packages/compartment-mapper/index.js b/packages/compartment-mapper/index.js index acccf2c663..872a7b90be 100644 --- a/packages/compartment-mapper/index.js +++ b/packages/compartment-mapper/index.js @@ -6,6 +6,7 @@ export { writeArchive, mapLocation, hashLocation, + loadCompartmentForArchive, } from './src/archive.js'; export { parseArchive, diff --git a/packages/compartment-mapper/src/archive.js b/packages/compartment-mapper/src/archive.js index 17f10f75d1..56dd395509 100644 --- a/packages/compartment-mapper/src/archive.js +++ b/packages/compartment-mapper/src/archive.js @@ -250,7 +250,7 @@ const captureSourceLocations = async (sources, captureSourceLocation) => { /** * @param {CompartmentMapDescriptor} compartmentMap * @param {Sources} sources - * @returns {{archiveCompartmentMap: CompartmentMapDescriptor, archiveSources: Sources}} + * @returns {import('./types.js').MakeArchiveCompartmentMapResult} */ export const makeArchiveCompartmentMap = (compartmentMap, sources) => { const { @@ -282,29 +282,27 @@ export const makeArchiveCompartmentMap = (compartmentMap, sources) => { // accept all valid compartment maps. assertCompartmentMap(archiveCompartmentMap); - return { archiveCompartmentMap, archiveSources }; + return { archiveCompartmentMap, archiveSources, compartmentRenames }; }; /** - * @param {ReadFn | ReadPowers} powers - * @param {string} moduleLocation - * @param {ArchiveOptions} [options] - * @returns {Promise<{sources: Sources, compartmentMapBytes: Uint8Array, sha512?: string}>} + * @param {import('./types.js').LoadCompartmentForArchiveOptions & ArchiveOptions} options + * @returns {Promise} */ -const digestLocation = async (powers, moduleLocation, options) => { - const { - moduleTransforms, - modules: exitModules = {}, - dev = false, - tags = new Set(), - captureSourceLocation = undefined, - searchSuffixes = undefined, - commonDependencies = undefined, - importHook: exitModuleImportHook = undefined, - policy = undefined, - sourceMapHook = undefined, - } = options || {}; - const { read, computeSha512 } = unpackReadPowers(powers); +export const loadCompartmentForArchive = async ({ + readPowers, + moduleLocation, + moduleTransforms, + modules: exitModules = {}, + dev = false, + tags = new Set(), + searchSuffixes = undefined, + commonDependencies = undefined, + importHook: exitModuleImportHook = undefined, + policy = undefined, + sourceMapHook = undefined, +}) => { + const { read, computeSha512 } = unpackReadPowers(readPowers); const { packageLocation, packageDescriptorText, @@ -321,7 +319,7 @@ const digestLocation = async (powers, moduleLocation, options) => { packageDescriptorLocation, ); const compartmentMap = await compartmentMapForNodeModules( - powers, + readPowers, packageLocation, tags, packageDescriptor, @@ -362,6 +360,15 @@ const digestLocation = async (powers, moduleLocation, options) => { archiveOnly: true, }); await compartment.load(entryModuleSpecifier); + + /** @type {string|undefined} */ + let compartmentMapSha512; + if (computeSha512 !== undefined) { + const compartmentMapText = JSON.stringify(compartmentMap, null, 2); + const compartmentMapBytes = textEncoder.encode(compartmentMapText); + compartmentMapSha512 = computeSha512(compartmentMapBytes); + } + if (policy) { // retain all attenuators. await Promise.all( @@ -371,10 +378,33 @@ const digestLocation = async (powers, moduleLocation, options) => { ); } - const { archiveCompartmentMap, archiveSources } = makeArchiveCompartmentMap( - compartmentMap, - sources, - ); + const { archiveCompartmentMap, archiveSources, compartmentRenames } = + makeArchiveCompartmentMap(compartmentMap, sources); + + return { + archiveCompartmentMap, + archiveSources, + compartmentMapSha512, + compartmentRenames, + computeSha512, + }; +}; + +/** + * @param {ReadFn | ReadPowers} powers + * @param {string} moduleLocation + * @param {ArchiveOptions} [options] + * @returns {Promise<{sources: Sources, compartmentMapBytes: Uint8Array, sha512?: string}>} + */ +const digestLocation = async (powers, moduleLocation, options = {}) => { + const { captureSourceLocation = undefined } = options; + + const { archiveCompartmentMap, archiveSources, computeSha512 } = + await loadCompartmentForArchive({ + readPowers: powers, + moduleLocation, + ...options, + }); const archiveCompartmentMapText = JSON.stringify( archiveCompartmentMap, diff --git a/packages/compartment-mapper/src/types.js b/packages/compartment-mapper/src/types.js index 4dc3a1a26f..bc3bbfc681 100644 --- a/packages/compartment-mapper/src/types.js +++ b/packages/compartment-mapper/src/types.js @@ -525,3 +525,29 @@ export {}; * @typedef CryptoAPI * @property {typeof import('crypto').createHash} createHash */ + +/** + * @typedef LoadCompartmentForArchiveOptions + * @property {ReadFn | ReadPowers} readPowers + * @property {string} moduleLocation + */ + +/** + * Return value of `loadCompartmentForArchive`. + * + * @typedef LoadCompartmentForArchiveResult + * @property {CompartmentMapDescriptor} archiveCompartmentMap + * @property {Sources} archiveSources + * @property {Record} compartmentRenames + * @property {string} [compartmentMapSha512] + * @property {HashFn} [computeSha512] + */ + +/** + * Return value of `makeArchiveCompartmentMap` + * + * @typedef MakeArchiveCompartmentMapResult + * @property {CompartmentMapDescriptor} archiveCompartmentMap + * @property {Sources} archiveSources + * @property {Record} compartmentRenames + */ diff --git a/packages/compartment-mapper/types.d.ts b/packages/compartment-mapper/types.d.ts index e480609c63..41742f0dba 100644 --- a/packages/compartment-mapper/types.d.ts +++ b/packages/compartment-mapper/types.d.ts @@ -5,6 +5,7 @@ export { writeArchive, mapLocation, hashLocation, + loadCompartmentForArchive, } from './src/archive.js'; export { parseArchive,