diff --git a/src/plugins/consoleShortcuts/index.ts b/src/plugins/consoleShortcuts/index.ts index 9896bcdfb..74243d9cd 100644 --- a/src/plugins/consoleShortcuts/index.ts +++ b/src/plugins/consoleShortcuts/index.ts @@ -161,16 +161,32 @@ function loadAndCacheShortcut(key: string, val: any, forceLoad: boolean) { const currentVal = val.getter(); if (!currentVal || val.preload === false) return currentVal; - let value: any; - if (currentVal[SYM_LAZY_GET]) { - value = forceLoad ? currentVal[SYM_LAZY_GET]() : currentVal[SYM_LAZY_CACHED]; - } else if (currentVal[SYM_PROXY_INNER_GET]) { - value = forceLoad ? currentVal[SYM_PROXY_INNER_GET]() : currentVal[SYM_PROXY_INNER_VALUE]; - } else { - value = currentVal; + function unwrapProxy(value: any) { + if (value[SYM_LAZY_GET]) { + return forceLoad ? value[SYM_LAZY_GET]() : value[SYM_LAZY_CACHED]; + } else if (value[SYM_PROXY_INNER_GET]) { + return forceLoad ? value[SYM_PROXY_INNER_GET]() : value[SYM_PROXY_INNER_VALUE]; + } + + return value; } - if (value) define(window.shortcutList, key, { value }); + const value = unwrapProxy(currentVal); + if (typeof value === "object") { + const descriptors = Object.getOwnPropertyDescriptors(value); + + for (const propKey in descriptors) { + const descriptor = descriptors[propKey]; + + if (descriptor.writable === true || descriptor.set != null) { + value[propKey] = unwrapProxy(value[propKey]); + } + } + } + + if (value) { + define(window.shortcutList, key, { value }); + } return value; } diff --git a/src/webpack/api.tsx b/src/webpack/api.tsx index 06f9bce11..6f360fa39 100644 --- a/src/webpack/api.tsx +++ b/src/webpack/api.tsx @@ -426,6 +426,8 @@ export function findByFactoryCode(...code: CodeFilter | [...CodeFilter, * Find the module exports of the first module which the factory includes all the given code, * then map them into an easily usable object via the specified mappers. * + * IMPORTANT: You can destructure the properties of the returned object at top level as long as the property filter does not return a primitive value export. + * * @example * const Modals = mapMangledModule("headerIdIsManaged:", { * openModal: filters.byCode("headerIdIsManaged:"), @@ -444,7 +446,7 @@ export function mapMangledModule(code: string | RegExp | // Wrapper to select whether the parent factory filter or child mapper filter failed when the error is thrown const errorMsgWrapper = lazyString(() => `Webpack mapMangledModule ${callbackCalled ? "mapper" : "factory"} filter matched no module. Filter: ${printFilter(callbackCalled ? mappers[newName] : factoryFilter)}`); - const [proxy, setInnerValue] = proxyInner(errorMsgWrapper, "Webpack find with proxy called on a primitive value."); + const [proxy, setInnerValue] = proxyInner(errorMsgWrapper, "Webpack find with proxy called on a primitive value. This may happen if you are trying to destructure a mapMangledModule primitive value on top level."); mapping[newName] = proxy; setters[newName] = setInnerValue; } @@ -463,6 +465,10 @@ export function mapMangledModule(code: string | RegExp | const filter = mappers[newName]; if (filter(exportValue)) { + if (typeof exportValue !== "object" && typeof exportValue !== "function") { + mapping[newName] = exportValue; + } + setters[newName](exportValue); } }