Skip to content

Commit

Permalink
fix: Support Hooking multiple times (#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
timfish authored Sep 26, 2024
1 parent b74cd07 commit e0d8080
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ ignorePatterns:
- test/fixtures/circular-a.js
- test/fixtures/circular-b.js
- test/fixtures/reexport.js
- test/fixtures/duplicate-explicit.mjs
- test/fixtures/duplicate.mjs
- test/fixtures/export-types/default-call-expression-renamed.mjs
4 changes: 3 additions & 1 deletion hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
$${n} = v
return true
}
get.${n} = () => $${n}
`)
}
}
Expand Down Expand Up @@ -402,10 +403,11 @@ const _ = Object.assign(
namespace
)
const set = {}
const get = {}
${Array.from(setters.values()).join('\n')}
register(${JSON.stringify(realUrl)}, _, set, ${JSON.stringify(specifiers.get(realUrl))})
register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(specifiers.get(realUrl))})
`
}
} catch (cause) {
Expand Down
11 changes: 10 additions & 1 deletion lib/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const importHooks = [] // TODO should this be a Set?
const setters = new WeakMap()
const getters = new WeakMap()
const specifiers = new Map()
const toHook = []

Expand All @@ -12,6 +13,13 @@ const proxyHandler = {
return setters.get(target)[name](value)
},

get (target, name) {
if (name === Symbol.toStringTag) {
return 'Module'
}
return getters.get(target)[name]()
},

defineProperty (target, property, descriptor) {
if ((!('value' in descriptor))) {
throw new Error('Getters/setters are not supported for exports property descriptors.')
Expand All @@ -21,9 +29,10 @@ const proxyHandler = {
}
}

function register (name, namespace, set, specifier) {
function register (name, namespace, set, get, specifier) {
specifiers.set(name, specifier)
setters.set(namespace, set)
getters.set(namespace, get)
const proxy = new Proxy(namespace, proxyHandler)
importHooks.forEach(hook => hook(name, proxy))
toHook.push([name, proxy])
Expand Down
24 changes: 24 additions & 0 deletions test/hook/v14-double-hook.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { fileURLToPath } from 'url'
import { join } from 'path'
import { strictEqual } from 'assert'
import Hook from '../../index.js'

const toWrap = join(fileURLToPath(import.meta.url), '..', '..', 'fixtures', 'foo.mjs')

Hook([toWrap], (exports) => {
const original = exports.foo
exports.foo = function foo () {
return original() + '-first'
}
})

Hook([toWrap], (exports) => {
const original = exports.foo
exports.foo = function foo () {
return original() + '-second'
}
})

const { foo } = await import('../fixtures/foo.mjs')

strictEqual(foo(), 'foo-first-second')

0 comments on commit e0d8080

Please sign in to comment.