mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Compare commits
	
		
			26 Commits
		
	
	
		
			fix-cred-o
			...
			rename-pac
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0346294c59 | ||
|  | 8d240ca797 | ||
|  | 7dbbafec1b | ||
|  | c49330f9d1 | ||
|  | 10324d8260 | ||
|  | 8f27dae7ea | ||
|  | 74794fea09 | ||
|  | 4d202a7a37 | ||
|  | e0d71abdc6 | ||
|  | 550eb6ee2f | ||
|  | f737162697 | ||
|  | ce57ba80eb | ||
|  | b3ce0c0079 | ||
|  | 4adc6b269c | ||
|  | 920b0178ec | ||
|  | 7870830367 | ||
|  | 4c1d7ad2d2 | ||
|  | 661b07c856 | ||
|  | 5670bd8265 | ||
|  | 156c3984a7 | ||
|  | f91af2153a | ||
|  | 805f8a5ee7 | ||
|  | 113d42ef35 | ||
|  | e804addf0a | ||
|  | 4bb2b91ee6 | ||
|  | 5bb66ed7d4 | 
| @@ -432,6 +432,7 @@ RED.palette = (function() { | ||||
|                 categoryNode.find(".red-ui-palette-content").slideToggle(); | ||||
|                 categoryNode.find("i").toggleClass("expanded"); | ||||
|             } | ||||
|             categoryNode.hide(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -510,6 +511,7 @@ RED.palette = (function() { | ||||
|                     currentCategoryNode.find(".red-ui-palette-content").slideToggle(); | ||||
|                     currentCategoryNode.find("i").toggleClass("expanded"); | ||||
|                 } | ||||
|                 currentCategoryNode.hide(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -3369,6 +3369,9 @@ RED.view = (function() { | ||||
|         } | ||||
|         if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) { | ||||
|             mouse_mode = RED.state.DEFAULT; | ||||
|             // Avoid dbl click causing text selection. | ||||
|             d3.event.preventDefault() | ||||
|             document.getSelection().removeAllRanges() | ||||
|             if (d.type != "subflow") { | ||||
|                 if (/^subflow:/.test(d.type) && (d3.event.ctrlKey || d3.event.metaKey)) { | ||||
|                     RED.workspaces.show(d.type.substring(8)); | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
|     height: 50px; | ||||
|     background: var(--red-ui-secondary-background); | ||||
|     border: 2px solid var(--red-ui-primary-border-color); | ||||
|     color: var(--red-ui-primary-text-color); | ||||
|     text-align: center; | ||||
|     line-height:50px; | ||||
|  | ||||
| @@ -51,7 +52,7 @@ | ||||
|  | ||||
| .red-ui-editor-radial-menu-opt-disabled { | ||||
|     border-color: var(--red-ui-tertiary-border-color); | ||||
|     color: var(--red-ui-tertiary-border-color); | ||||
|     color: var(--red-ui-secondary-text-color-disabled); | ||||
| } | ||||
| .red-ui-editor-radial-menu-opt-active { | ||||
|     background: var(--red-ui-secondary-background-hover); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|         <label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label> | ||||
|         <select id="node-input-scope-select"> | ||||
|             <option value="all" data-i18n="status.scope.all"></option> | ||||
|             <option value="target" data-i18n="status.scope.selected"></options> | ||||
|             <option value="target" data-i18n="status.scope.selected"></option> | ||||
|         </select> | ||||
|     </div> | ||||
|     <div class="form-row node-input-target-row"> | ||||
|   | ||||
| @@ -295,7 +295,7 @@ module.exports = function(RED) { | ||||
|                         /* mute error - it simply isnt JSON, just leave payload as a string */ | ||||
|                     } | ||||
|                 } | ||||
|             } //else {  | ||||
|             } //else { | ||||
|                 //leave as buffer | ||||
|             //} | ||||
|         } | ||||
| @@ -357,7 +357,7 @@ module.exports = function(RED) { | ||||
|                         return; | ||||
|                     } | ||||
|                     done(err); | ||||
|                 });  | ||||
|                 }); | ||||
|             } else { | ||||
|                 done(); | ||||
|             } | ||||
| @@ -366,6 +366,16 @@ module.exports = function(RED) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function updateStatus(node, allNodes) { | ||||
|         let setStatus = setStatusDisconnected | ||||
|         if(node.connecting) { | ||||
|             setStatus = setStatusConnecting | ||||
|         } else if(node.connected) { | ||||
|             setStatus = setStatusConnected | ||||
|         } | ||||
|         setStatus(node, allNodes) | ||||
|     } | ||||
|  | ||||
|     function setStatusDisconnected(node, allNodes) { | ||||
|         if(allNodes) { | ||||
|             for (var id in node.users) { | ||||
| @@ -697,16 +707,21 @@ module.exports = function(RED) { | ||||
|             if (Object.keys(node.users).length === 1) { | ||||
|                 if(node.autoConnect) { | ||||
|                     node.connect(); | ||||
|                     //update nodes status | ||||
|                     setTimeout(function() { | ||||
|                         updateStatus(node, true) | ||||
|                     }, 1) | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         node.deregister = function(mqttNode,done) { | ||||
|         node.deregister = function(mqttNode, done, autoDisconnect) { | ||||
|             delete node.users[mqttNode.id]; | ||||
|             if (!node.closing && node.connected && Object.keys(node.users).length === 0) { | ||||
|                 node.disconnect(); | ||||
|             if (autoDisconnect && !node.closing && node.connected && Object.keys(node.users).length === 0) { | ||||
|                 node.disconnect(done); | ||||
|             } else { | ||||
|                 done(); | ||||
|             } | ||||
|             done(); | ||||
|         }; | ||||
|         node.canConnect = function() { | ||||
|             return !node.connected && !node.connecting; | ||||
| @@ -840,7 +855,7 @@ module.exports = function(RED) { | ||||
|             let waitEnd = (client, ms) => { | ||||
|                 return new Promise( (resolve, reject) => { | ||||
|                     node.closing = true; | ||||
|                     if(!client) {  | ||||
|                     if(!client) { | ||||
|                         resolve(); | ||||
|                      } else { | ||||
|                         const t = setTimeout(() => { | ||||
| @@ -1019,7 +1034,7 @@ module.exports = function(RED) { | ||||
|  | ||||
|         /** | ||||
|          * Add event handlers to the MQTT.js client and track them so that | ||||
|          * we do not remove any handlers that the MQTT client uses internally.   | ||||
|          * we do not remove any handlers that the MQTT client uses internally. | ||||
|          * Use {@link node._clientRemoveListeners `node._clientRemoveListeners`} to remove handlers | ||||
|          * @param {string} event The name of the event | ||||
|          * @param {function} handler The handler for this event | ||||
| @@ -1027,11 +1042,11 @@ module.exports = function(RED) { | ||||
|          node._clientOn = function(event, handler) { | ||||
|             node.clientListeners.push({event, handler}) | ||||
|             node.client.on(event, handler) | ||||
|         }  | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Remove event handlers from the MQTT.js client & only the events  | ||||
|          * that we attached in {@link node._clientOn `node._clientOn`}.   | ||||
|          * Remove event handlers from the MQTT.js client & only the events | ||||
|          * that we attached in {@link node._clientOn `node._clientOn`}. | ||||
|          * * If `event` is omitted, then all events matching `handler` are removed | ||||
|          * * If `handler` is omitted, then all events named `event` are removed | ||||
|          * * If both parameters are omitted, then all events are removed | ||||
| @@ -1220,7 +1235,7 @@ module.exports = function(RED) { | ||||
|                     } else { | ||||
|                         node.brokerConn.unsubscribe(node.topic,node.id, removed); | ||||
|                     } | ||||
|                     node.brokerConn.deregister(node, done); | ||||
|                     node.brokerConn.deregister(node, done, removed); | ||||
|                     node.brokerConn = null; | ||||
|                 } else { | ||||
|                     done(); | ||||
| @@ -1283,9 +1298,9 @@ module.exports = function(RED) { | ||||
|                 node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); | ||||
|             } | ||||
|             node.brokerConn.register(node); | ||||
|             node.on('close', function(done) { | ||||
|             node.on('close', function(removed, done) { | ||||
|                 if (node.brokerConn) { | ||||
|                     node.brokerConn.deregister(node,done); | ||||
|                     node.brokerConn.deregister(node, done, removed) | ||||
|                     node.brokerConn = null; | ||||
|                 } else { | ||||
|                     done(); | ||||
|   | ||||
| @@ -435,6 +435,10 @@ in your Node-RED user directory (${RED.settings.userDir}). | ||||
|                                     formData.append(opt, val); | ||||
|                                 } else if (typeof val === 'object' && val.hasOwnProperty('value')) { | ||||
|                                     formData.append(opt,val.value,val.options || {}); | ||||
|                                 } else if (Array.isArray(val)) { | ||||
|                                     for (var i=0; i<val.length; i++) { | ||||
|                                         formData.append(opt, val[i]) | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     formData.append(opt,JSON.stringify(val)); | ||||
|                                 } | ||||
|   | ||||
| @@ -251,7 +251,9 @@ module.exports = function(RED) { | ||||
|                         } | ||||
|                         else { | ||||
|                             node.buffer = buff.slice(p,buff.length); | ||||
|                             node.pendingDones.push(done); | ||||
|                             if (node.buffer.length > 0) { | ||||
|                                 node.pendingDones.push(done); | ||||
|                             } | ||||
|                         } | ||||
|                         if (node.buffer.length == 0) { | ||||
|                             done(); | ||||
|   | ||||
| @@ -106,8 +106,8 @@ function getLocalNodeFiles(dir, skipValidNodeRedModules) { | ||||
|     // when loading local files, if the path is a valid node-red module | ||||
|     // dont include it (will be picked up in scanTreeForNodesModules) | ||||
|     if(skipValidNodeRedModules && files.indexOf("package.json") >= 0) { | ||||
|         const package = getPackageDetails(dir) | ||||
|         if(package.isNodeRedModule) { | ||||
|         const packageDetails = getPackageDetails(dir) | ||||
|         if(packageDetails.isNodeRedModule) { | ||||
|             return {files: [], icons: []}; | ||||
|         } | ||||
|     } | ||||
| @@ -135,17 +135,17 @@ function getLocalNodeFiles(dir, skipValidNodeRedModules) { | ||||
|     return {files: result, icons: icons} | ||||
| } | ||||
|  | ||||
| function scanDirForNodesModules(dir,moduleName,package) { | ||||
| function scanDirForNodesModules(dir,moduleName,packageDetails) { | ||||
|     let results = []; | ||||
|     let scopeName; | ||||
|     let files | ||||
|     try { | ||||
|         let isNodeRedModule = false | ||||
|         if(package) { | ||||
|             dir = path.join(package.moduleDir,'..') | ||||
|             files = [path.basename(package.moduleDir)] | ||||
|             moduleName =  (package.package ? package.package.name : null) || moduleName | ||||
|             isNodeRedModule = package.isNodeRedModule | ||||
|         if(packageDetails) { | ||||
|             dir = path.join(packageDetails.moduleDir,'..') | ||||
|             files = [path.basename(packageDetails.moduleDir)] | ||||
|             moduleName =  (packageDetails.package ? packageDetails.package.name : null) || moduleName | ||||
|             isNodeRedModule = packageDetails.isNodeRedModule | ||||
|         } else { | ||||
|             files = fs.readdirSync(dir); | ||||
|             if (moduleName) { | ||||
| @@ -159,8 +159,8 @@ function scanDirForNodesModules(dir,moduleName,package) { | ||||
|  | ||||
|         // if we have found a package.json, this IS a node_module, lets see if it is a node-red node | ||||
|         if (!isNodeRedModule && files.indexOf('package.json') > -1) { | ||||
|             package = getPackageDetails(dir) // get package details | ||||
|             if(package && package.isNodeRedModule) { | ||||
|             packageDetails = getPackageDetails(dir) // get package details | ||||
|             if(packageDetails && packageDetails.isNodeRedModule) { | ||||
|                 isNodeRedModule = true | ||||
|                 files = ['package.json'] // shortcut the file scan | ||||
|             } | ||||
| @@ -179,8 +179,8 @@ function scanDirForNodesModules(dir,moduleName,package) { | ||||
|             } else { | ||||
|                 if ((isNodeRedModule || (!moduleName || fn == moduleName)) && (isIncluded(fn) && !isExcluded(fn))) { | ||||
|                     try { | ||||
|                         const moduleDir = isNodeRedModule ? package.moduleDir : path.join(dir,fn); | ||||
|                         const pkg = package || getPackageDetails(moduleDir) | ||||
|                         const moduleDir = isNodeRedModule ? packageDetails.moduleDir : path.join(dir,fn); | ||||
|                         const pkg = packageDetails || getPackageDetails(moduleDir) | ||||
|                         if(pkg.error) { | ||||
|                             throw pkg.error | ||||
|                         } | ||||
|   | ||||
| @@ -18,7 +18,7 @@ var i18n = require("@node-red/util").i18n; | ||||
|  | ||||
| module.exports = { | ||||
|     "package.json": function(project) { | ||||
|         var package = { | ||||
|         var packageDetails = { | ||||
|             "name": project.name, | ||||
|             "description": project.summary||i18n._("storage.localfilesystem.projects.summary"), | ||||
|             "version": "0.0.1", | ||||
| @@ -30,11 +30,11 @@ module.exports = { | ||||
|         }; | ||||
|         if (project.files) { | ||||
|             if (project.files.flow) { | ||||
|                 package['node-red'].settings.flowFile = project.files.flow; | ||||
|                 package['node-red'].settings.credentialsFile = project.files.credentials; | ||||
|                 packageDetails['node-red'].settings.flowFile = project.files.flow; | ||||
|                 packageDetails['node-red'].settings.credentialsFile = project.files.credentials; | ||||
|             } | ||||
|         } | ||||
|         return JSON.stringify(package,"",4); | ||||
|         return JSON.stringify(packageDetails,"",4); | ||||
|     }, | ||||
|     "README.md": function(project) { | ||||
|         var content = project.name+"\n"+("=".repeat(project.name.length))+"\n\n"; | ||||
|   | ||||
| @@ -71,6 +71,8 @@ function runGitCommand(args,cwd,env,emit) { | ||||
|             err.code = "git_missing_user"; | ||||
|         } else if (/name consists only of disallowed characters/i.test(stderr)) { | ||||
|             err.code = "git_missing_user"; | ||||
|         } else if (/nothing (add )?to commit/i.test(stdout)) { | ||||
|             return stdout; | ||||
|         } | ||||
|         throw err; | ||||
|     }) | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
|         "errors-help": "詳細は -v を指定して実行してください", | ||||
|         "missing-modules": "不足しているノードモジュール:", | ||||
|         "node-version-mismatch": "ノードモジュールはこのバージョンではロードできません。必要なバージョン: __version__ ", | ||||
|         "set-has-no-types": "セットに型がありません。 名前: '__name__', モジュール: '__module__', ファイル: '__file__'", | ||||
|         "type-already-registered": "'__type__' はモジュール __module__ で登録済みです", | ||||
|         "removing-modules": "設定からモジュールを削除します", | ||||
|         "added-types": "追加したノード:", | ||||
| @@ -134,7 +135,8 @@ | ||||
|         "flow": { | ||||
|             "unknown-type": "不明なノード: __type__", | ||||
|             "missing-types": "欠落したノード", | ||||
|             "error-loop": "メッセージの例外補足回数が最大値を超えました" | ||||
|             "error-loop": "メッセージの例外補足回数が最大値を超えました", | ||||
|             "non-message-returned": "ノードが __type__ 型のメッセージの送信を試みました" | ||||
|         }, | ||||
|         "index": { | ||||
|             "unrecognised-id": "不明なID: __id__", | ||||
|   | ||||
							
								
								
									
										28
									
								
								packages/node_modules/node-red/settings.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								packages/node_modules/node-red/settings.js
									
									
									
									
										vendored
									
									
								
							| @@ -181,7 +181,7 @@ module.exports = { | ||||
|  | ||||
|     /** Some nodes, such as HTTP In, can be used to listen for incoming http requests. | ||||
|      * By default, these are served relative to '/'. The following property | ||||
|      * can be used to specifiy a different root path. If set to false, this is | ||||
|      * can be used to specify a different root path. If set to false, this is | ||||
|      * disabled. | ||||
|      */ | ||||
|     //httpNodeRoot: '/red-nodes', | ||||
| @@ -219,17 +219,17 @@ module.exports = { | ||||
|     /** When httpAdminRoot is used to move the UI to a different root path, the | ||||
|      * following property can be used to identify a directory of static content | ||||
|      * that should be served at http://localhost:1880/. | ||||
|      * When httpStaticRoot is set differently to httpAdminRoot, there is no need  | ||||
|      * When httpStaticRoot is set differently to httpAdminRoot, there is no need | ||||
|      * to move httpAdminRoot | ||||
|      */ | ||||
|     //httpStatic: '/home/nol/node-red-static/', //single static source | ||||
|     /* OR multiple static sources can be created using an array of objects... */ | ||||
|     //httpStatic: [ | ||||
|     //    {path: '/home/nol/pics/',    root: "/img/"},  | ||||
|     //    {path: '/home/nol/reports/', root: "/doc/"},  | ||||
|     //    {path: '/home/nol/pics/',    root: "/img/"}, | ||||
|     //    {path: '/home/nol/reports/', root: "/doc/"}, | ||||
|     //], | ||||
|  | ||||
|     /**   | ||||
|     /** | ||||
|      * All static routes will be appended to httpStaticRoot | ||||
|      * e.g. if httpStatic = "/home/nol/docs" and  httpStaticRoot = "/static/" | ||||
|      *      then "/home/nol/docs" will be served at "/static/" | ||||
| @@ -256,11 +256,11 @@ module.exports = { | ||||
|      */ | ||||
|     // lang: "de", | ||||
|  | ||||
|     /** Configure diagnostics options  | ||||
|     /** Configure diagnostics options | ||||
|      * - enabled:  When `enabled` is `true` (or unset), diagnostics data will | ||||
|      *   be available at http://localhost:1880/diagnostics   | ||||
|      * - ui: When `ui` is `true` (or unset), the action `show-system-info` will  | ||||
|      *   be available to logged in users of node-red editor   | ||||
|      *   be available at http://localhost:1880/diagnostics | ||||
|      * - ui: When `ui` is `true` (or unset), the action `show-system-info` will | ||||
|      *   be available to logged in users of node-red editor | ||||
|     */ | ||||
|     diagnostics: { | ||||
|         /** enable or disable diagnostics endpoint. Must be set to `false` to disable */ | ||||
| @@ -268,10 +268,10 @@ module.exports = { | ||||
|         /** enable or disable diagnostics display in the node-red editor. Must be set to `false` to disable */ | ||||
|         ui: true, | ||||
|     }, | ||||
|     /** Configure runtimeState options  | ||||
|      * - enabled:  When `enabled` is `true` flows runtime can be Started/Stoped  | ||||
|      *   by POSTing to available at http://localhost:1880/flows/state   | ||||
|      * - ui: When `ui` is `true`, the action `core:start-flows` and  | ||||
|     /** Configure runtimeState options | ||||
|      * - enabled:  When `enabled` is `true` flows runtime can be Started/Stopped | ||||
|      *   by POSTing to available at http://localhost:1880/flows/state | ||||
|      * - ui: When `ui` is `true`, the action `core:start-flows` and | ||||
|      *   `core:stop-flows` will be available to logged in users of node-red editor | ||||
|      *   Also, the deploy menu (when set to default) will show a stop or start button | ||||
|      */ | ||||
| @@ -519,7 +519,7 @@ module.exports = { | ||||
|      */ | ||||
|     //tlsConfigDisableLocalFiles: true, | ||||
|  | ||||
|     /** The following property can be used to verify websocket connection attempts. | ||||
|     /** The following property can be used to verify WebSocket connection attempts. | ||||
|      * This allows, for example, the HTTP request headers to be checked to ensure | ||||
|      * they include valid authentication information. | ||||
|      */ | ||||
|   | ||||
| @@ -2334,4 +2334,38 @@ describe('HTTP Request Node', function() { | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     describe('multipart form posts', function() { | ||||
|         it('should send arrays as multiple entries', function (done) { | ||||
|             const flow = [ | ||||
|                 { | ||||
|                     id: 'n1', type: 'http request', wires: [['n2']], method: 'POST', ret: 'obj', url: getTestURL('/file-upload'), headers: [ | ||||
|                     ] | ||||
|                 }, | ||||
|                 { id: "n2", type: "helper" } | ||||
|             ]; | ||||
|             helper.load(httpRequestNode, flow, function() { | ||||
|                 var n1 = helper.getNode("n1"); | ||||
|                 var n2 = helper.getNode("n2"); | ||||
|                 n2.on('input', function(msg){ | ||||
|                     try { | ||||
|                         msg.payload.body.should.have.property('foo') | ||||
|                         msg.payload.body.list.should.deepEqual(['a','b','c']) | ||||
|                         done() | ||||
|                     } catch (e) { | ||||
|                         done(e) | ||||
|                     } | ||||
|                 }); | ||||
|                 n1.receive({ | ||||
|                     headers: { | ||||
|                         'content-type': 'multipart/form-data' | ||||
|                     }, | ||||
|                     payload: { | ||||
|                         foo: 'bar', | ||||
|                         list: [ 'a', 'b', 'c' ] | ||||
|                     } | ||||
|                 }); | ||||
|             }) | ||||
|         }); | ||||
|     }) | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user