import-in-the-middle
Advanced tools
Comparing version 1.7.1 to 1.7.2
94
hook.js
@@ -5,2 +5,3 @@ // Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License. | ||
const { randomBytes } = require('crypto') | ||
const specifiers = new Map() | ||
@@ -81,3 +82,73 @@ const isWin = process.platform === "win32" | ||
/** | ||
* Determines if a specifier represents an export all ESM line. | ||
* Note that the expected `line` isn't 100% valid ESM. It is derived | ||
* from the `getExports` function wherein we have recognized the true | ||
* line and re-mapped it to one we expect. | ||
* | ||
* @param {string} line | ||
* @returns {boolean} | ||
*/ | ||
function isStarExportLine(line) { | ||
return /^\* from /.test(line) | ||
} | ||
/** | ||
* @typedef {object} ProcessedModule | ||
* @property {string[]} imports A set of ESM import lines to be added to the | ||
* shimmed module source. | ||
* @property {string[]} namespaces A set of identifiers representing the | ||
* modules in `imports`, e.g. for `import * as foo from 'bar'`, "foo" will be | ||
* present in this array. | ||
* @property {string[]} setters The shimmed setters for all the exports | ||
* from the module and any transitive export all modules. | ||
*/ | ||
/** | ||
* Processes a module's exports and builds a set of new import statements, | ||
* namespace names, and setter blocks. If an export all export if encountered, | ||
* the target exports will be hoisted to the current module via a generated | ||
* namespace. | ||
* | ||
* @param {object} params | ||
* @param {string} params.srcUrl The full URL to the module to process. | ||
* @param {object} params.context Provided by the loaders API. | ||
* @param {function} parentGetSource Provides the source code for the parent | ||
* module. | ||
* @returns {Promise<ProcessedModule>} | ||
*/ | ||
async function processModule({ srcUrl, context, parentGetSource }) { | ||
const exportNames = await getExports(srcUrl, context, parentGetSource) | ||
const imports = [`import * as namespace from ${JSON.stringify(srcUrl)}`] | ||
const namespaces = ['namespace'] | ||
const setters = [] | ||
for (const n of exportNames) { | ||
if (isStarExportLine(n) === true) { | ||
const [_, modFile] = n.split('* from ') | ||
const modUrl = new URL(modFile, srcUrl).toString() | ||
const modName = Buffer.from(modFile, 'hex') + Date.now() + randomBytes(4).toString('hex') | ||
imports.push(`import * as $${modName} from ${JSON.stringify(modUrl)}`) | ||
namespaces.push(`$${modName}`) | ||
const data = await processModule({ srcUrl: modUrl, context, parentGetSource }) | ||
Array.prototype.push.apply(setters, data.setters) | ||
continue | ||
} | ||
setters.push(` | ||
let $${n} = _.${n} | ||
export { $${n} as ${n} } | ||
set.${n} = (v) => { | ||
$${n} = v | ||
return true | ||
} | ||
`) | ||
} | ||
return { imports, namespaces, setters } | ||
} | ||
function addIitm (url) { | ||
@@ -128,17 +199,18 @@ const urlObj = new URL(url) | ||
const realUrl = deleteIitm(url) | ||
const exportNames = await getExports(realUrl, context, parentGetSource) | ||
const { imports, namespaces, setters } = await processModule({ | ||
srcUrl: realUrl, | ||
context, | ||
parentGetSource | ||
}) | ||
return { | ||
source: ` | ||
import { register } from '${iitmURL}' | ||
import * as namespace from ${JSON.stringify(url)} | ||
${imports.join('\n')} | ||
const _ = Object.assign({}, ...[${namespaces.join(', ')}]) | ||
const set = {} | ||
${exportNames.map((n) => ` | ||
let $${n} = namespace.${n} | ||
export { $${n} as ${n} } | ||
set.${n} = (v) => { | ||
$${n} = v | ||
return true | ||
} | ||
`).join('\n')} | ||
register(${JSON.stringify(realUrl)}, namespace, set, ${JSON.stringify(specifiers.get(realUrl))}) | ||
${setters.join('\n')} | ||
register(${JSON.stringify(realUrl)}, _, set, ${JSON.stringify(specifiers.get(realUrl))}) | ||
` | ||
@@ -145,0 +217,0 @@ } |
@@ -37,3 +37,3 @@ 'use strict' | ||
} else { | ||
exportedNames.add('*') | ||
exportedNames.add(`* from ${node.source.value}`) | ||
} | ||
@@ -40,0 +40,0 @@ break |
{ | ||
"name": "import-in-the-middle", | ||
"version": "1.7.1", | ||
"version": "1.7.2", | ||
"description": "Intercept imports in Node.js", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "c8 --check-coverage --lines 85 imhotap --runner 'node test/runtest' --files test/{hook,low-level,other,get-esm-exports}/*", | ||
"test:ts": "c8 imhotap --runner 'node test/runtest' --files test/typescript/*.test.mts", | ||
"test": "c8 --reporter lcov --check-coverage --lines 70 imhotap --runner 'node test/runtest' --files test/{hook,low-level,other,get-esm-exports}/*", | ||
"test:ts": "c8 --reporter lcov imhotap --runner 'node test/runtest' --files test/typescript/*.test.mts", | ||
"coverage": "c8 --reporter html imhotap --runner 'node test/runtest' --files test/{hook,low-level,other,get-esm-exports}/* && echo '\nNow open coverage/index.html\n'" | ||
@@ -10,0 +10,0 @@ }, |
@@ -26,3 +26,3 @@ // Exporting declarations | ||
// Aggregating modules | ||
export * from "module-name"; //| * | ||
export * from "module-name"; //| * from module-name | ||
export * as name1 from "module-name"; //| name1 | ||
@@ -29,0 +29,0 @@ export { name1, /* …, */ nameN } from "module-name"; //| name1,nameN |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
45989
57
1063