From 153b82ca7735e3c9c8f3226c561e04ada71149f9 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 20 Nov 2020 22:22:08 +0800 Subject: [PATCH] Fix loading external convertersThis fixes Error: Cannot find module 'zigbee-herdsman-converters'Caused by requiring converter from folder which is located outside z2m sources folder (ZIGBEE2MQTT_DATA) (#5027) --- lib/util/utils.js | 15 ++++++++++++--- test/homeassistant.test.js | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/util/utils.js b/lib/util/utils.js index f342918be..75e7f233c 100644 --- a/lib/util/utils.js +++ b/lib/util/utils.js @@ -1,6 +1,8 @@ const equals = require('fast-deep-equal/es6'); const humanizeDuration = require('humanize-duration'); const data = require('./data'); +const vm = require('vm'); +const fs = require('fs'); // Xiaomi uses 4151 and 4447 (lumi.plug) as manufacturer ID. const xiaomiManufacturerID = [4151, 4447]; @@ -146,13 +148,20 @@ function* getExternalConvertersDefinitions(settings) { const externalConverters = settings.get().external_converters; for (const moduleName of externalConverters) { - let converterModule = moduleName; + let converter; if (moduleName.endsWith('.js')) { - converterModule = data.joinPath(moduleName.split('.')[0]); + const sandbox = { + require, + module: {}, + }; + const converterCode = fs.readFileSync(data.joinPath(moduleName), {encoding: 'utf8'}); + vm.runInNewContext(converterCode, sandbox); + converter = sandbox.module.exports; + } else { + converter = require(moduleName); } - const converter = require(converterModule); if (Array.isArray(converter)) { for (const item of converter) { yield item; diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index f741e15b2..533f9bfcc 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -1277,7 +1277,7 @@ describe('HomeAssistant extension', () => { command_topic: true, }, }; - expect(ha._getMapping()['external_converters_device']).toStrictEqual([homeassistantSwitch]); + expect(ha._getMapping()['external_converters_device']).toEqual([homeassistantSwitch]); }); it('Should clear outdated configs', async () => {