{"version":3,"sources":["jsdelivr-header.js","/npm/iobroker.node-red@1.17.2/main.js"],"names":[],"mappings":"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","file":"/npm/iobroker.node-red@1.17.2/main.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/iobroker.node-red@1.17.2/main.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n *\n *      ioBroker node-red Adapter\n *\n *      (c) 2014-2020 bluefox<bluefox@ccu.io>\n *\n *      Apache 2.0 License\n *\n */\n/* jshint -W097 */\n/* jshint strict: false */\n/* jslint node: true */\n'use strict';\n\nconst utils = require('@iobroker/adapter-core'); // Get common adapter utils\nconst adapterName = require('./package.json').name.split('.').pop();\n\nlet   adapter;\nconst fs          = require('fs');\nconst path        = require('path');\nconst spawn       = require('child_process').spawn;\nconst Notify      = require('fs.notify');\nconst attempts    = {};\nconst additional  = [];\nlet secret;\n\nlet userDataDir = __dirname + '/userdata/';\n\nfunction startAdapter(options) {\n    options = options || {};\n    Object.assign(options, {\n        name: adapterName,\n        systemConfig: true,\n        unload: unloadRed\n    });\n\n    adapter = new utils.Adapter(options);\n\n    adapter.on('message', obj => obj && obj.command && processMessage(obj));\n\n    adapter.on('ready', () => installLibraries(main));\n\n    return adapter;\n}\n\nfunction installNpm(npmLib, callback) {\n    const path = __dirname;\n    if (typeof npmLib === 'function') {\n        callback = npmLib;\n        npmLib = undefined;\n    }\n\n    const cmd = 'npm install ' + npmLib + ' --production --prefix \"' + path + '\" --save';\n    adapter.log.info(cmd + ' (System call)');\n    // Install node modules as system call\n\n    // System call used for update of js-controller itself,\n    // because during installation npm packet will be deleted too, but some files must be loaded even during the install process.\n    const exec = require('child_process').exec;\n    const child = exec(cmd);\n    child.stdout.on('data', buf => adapter.log.info(buf.toString('utf8')));\n    child.stderr.on('data', buf => adapter.log.error(buf.toString('utf8')));\n\n    child.on('exit', (code, signal) => {\n        code && adapter.log.error('Cannot install ' + npmLib + ': ' + code);\n        // command succeeded\n        callback && callback(npmLib);\n    });\n}\n\nfunction installLibraries(callback) {\n    let allInstalled = true;\n    if (typeof adapter.common.npmLibs === 'string') {\n        adapter.common.npmLibs = adapter.common.npmLibs.split(/[,;\\s]+/);\n    }\n\n    if (adapter.common && adapter.common.npmLibs) {\n        for (let lib = 0; lib < adapter.common.npmLibs.length; lib++) {\n            if (adapter.common.npmLibs[lib] && adapter.common.npmLibs[lib].trim()) {\n                adapter.common.npmLibs[lib] = adapter.common.npmLibs[lib].trim();\n                if (!fs.existsSync(__dirname + '/node_modules/' + adapter.common.npmLibs[lib] + '/package.json')) {\n\n                    if (!attempts[adapter.common.npmLibs[lib]]) {\n                        attempts[adapter.common.npmLibs[lib]] = 1;\n                    } else {\n                        attempts[adapter.common.npmLibs[lib]]++;\n                    }\n                    if (attempts[adapter.common.npmLibs[lib]] > 3) {\n                        adapter.log.error('Cannot install npm packet: ' + adapter.common.npmLibs[lib]);\n                        continue;\n                    }\n\n                    installNpm(adapter.common.npmLibs[lib], () =>\n                        setImmediate(() => installLibraries(callback)));\n\n                    allInstalled = false;\n                    break;\n                } else {\n                    if (additional.indexOf(adapter.common.npmLibs[lib]) === -1) {\n                        additional.push(adapter.common.npmLibs[lib]);\n                    }\n                }\n            }\n        }\n    }\n    allInstalled && callback();\n}\n\n// is called if a subscribed state changes\n//adapter.on('stateChange', function (id, state) {\n//});\nfunction unloadRed (callback) {\n    // Stop node-red\n    stopping = true;\n    if (redProcess) {\n        adapter.log.info('kill node-red task');\n        redProcess.kill();\n        redProcess = null;\n    }\n    notificationsCreds && notificationsCreds.close();\n    notificationsFlows && notificationsFlows.close();\n\n    callback && callback();\n}\n\nfunction processMessage(obj) {\n    switch (obj.command) {\n        case 'update':\n            writeStateList(error => \n                obj.callback && adapter.sendTo(obj.from, obj.command, error, obj.callback));\n            break;\n\n        case 'stopInstance':\n            unloadRed();\n            break;\n\n    }\n}\n\nfunction getNodeRedPath() {\n    let nodeRed = __dirname + '/node_modules/node-red';\n    if (!fs.existsSync(nodeRed)) {\n        nodeRed = path.normalize(__dirname + '/../node-red');\n        if (!fs.existsSync(nodeRed)) {\n            nodeRed = path.normalize(__dirname + '/../node_modules/node-red');\n            if (!fs.existsSync(nodeRed)) {\n                adapter && adapter.log && adapter.log.error('Cannot find node-red packet!');\n                throw new Error('Cannot find node-red packet!');\n            }\n        }\n    }\n\n    return nodeRed;\n}\n\nfunction getNodeRedEditorPath() {\n    let nodeRedEditor = __dirname + '/node_modules/@node-red/editor-client';\n    if (!fs.existsSync(nodeRedEditor)) {\n        nodeRedEditor = path.normalize(__dirname + '/../@node-red/editor-client');\n        if (!fs.existsSync(nodeRedEditor)) {\n            nodeRedEditor = path.normalize(__dirname + '/../node_modules/@node-red/editor-client');\n            if (!fs.existsSync(nodeRedEditor)) {\n                adapter && adapter.log && adapter.log.error('Cannot find @node-red/editor-client packet!');\n                throw new Error('Cannot find @node-red/editor-client packet!');\n            }\n        }\n    }\n    return nodeRedEditor;\n}\n\nlet redProcess;\nlet stopping;\nlet notificationsFlows;\nlet notificationsCreds;\nlet saveTimer;\nconst nodePath = getNodeRedPath();\nconst editorClientPath = getNodeRedEditorPath();\n\nfunction startNodeRed() {\n    adapter.config.maxMemory = parseInt(adapter.config.maxMemory, 10) || 128;\n    const args = ['--max-old-space-size=' + adapter.config.maxMemory, nodePath + '/red.js', '-v', '--settings', userDataDir + 'settings.js'];\n\n    if (adapter.config.safeMode) {\n        args.push('--safe');\n    }\n\n    adapter.log.info('Starting node-red: ' + args.join(' '));\n\n    redProcess = spawn('node', args);\n\n    redProcess.on('error', err =>\n        adapter.log.error('catched exception from node-red:' + JSON.stringify(err)));\n\n    redProcess.stdout.on('data', data => {\n        if (!data) {\n            return;\n        }\n\n        data = data.toString();\n\n        if (data[data.length - 2] === '\\r' && data[data.length - 1] === '\\n') data = data.substring(0, data.length - 2);\n        if (data[data.length - 2] === '\\n' && data[data.length - 1] === '\\r') data = data.substring(0, data.length - 2);\n        if (data[data.length - 1] === '\\r') data = data.substring(0, data.length - 1);\n\n        if (data.indexOf('[err') !== -1) {\n            adapter.log.error(data);\n        } else if (data.indexOf('[warn]') !== -1) {\n            adapter.log.warn(data);\n        } else if (data.indexOf('[info] [debug:') !== -1) {\n            adapter.log.info(data);\n        } else {\n            adapter.log.debug(data);\n        }\n    });\n\n    redProcess.stderr.on('data', data => {\n\t\tif (!data) {\n\t\t    return;\n        }\n\t\tif (data[0]) {\n            let text = '';\n\t\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\t\ttext += String.fromCharCode(data[i]);\n\t\t\t}\n\t\t\tdata = text;\n\t\t}\n        if (data.indexOf && data.indexOf('[warn]') === -1) {\n            adapter.log.warn(data);\n        } else {\n            adapter.log.error(JSON.stringify(data));\n        }\n    });\n\n    redProcess.on('exit', exitCode => {\n        adapter.log.info('node-red exited with ' + exitCode);\n        redProcess = null;\n        if (!stopping) {\n            setTimeout(startNodeRed, 5000);\n        }\n    });\n}\n\nfunction setOption(line, option, value) {\n    const toFind = \"'%%\" + option + \"%%'\";\n    const pos = line.indexOf(toFind);\n    if (pos !== -1) {\n        return line.substring(0, pos) + ((value !== undefined) ? value : (adapter.config[option] === null || adapter.config[option] === undefined) ? '' : adapter.config[option]) + line.substring(pos + toFind.length);\n    }\n    return line;\n}\n\nfunction writeSettings() {\n    const config = JSON.stringify(adapter.systemConfig);\n    const text = fs.readFileSync(__dirname + '/settings.js').toString();\n    const lines = text.split('\\n');\n    let npms = '\\r\\n';\n    const dir = __dirname.replace(/\\\\/g, '/') + '/node_modules/';\n    const nodesDir = '\"' + __dirname.replace(/\\\\/g, '/') + '/nodes/\"';\n\n    const bind = '\"' + (adapter.config.bind || '0.0.0.0') + '\"';\n    const auth = adapter.config.user && adapter.config.pass ? JSON.stringify({user: adapter.config.user, pass: adapter.config.pass}) : '\"\"';\n    const pass = '\"' + adapter.config.pass + '\"';\n\n    for (let a = 0; a < additional.length; a++) {\n        if (additional[a].startsWith('node-red-')) {\n            continue;\n        }\n        npms += '        \"' + additional[a] + '\": require(\"' + dir + additional[a] + '\")';\n        if (a !== additional.length - 1) {\n            npms += ', \\r\\n';\n        }\n    }\n\n\t// update from 1.0.1 (new convert-option)\n\tif (adapter.config.valueConvert === null      ||\n        adapter.config.valueConvert === undefined ||\n        adapter.config.valueConvert === ''        ||\n        adapter.config.valueConvert === 'true'    ||\n        adapter.config.valueConvert === '1'       ||\n        adapter.config.valueConvert === 1) {\n\t\tadapter.config.valueConvert = true;\n\t}\n    if (adapter.config.valueConvert === 0   ||\n        adapter.config.valueConvert === '0' ||\n        adapter.config.valueConvert === 'false') {\n        adapter.config.valueConvert = false;\n    }\n    for (let i = 0; i < lines.length; i++) {\n        lines[i] = setOption(lines[i], 'port');\n        lines[i] = setOption(lines[i], 'auth', auth);\n        lines[i] = setOption(lines[i], 'pass', pass);\n        lines[i] = setOption(lines[i], 'bind', bind);\n        lines[i] = setOption(lines[i], 'port');\n        lines[i] = setOption(lines[i], 'instance', adapter.instance);\n        lines[i] = setOption(lines[i], 'config', config);\n        lines[i] = setOption(lines[i], 'functionGlobalContext', npms);\n        lines[i] = setOption(lines[i], 'nodesdir', nodesDir);\n        lines[i] = setOption(lines[i], 'httpRoot');\n        lines[i] = setOption(lines[i], 'credentialSecret', secret);\n        lines[i] = setOption(lines[i], 'valueConvert');\n        lines[i] = setOption(lines[i], 'projectsEnabled', adapter.config.projectsEnabled);\n        lines[i] = setOption(lines[i], 'allowCreationOfForeignObjects', adapter.config.allowCreationOfForeignObjects);\n    }\n\n    const oldText = fs.existsSync(userDataDir + 'settings.js') ? fs.readFileSync(userDataDir + 'settings.js').toString('utf8') : '';\n    const newText = lines.join('\\n');\n    if (oldText !== newText) {\n        fs.writeFileSync(userDataDir + 'settings.js', newText);\n    }\n}\n\nfunction writeStateList(callback) {\n    adapter.getForeignObjects('*', 'state', ['rooms', 'functions'], (err, obj) => {\n        // remove native information\n        for (const i in obj) {\n            if (obj.hasOwnProperty(i) && obj[i].native) {\n                delete obj[i].native;\n            }\n        }\n\n        fs.writeFileSync(editorClientPath + '/public/iobroker.json', JSON.stringify(obj));\n        callback && callback(err);\n    });\n}\n\nfunction saveObjects() {\n    if (saveTimer) {\n        clearTimeout(saveTimer);\n        saveTimer = null;\n    }\n    let cred  = undefined;\n    let flows = undefined;\n\n    try {\n        if (fs.existsSync(userDataDir + 'flows_cred.json')) {\n            cred = JSON.parse(fs.readFileSync(userDataDir + 'flows_cred.json'));\n        }\n    } catch(e) {\n        adapter.log.error('Cannot save ' + userDataDir + 'flows_cred.json');\n    }\n    try {\n        if (fs.existsSync(userDataDir + 'flows.json')) {\n            flows = JSON.parse(fs.readFileSync(userDataDir + 'flows.json'));\n        }\n    } catch(e) {\n        adapter.log.error('Cannot save ' + userDataDir + 'flows.json');\n    }\n    //upload it to config\n    adapter.setObject('flows',\n        {\n            common: {\n                name: 'Flows for node-red'\n            },\n            native: {\n                cred:  cred,\n                flows: flows\n            },\n            type: 'config'\n        },\n        () => adapter.log.info('Save ' + userDataDir + 'flows.json')\n    );\n}\n\nfunction syncPublic(path) {\n    path = path || '/public';\n\n    const dir = fs.readdirSync(__dirname + path);\n\n    if (!fs.existsSync(editorClientPath + path)) {\n        fs.mkdirSync(editorClientPath + path);\n    }\n\n    for (let i = 0; i < dir.length; i++) {\n        const stat = fs.statSync(__dirname + path + '/' + dir[i]);\n        if (stat.isDirectory())  {\n            syncPublic(path + '/' + dir[i]);\n        } else {\n            if (!fs.existsSync(editorClientPath + path + '/' + dir[i])) {\n                fs.createReadStream(__dirname + path + '/' + dir[i]).pipe(fs.createWriteStream(editorClientPath + path + '/' + dir[i]));\n            }\n        }\n    }\n}\n\nfunction installNotifierFlows(isFirst) {\n    if (!notificationsFlows) {\n        if (fs.existsSync(userDataDir + 'flows.json')) {\n            if (!isFirst) saveObjects();\n            // monitor project file\n            notificationsFlows = new Notify([userDataDir + 'flows.json']);\n            notificationsFlows.on('change', () => {\n                saveTimer && clearTimeout(saveTimer);\n                saveTimer = setTimeout(saveObjects, 500);\n            });\n        } else {\n            // Try to install notifier every 10 seconds till the file will be created\n            setTimeout(() => installNotifierFlows(), 10000);\n        }\n    }\n}\n\nfunction installNotifierCreds(isFirst) {\n    if (!notificationsCreds) {\n        if (fs.existsSync(userDataDir + 'flows_cred.json')) {\n            if (!isFirst) saveObjects();\n            // monitor project file\n            notificationsCreds = new Notify([userDataDir + 'flows_cred.json']);\n            notificationsCreds.on('change', () => {\n                saveTimer && clearTimeout(saveTimer);\n                saveTimer = setTimeout(saveObjects, 500);\n            });\n        } else {\n            // Try to install notifier every 10 seconds till the file will be created\n            setTimeout(() => installNotifierCreds(), 10000);\n        }\n    }\n}\n\nfunction main() {\n    if (adapter.config.projectsEnabled === undefined) adapter.config.projectsEnabled = false;\n    if (adapter.config.allowCreationOfForeignObjects === undefined) adapter.config.allowCreationOfForeignObjects = false;\n\n    // Find userdata directory\n\n    // normally /opt/iobroker/node_modules/iobroker.js-controller\n    // but can be /example/ioBroker.js-controller\n    const controllerDir = utils.controllerDir;\n    const parts = controllerDir.split('/');\n    if (parts.length > 1 && parts[parts.length - 2] === 'node_modules') {\n        parts.splice(parts.length - 2, 2);\n        userDataDir = parts.join('/');\n        userDataDir += '/iobroker-data/node-red/';\n    }\n\n    // create userData directory\n    if (!fs.existsSync(userDataDir)) {\n        fs.mkdirSync(userDataDir);\n    }\n\n    syncPublic();\n\n    // Read configuration\n    adapter.getObject('flows', (err, obj) => {\n        if (obj && obj.native && obj.native.cred) {\n            const c = JSON.stringify(obj.native.cred);\n            // If really not empty\n            if (c !== '{}' && c !== '[]') {\n                fs.writeFileSync(userDataDir + 'flows_cred.json', JSON.stringify(obj.native.cred));\n            }\n        }\n        if (obj && obj.native && obj.native.flows) {\n            const f = JSON.stringify(obj.native.flows);\n            // If really not empty\n            if (f !== '{}' && f !== '[]') {\n                fs.writeFileSync(userDataDir  + 'flows.json', JSON.stringify(obj.native.flows));\n            }\n        }\n\n        installNotifierFlows(true);\n        installNotifierCreds(true);\n\n        adapter.getForeignObject('system.config', (err, obj) => {\n            if (obj && obj.native && obj.native.secret) {\n                //noinspection JSUnresolvedVariable\n                secret = obj.native.secret;\n            }\n            // Create settings for node-red\n            writeSettings();\n            writeStateList(() => startNodeRed());\n        });\n    });\n}\n\n// If started as allInOne/compact mode => return function to create instance\nif (module && module.parent) {\n    module.exports = startAdapter;\n} else {\n    // or start the instance directly\n    startAdapter();\n}\n\n"]}