mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Added YAML parser node (#1034)
Thanks @natcl - (sorry pressed closed by mistake !) * Added YAML parser node * Added YAML error strings in messages.json * Change location of YAML library import * Remove copyright * Remove copyright * Change order of yaml in Template node * Add YAML test * Add working test
This commit is contained in:
		
				
					committed by
					
						 Dave Conway-Jones
						Dave Conway-Jones
					
				
			
			
				
	
			
			
			
						parent
						
							b1ab26e3ad
						
					
				
				
					commit
					9bbc8eda9d
				
			
							
								
								
									
										
											BIN
										
									
								
								editor/icons/parser-yaml.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								editor/icons/parser-yaml.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 423 B | 
| @@ -37,6 +37,7 @@ | ||||
|                 <option value="css">CSS</option> | ||||
|                 <option value="markdown">Markdown</option> | ||||
|                 <option value="text">none</option> | ||||
|                 <option value="yaml">YAML</option> | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -614,6 +614,13 @@ | ||||
|             "dropped-error": "Failed to convert payload" | ||||
|         } | ||||
|     }, | ||||
|     "yaml": { | ||||
|         "errors": { | ||||
|             "dropped-object": "Ignored non-object payload", | ||||
|             "dropped": "Ignored unsupported payload type", | ||||
|             "dropped-error": "Failed to convert payload" | ||||
|         } | ||||
|     }, | ||||
|     "xml": { | ||||
|         "label": { | ||||
|             "represent": "Represent XML tag attributes as a property named", | ||||
|   | ||||
							
								
								
									
										31
									
								
								nodes/core/parsers/70-YAML.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								nodes/core/parsers/70-YAML.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| <script type="text/x-red" data-template-name="yaml"> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> | ||||
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> | ||||
|     </div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="yaml"> | ||||
|     <p>A function that parses the <code>msg.payload</code> to convert a YAML string to/from a javascript object. Places the result back into the payload.</p> | ||||
|     <p>If the input is a YAML string it tries to parse it to a javascript object.</p> | ||||
|     <p>If the input is a javascript object it creates a YAML string.</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     RED.nodes.registerType('yaml',{ | ||||
|         category: 'function', | ||||
|         color:"#DEBD5C", | ||||
|         defaults: { | ||||
|             name: {value:""} | ||||
|         }, | ||||
|         inputs:1, | ||||
|         outputs:1, | ||||
|         icon: "parser-yaml.png", | ||||
|         label: function() { | ||||
|             return this.name||"yaml"; | ||||
|         }, | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         } | ||||
|     }); | ||||
| </script> | ||||
							
								
								
									
										34
									
								
								nodes/core/parsers/70-YAML.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								nodes/core/parsers/70-YAML.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| module.exports = function(RED) { | ||||
|     "use strict"; | ||||
|     var yaml = require('js-yaml'); | ||||
|     function YAMLNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         var node = this; | ||||
|         this.on("input", function(msg) { | ||||
|             if (msg.hasOwnProperty("payload")) { | ||||
|                 if (typeof msg.payload === "string") { | ||||
|                     try { | ||||
|                         msg.payload = yaml.load(msg.payload); | ||||
|                         node.send(msg); | ||||
|                     } | ||||
|                     catch(e) { node.error(e.message,msg); } | ||||
|                 } | ||||
|                 else if (typeof msg.payload === "object") { | ||||
|                     if (!Buffer.isBuffer(msg.payload)) { | ||||
|                         try { | ||||
|                             msg.payload = yaml.dump(msg.payload); | ||||
|                             node.send(msg); | ||||
|                         } | ||||
|                         catch(e) { | ||||
|                             node.error(RED._("yaml.errors.dropped-error")); | ||||
|                         } | ||||
|                     } | ||||
|                     else { node.warn(RED._("yaml.errors.dropped-object")); } | ||||
|                 } | ||||
|                 else { node.warn(RED._("yaml.errors.dropped")); } | ||||
|             } | ||||
|             else { node.send(msg); } // If no payload - just pass it on. | ||||
|         }); | ||||
|     } | ||||
|     RED.nodes.registerType("yaml",YAMLNode); | ||||
| }; | ||||
| @@ -40,6 +40,7 @@ | ||||
|         "fs.notify":"0.0.4", | ||||
|         "i18next":"1.10.6", | ||||
|         "is-utf8":"0.2.1", | ||||
|         "js-yaml": "3.6.1", | ||||
|         "media-typer": "0.3.0", | ||||
|         "mqtt": "1.14.1", | ||||
|         "mustache": "2.2.1", | ||||
|   | ||||
							
								
								
									
										156
									
								
								test/nodes/core/parsers/70-YAML_spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								test/nodes/core/parsers/70-YAML_spec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| /** | ||||
|  * Copyright 2014 IBM Corp. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| var should = require("should"); | ||||
| var yamlNode = require("../../../../nodes/core/parsers/70-YAML.js"); | ||||
| var helper = require("../../helper.js"); | ||||
|  | ||||
| describe('YAML node', function() { | ||||
|  | ||||
|     before(function(done) { | ||||
|         helper.startServer(done); | ||||
|     }); | ||||
|  | ||||
|     afterEach(function() { | ||||
|         helper.unload(); | ||||
|     }); | ||||
|  | ||||
|     it('should be loaded', function(done) { | ||||
|         var flow = [{id:"yamlNode1", type:"yaml", name: "yamlNode" }]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yamlNode1 = helper.getNode("yamlNode1"); | ||||
|             yamlNode1.should.have.property('name', 'yamlNode'); | ||||
|             done(); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should convert a valid yaml string to a javascript object', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yn1 = helper.getNode("yn1"); | ||||
|             var yn2 = helper.getNode("yn2"); | ||||
|             yn2.on("input", function(msg) { | ||||
|                 console.log('msg', msg); | ||||
|                 console.log('payload', msg.payload.employees[0]); | ||||
|                 msg.should.have.property('topic', 'bar'); | ||||
|                 msg.payload.should.have.property('employees'); | ||||
|                 msg.payload.employees[0].should.have.property('firstName', 'John'); | ||||
|                 msg.payload.employees[0].should.have.property('lastName', 'Smith'); | ||||
|                 done(); | ||||
|             }); | ||||
|             var yamlString = "employees:\n  - firstName: John\n    lastName: Smith\n"; | ||||
|             yn1.receive({payload:yamlString,topic: "bar"}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should convert a javascript object to a yaml string', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yn1 = helper.getNode("yn1"); | ||||
|             var yn2 = helper.getNode("yn2"); | ||||
|             yn2.on("input", function(msg) { | ||||
|                 should.equal(msg.payload, "employees:\n  - firstName: John\n    lastName: Smith\n"); | ||||
|                 done(); | ||||
|             }); | ||||
|             var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; | ||||
|             yn1.receive({payload:obj}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should convert an array to a yaml string', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yn1 = helper.getNode("yn1"); | ||||
|             var yn2 = helper.getNode("yn2"); | ||||
|             yn2.on("input", function(msg) { | ||||
|                 should.equal(msg.payload, "- 1\n- 2\n- 3\n"); | ||||
|                 done(); | ||||
|             }); | ||||
|             var obj = [1,2,3]; | ||||
|             yn1.receive({payload:obj}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should log an error if asked to parse an invalid yaml string', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             try { | ||||
|                 var yn1 = helper.getNode("yn1"); | ||||
|                 var yn2 = helper.getNode("yn2"); | ||||
|                 yn1.receive({payload:'employees:\n-firstName: John\n- lastName: Smith\n',topic: "bar"}); | ||||
|                 var logEvents = helper.log().args.filter(function(evt) { | ||||
|                     return evt[0].type == "yaml"; | ||||
|                 }); | ||||
|                 logEvents.should.have.length(1); | ||||
|                 logEvents[0][0].should.have.a.property('msg'); | ||||
|                 logEvents[0][0].msg.should.startWith("end of the stream"); | ||||
|                 logEvents[0][0].should.have.a.property('level',helper.log().ERROR); | ||||
|                 done(); | ||||
|             } catch(err) { | ||||
|                 done(err); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should log an error if asked to parse something thats not yaml or js', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yn1 = helper.getNode("yn1"); | ||||
|             var yn2 = helper.getNode("yn2"); | ||||
|             setTimeout(function() { | ||||
|                 try { | ||||
|                     var logEvents = helper.log().args.filter(function(evt) { | ||||
|                         return evt[0].type == "yaml"; | ||||
|                     }); | ||||
|                     logEvents.should.have.length(3); | ||||
|                     logEvents[0][0].should.have.a.property('msg'); | ||||
|                     logEvents[0][0].msg.toString().should.eql('yaml.errors.dropped'); | ||||
|                     logEvents[1][0].should.have.a.property('msg'); | ||||
|                     logEvents[1][0].msg.toString().should.eql('yaml.errors.dropped'); | ||||
|                     logEvents[2][0].should.have.a.property('msg'); | ||||
|                     logEvents[2][0].msg.toString().should.eql('yaml.errors.dropped-object'); | ||||
|                     done(); | ||||
|                 } catch(err) { | ||||
|                     done(err); | ||||
|                 } | ||||
|             },150); | ||||
|             yn1.receive({payload:true}); | ||||
|             yn1.receive({payload:1}); | ||||
|             yn1.receive({payload:new Buffer("a")}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should pass straight through if no payload set', function(done) { | ||||
|         var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, | ||||
|                     {id:"yn2", type:"helper"}]; | ||||
|         helper.load(yamlNode, flow, function() { | ||||
|             var yn1 = helper.getNode("yn1"); | ||||
|             var yn2 = helper.getNode("yn2"); | ||||
|             yn2.on("input", function(msg) { | ||||
|                 msg.should.have.property('topic', 'bar'); | ||||
|                 msg.should.not.have.property('payload'); | ||||
|                 done(); | ||||
|             }); | ||||
|             yn1.receive({topic: "bar"}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user