{"_id":"@breshinas/node-red-contrib-flow-manager","name":"@breshinas/node-red-contrib-flow-manager","dist-tags":{"latest":"0.8.0"},"versions":{"0.8.0":{"name":"@breshinas/node-red-contrib-flow-manager","version":"0.8.0","node-red":{"version":">=2.0.0","nodes":{"flow-manager":"flow-manager.js"}},"engines":{"node":">=16.20.1"},"scripts":{"start":"build "},"dependencies":{"axios":"0.19.2","body-parser":"^1.0.0","eol":"^0.9.1","fs-extra":"^9.0.1","js-yaml":"^3.14.0","jsonata":"*","log4js":"~1.0.1"},"repository":{"type":"git","url":"git+https://github.com/breshinas/node-red-contrib-flow-manager.git"},"keywords":["node-red","node","red","flow","manager"],"publishConfig":{"access":"public"},"author":{"name":"Aleksey Breshin"},"license":"MIT","_id":"@breshinas/node-red-contrib-flow-manager@0.8.0","gitHead":"93354d5dab60f7aa169ed788fc567f9c3a9b9241","description":"This is a fork from the excellent node-red-contrib-flow-manager with a small patch.","bugs":{"url":"https://github.com/breshinas/node-red-contrib-flow-manager/issues"},"homepage":"https://github.com/breshinas/node-red-contrib-flow-manager#readme","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-MErsXMqZTASOL6ztLu8BzbPxtpe27WrOgeCWgtJ80YWrjuEwK5wiSQk79XmC8DzwVRnAsDGXT1qF8bzzi6LyVQ==","shasum":"d439a615524a0253520dbef6f46a85ee9c12d00f","tarball":"https://registry.npmjs.org/@breshinas/node-red-contrib-flow-manager/-/node-red-contrib-flow-manager-0.8.0.tgz","fileCount":7,"unpackedSize":86581,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCtgYKsOZIB+or2KU546uJZFVNerXIHM6mH3EzHGcNsmgIgf+OlnYMxlaFOdV8pN/d3BwTfZJTSc1UWF4PoEJC9CPQ="}]},"_npmUser":{"name":"breshinas","email":"9035788472@mail.ru"},"directories":{},"maintainers":[{"name":"breshinas","email":"9035788472@mail.ru"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node-red-contrib-flow-manager_0.8.0_1761225523716_0.15178508500578203"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-23T13:18:43.606Z","0.8.0":"2025-10-23T13:18:43.950Z","modified":"2025-10-23T13:18:44.188Z"},"maintainers":[{"name":"breshinas","email":"9035788472@mail.ru"}],"description":"This is a fork from the excellent node-red-contrib-flow-manager with a small patch.","homepage":"https://github.com/breshinas/node-red-contrib-flow-manager#readme","keywords":["node-red","node","red","flow","manager"],"repository":{"type":"git","url":"git+https://github.com/breshinas/node-red-contrib-flow-manager.git"},"author":{"name":"Aleksey Breshin"},"bugs":{"url":"https://github.com/breshinas/node-red-contrib-flow-manager/issues"},"license":"MIT","readme":"## _Flow Manager_ module for node-red\r\n\r\nThis is a fork from the excellent node-red-contrib-flow-manager with a small patch.\r\n\r\nFlow Manager separates your flow json to multiple files\r\n\r\n[View change log](https://raw.githubusercontent.com/breshinas/node-red-contrib-flow-manager/refs/heads/master/CHANGELOG.md)\r\n\r\n### Installation\r\n\r\nThis assumes you have [Node-RED](https://nodered.org) already installed and working, if you need to install Node-RED see [here](https://nodered.org/docs/getting-started/installation)\r\n\r\n**NOTE:** This requires [Node.js](https://nodejs.org) v14+\r\n\r\nInstall via Node-RED Manage Palette\r\n\r\n```\r\nnode-red-contrib-flow-manager\r\n```\r\n\r\nInstall via npm\r\n\r\n```shell\r\n$ cd ~/.node-red\r\n$ npm install node-red-contrib-flow-manager\r\n# Restart node-red\r\n```\r\n\r\n### Usage \r\nAfter installation of this module, during first boot only, A migration process will initiate.\r\n\r\nDuring migration, your main flow json file will be split to multiple files which will store your node information.<br/>\r\nIt is advised to **back up your main flow json**, before running this module for the first time.\r\n\r\nNode-RED startup process after migration:<br/>\r\nAll of your flow files are combined into a single JSON object, which is then loaded and served as your main flow object.\r\n\r\nFor that reason, it is advised to add your \"fat\" flow json file to .gitignore because from that moment, the flows are saved separately.\r\n\r\nThe nodes will be stored in the following subdirectories of your Node-RED path as such:\r\n* `/flows/`**`flow name`**\r\n* `/subflows/`**`subflow name`**\r\n* `/config-nodes.json` (global config nodes will be stored here)\r\n\r\nIt's a good idea to add these paths to your version control system. \r\n\r\n#### ![Filter Flows](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/filter_flows_button.png?raw=true)\r\n* Allows selecting which flows Node-RED will load, and which will be ignored and not loaded, **not only in Node-RED's UI, also in it's NodeJS process.** <br/>\r\n* Unselected flows are NOT deleted, only \"ignored\" until you select them again using `Filter Flows`.\r\n* Filtering configuration is stored in `flow-manager-cfg.json` file under your Node-RED path.\r\n* if `flow-manager-cfg.json` file does not exist, or exists but malformed, or contains an empty JSON array, then all flows will be loaded and no filtering is done.\r\n* ![Filter Flows Popup](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/filter_flows_popup.png?raw=true)\r\n    \r\n### envnodes\r\nenvnodes allows configuration of nodes using an external source and custom logic.<br/>\r\nexample:\r\ncreate \"envnodes/someName.jsonata\" in your Node-RED project directory and put these contents:\r\n\r\n```json5\r\n  (\r\n     $config := require(basePath & \"/someConfig.json\");\r\n     {\r\n       /* mqtt config node */\r\n       \"21bcf36a.891e4d\": {\r\n          \"broker\": $config.mqtt.broker,\r\n          \"port\": $config.mqtt.port\r\n       },\r\n       \"name:MyInject\": {\r\n          \"topic\": \"niceTopic\"\r\n       }\r\n     };\r\n  )\r\n```\r\nThe result would be that your mqtt config node will use values from an external configuration file (which is useful in some cases),\r\nAnd a topic value will be inserted to an inject node matched with the given name.\r\n\r\nNote `basePath` is the path to your Node-RED directory.<br/>\r\nWhen using Node-RED's \"project mode\", the value is the project folder path.\r\n\r\nSupported envnode file ext: .jsonata .js .json\r\nwhen using .js you can either module.exports = {...} the object directly, or use a function/async function (for example to read external file) and return an object.<br/>\r\njs example:\r\n\r\n```javascript\r\nconst fs = require('fs-extra');\r\n\r\nmodule.exports = async function() {\r\n    const configTopic = await fs.readJson('./config').topic;\r\n    return {\r\n        \"name:MyInject\": {\r\n            \"topic\": configTopic\r\n        },\r\n        \"cff2a203.8158a\": {\r\n            \"someProperty\": \"myProperty\"\r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nAttempting to change any envnode controlled property via Node-RED UI/AdminAPI will be cancelled (with a warning popup) to keep original values defined in your envnodes configuration.\r\n\r\n![EnvNodes Warning](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/envnodes_warning.png?raw=true)\r\n\r\n### Remote Deploy\r\n![Remote Deploy Button](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/remote_deploy_button.png?raw=true)\r\n\r\nIf you work in a server-client environment, where you work locally on your flows, and once in a while need to push your local changes to a remote process running Node-RED.\r\n\r\nDo the following to enable Remote Deployment feature:<br/>\r\n* Add remote definitions to `flow-manager-cfg.json` (you can add as many as you want, choose any name you wish for each remote)\r\n    -   ```json\r\n        {\r\n          \"filter\": [],\r\n          \"fileFormat\": \"json\",\r\n          \"remoteDeploy\": {\r\n            \"remotes\": [\r\n              {\r\n                \"name\": \"Production\",\r\n                \"nrAddress\": \"http://yourAddress:1881\"\r\n              },\r\n              {\r\n                \"name\": \"Staging\",\r\n                \"nrAddress\": \"http://yourOtherAddress:1881\"\r\n              }\r\n            ]\r\n          }\r\n        }\r\n        ``` \r\n* Restart Node-RED\r\n* You should see the new \"Remote Deploy\" button on top of the Node-RED UI.\r\n\r\n![Remote Deploy Remote Selection](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/remote_deploy_select_remote.png?raw=true)\r\n\r\n![Remote Deploy Diff Tool](https://github.com/breshinas/node-red-contrib-flow-manager/blob/master/img/remote_diff.png?raw=true)\r\n\r\n    \r\n### YAML flow file format\r\n\r\nNote `yaml` format is used by default.\r\nYou can configure flow-manager to load/save flow files in YAML format instead oj JSON, by modifying file `flow-manager-cfg.json` as such:\r\n\r\n```json\r\n{\r\n  ...\r\n  \"fileFormat\": \"yaml\"\r\n  ...\r\n}\r\n```\r\nThe advantage is the code within function node becomes easier to read when inspecting the flow file itself.<br/>\r\nSee comparison below\r\n#### YAML\r\n```yaml\r\n- id: 493f0b3.b3b48f4\r\n  type: function\r\n  z: 70dd6be0.e35274\r\n  name: 'SomeFuncNode'\r\n  func: |-\r\n      const str = \"hello\";\r\n      console.log(str + ' world');\r\n      msg.payload = 'test';\r\n      return msg;\r\n  outputs: 1\r\n  noerr: 0\r\n  x: 580\r\n  'y': 40\r\n  wires:\r\n    - []\r\n```\r\n#### JSON\r\n```json\r\n{\r\n    \"id\": \"493f0b3.b3b48f4\",\r\n    \"type\": \"function\",\r\n    \"z\": \"70dd6be0.e35274\",\r\n    \"name\": \"SomeFuncNode\",\r\n    \"func\": \"const str = \\\"hello\\\";\\nconsole.log(str + ' world');\\nmsg.payload = 'test';\\nreturn msg;\",\r\n    \"outputs\": 1,\r\n    \"noerr\": 0,\r\n    \"x\": 580,\r\n    \"y\": 40,\r\n    \"wires\": [\r\n        []\r\n    ]\r\n}\r\n```\r\n  \r\n  \r\n### flow-manager RESTful API\r\n\r\n#### Get all flow names\r\n\r\n```shell\r\ncurl --request GET \\\r\n  http://localhost:1880/flow-manager/flow-names\r\n```\r\n\r\nResponse:\r\n\r\n```json\r\n  [\"Flow 1.json\",\"Flow 2.json\",\"Flow 3.json\",\"Flow 4.json\"]\r\n```\r\n\r\n#### Get flow-manager-cfg.json contents\r\n\r\n```shell\r\ncurl --request GET \\\r\n  http://localhost:1880/flow-manager/cfg\r\n```\r\n\r\n#### get / change filter flows\r\nget\r\n\r\n```shell\r\ncurl --request GET \\\r\n  http://localhost:1880/flow-manager/filter-flows\r\n```\r\n\r\nchange\r\n\r\n```shell\r\ncurl --header \"Content-Type: application/json\" \\\r\n  --request PUT \\\r\n  --data '[\"Flow 1\", \"Flow 2\"]' \\\r\n  http://localhost:1880/flow-manager/filter-flows\r\n```\r\n\r\n#### Modify flow files (add, update, delete any flow/subflow files)\r\n\r\nRequest URL template:\r\n\r\n```\r\nhttp://localhost:1880/flow-manager/flow-files/:type/:fileName?\r\n```\r\n`type` can be `flow`/`subflow`/`global`<br/>\r\ncan pass plural too: `flows`/`subflows`\r\n\r\nNotice `fileName` is optional if you request \"global\" flow, leave out the `fileName` url part.\r\n\r\nget\r\n\r\n```shell\r\ncurl --request GET \\\r\n  http://localhost:1880/flow-manager/flow-files/flow/MyFlow\r\n```\r\n\r\ndelete\r\n\r\n```shell\r\ncurl --request DELETE \\\r\n  http://localhost:1880/flow-manager/flow-files/flow/MyFlow\r\n```\r\n\r\nadd/update (mtime/atime query params are optional, in case you wish to set mtime \"Modified Time\" or atime \"Access Time\" after the file is written)\r\n\r\n```shell\r\ncurl --header \"Content-Type: application/json\" \\\r\n  --request POST \\\r\n  --data '[{\"id\":\"d4366369.5303d\",\"type\":\"tab\",\"label\":\"NewFlow\",\"disabled\":false,\"info\":\"\"}]' \\\r\n  http://localhost:1880/flow-manager/flow-files/flow/NewFlow\r\n```\r\n\r\nExample with mtime query param:\r\n\r\n```shell\r\ncurl --header \"Content-Type: application/json\" \\\r\n  --request POST \\\r\n  --data '[{\"id\":\"d4366369.5303d\",\"type\":\"tab\",\"label\":\"NewFlow\",\"disabled\":false,\"info\":\"\"}]' \\\r\n  'http://localhost:1880/flow-manager/flow-files/flows/NewFlow?mtime=8/16/2020,%206:12:17%20PM'\r\n```\r\n\r\n#### On Demand flow loading using external RESTful requests\r\nDuring runtime, you can request flow-manager to load any flow file placed in the flows directory,<br/>\r\nby sending a POST request with the flows you wish to load (regardless of whether you configured any filter-flows or not)\r\n\r\nRequest to deploy all flows / redeploy current flows:\r\n\r\n```shell\r\ncurl --header \"Content-Type: application/json\" \\\r\n  --request POST \\\r\n  --data '{\"action\":\"loadAll\"/\"reloadOnly\" }' \\\r\n  http://localhost:1880/flow-manager/states\r\n```\r\n\r\nRequest to add/remove/replace any flow:\r\n\r\n```shell\r\ncurl --header \"Content-Type: application/json\" \\\r\n  --request POST \\\r\n  --data '{\"action\":\"addOndemand\"/\"removeOndemand\"/\"replaceOndemand\" \"flows\":[\"Flow 1\",\"Flow 2\"] }' \\\r\n  http://localhost:1880/flow-manager/states\r\n```\r\n\r\n#### Retrieve flow states for all flows, subflows, and global nodes (config nodes)\r\n\r\nRetrieve state for specific type and flow.<br/>\r\n`http://localhost:1880/flow-manager/states/:type/:flowName`\r\n\r\nRetrieve state for all flows of a given type.<br/>\r\n`http://localhost:1880/flow-manager/states/:type`\r\n\r\nRetrieve state for all flows/subflows/global.<br/>\r\n`http://localhost:1880/flow-manager/states/`\r\n\r\n`:type` can be subflow/flow/global (if `global`, there's no need for `:flowName`).\r\n\r\nExample response for specific flow (`http://localhost:1880/flow-manager/states/flow/Flow1`)\r\n\r\n```json\r\n{\r\n    \"deployed\": true,\r\n    \"hasUpdate\": true,\r\n    \"onDemand\": false,\r\n    \"rev\": \"477a9952b50e161afdf2e4bb6b84ee31\",\r\n    \"mtime\": \"2020-08-16T13:54:23.000Z\",\r\n    \"oldRev\": \"54d163c840657920aaac705dadecae2b\", // If hasUpdate\r\n    \"oldMtime\": \"2020-08-14T17:30:10.000Z\" // If hasUpdate\r\n}\r\n```\r\n* `deployed` whether that flow file is deployed. \r\n* `hasUpdate` whether that flow file was changed externally, and can be deployed again to update.\r\n* `onDemand` whether that flow was deployed by an OnDemand request, and is not part of filtered flows selection. \r\n* `rev/oldRev` revision (checksum) of file.\r\n* `mtime/oldMtime` Modified Time of file. \r\n\r\n#### Access flow-manager RESTful API on remotes defined in `flow-manager-cfg.json`\r\n\r\nRequest template:\r\n\r\n```\r\nhttp://localhost:1880/flow-manager/remotes/:remoteName/[append any rest endpoint here]\r\n```\r\n\r\nExample using `flow-names`\r\n\r\n```shell\r\ncurl --request GET \\\r\n  http://localhost:1880/flow-manager/remotes/Production/flow-names\r\n\r\n```\r\n","readmeFilename":"README.md","_rev":"1-7c82bbbab40260caf76ccb9330e9cdad"}