Socket
Socket
Sign inDemoInstall

jstoxml

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jstoxml - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

2

dist/jstoxml-min.js

@@ -1,1 +0,1 @@

!function(e,n){if("function"==typeof define&&define.amd)define(["exports"],n);else if("undefined"!=typeof exports)n(exports);else{var t={exports:{}};n(t.exports),e.jstoxml=t.exports}}(this,function(e){"use strict";function n(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=["_selfCloseTag","_attrs"],o=r.join("|"),a=new RegExp(o,"g"),i=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.repeat(n)},c=function(e){return Array.isArray(e)?"array":"object"===(void 0===e?"undefined":t(e))&&null!==e&&e._name?"special-object":e instanceof Date?"date":null===e?"null":void 0===e?"undefined":t(e)},s=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Array.isArray(e)?e.map(function(e){var n=Object.keys(e)[0],t=e[n];return""+n+(!0===t?"":'="'+t+'"')}):Object.keys(e).map(function(n){return""+n+(!0===e[n]?"":'="'+e[n]+'"')})},u=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=s(e);return 0===n.length?"":" "+n.join(" ")},f=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t="("+Object.keys(n).join("|")+")",r=new RegExp(t,"g");return String(e).replace(r,function(e,t){return n[t]||""})},l=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Object.keys(e).map(function(n){return{_name:n,_content:e[n]}})},d=function(e){var n=c(e);return"string"===n||"number"===n||"boolean"===n||"date"===n||"special-object"===n},b=function(e){return!e.match("<")},v=function(e,n,t){var r="";return e.header&&t&&(r="boolean"==typeof e.header?'<?xml version="1.0" encoding="UTF-8"?>':e.header,e.indent&&(r+="\n")),r};e.toXML=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=o.depth?o.depth:0,y=i(o.indent,s),p=c(t),g=d(t),m=0===s&&(g||!g&&o._isFirstItem),h="";switch(p){case"special-object":var _=t._name,j=t._content;if(null===j){h=_;break}if(_.match(a))break;var k=Object.assign({},o,{depth:s+1}),O=e(j,k),x=c(O),A=b(O),S=""+(o.indent&&!m?"\n":"")+y,I="undefined"===x||""===O,F="boolean"==typeof t._selfCloseTag?I&&t._selfCloseTag:I,T=F?"/":"",w="<"+_+u(t._attrs)+T+">",C=o.indent&&!A?"\n"+y:"";h=""+S+w+(F?"":""+O+C+"</"+_+">");break;case"object":var E=Object.keys(t);h=E.map(function(a,i){var s=Object.assign({},o,{_isFirstItem:0===i,_isLastItem:i+1===E.length}),u={_name:a};if("object"===c(t[a])&&(r.forEach(function(e){var n=t[a][e];void 0!==n&&(u[e]=n,delete t[a][e])}),void 0!==t[a]._content&&Object.keys(t[a]).length>1)){var f=Object.assign({},t[a]);delete f._content,u._content=[].concat(n(l(f)),[t[a]._content])}return void 0===u._content&&(u._content=t[a]),e(u,s)},o).join("");break;case"function":var L=t(o);h=e(L,o);break;case"array":h=t.map(function(n,r){var a=Object.assign({},o,{_isFirstItem:0===r,_isLastItem:r+1===t.length});return e(n,a)}).join("");break;case"number":case"string":case"boolean":case"date":case"null":default:h=f(t,o.filter)}return h=""+v(o,0,m)+h}});
!function(e,t){if("function"==typeof define&&define.amd)define(["exports"],t);else if("undefined"!=typeof exports)t(exports);else{var n={exports:{}};t(n.exports),e.jstoxml=n.exports}}(this,function(e){"use strict";function t(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=["_selfCloseTag","_attrs"],o=r.join("|"),a=new RegExp(o,"g"),i=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.repeat(t)},c=function(e){return Array.isArray(e)?"array":"object"===(void 0===e?"undefined":n(e))&&null!==e&&e._name?"special-object":e instanceof Date?"date":null===e?"null":void 0===e?"undefined":n(e)},s=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1];return Array.isArray(e)?e.map(function(e){var n=Object.keys(e)[0],r=e[n],o=t?f(r,t):r;return""+n+(!0===o?"":'="'+o+'"')}):Object.keys(e).map(function(n){var r=t?f(e[n],t):e[n];return""+n+(!0===e[n]?"":'="'+r+'"')})},u=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1],n=s(e,t);return 0===n.length?"":" "+n.join(" ")},f=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n="("+Object.keys(t).join("|")+")",r=new RegExp(n,"g");return String(e).replace(r,function(e,n){return t[n]||""})},l=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Object.keys(e).map(function(t){return{_name:t,_content:e[t]}})},d=function(e){var t=c(e);return"string"===t||"number"===t||"boolean"===t||"date"===t||"special-object"===t},b=function(e){return!e.match("<")},v=function(e,t,n){var r="";return e.header&&n&&(r="boolean"==typeof e.header?'<?xml version="1.0" encoding="UTF-8"?>':e.header,e.indent&&(r+="\n")),r};e.toXML=function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=o.depth?o.depth:0,y=i(o.indent,s),p=c(n),g=d(n),m=0===s&&(g||!g&&o._isFirstItem),h="";switch(p){case"special-object":var _=n._name,j=n._content;if(null===j){h=_;break}if(_.match(a))break;var k=Object.assign({},o,{depth:s+1}),O=e(j,k),x=c(O),A=b(O),S=""+(o.indent&&!m?"\n":"")+y,F="undefined"===x||""===O,I="boolean"==typeof n._selfCloseTag?F&&n._selfCloseTag:F,T=I?"/":"",w="<"+_+u(n._attrs,o.attributesFilter)+T+">",C=o.indent&&!A?"\n"+y:"";h=""+S+w+(I?"":""+O+C+"</"+_+">");break;case"object":var E=Object.keys(n);h=E.map(function(a,i){var s=Object.assign({},o,{_isFirstItem:0===i,_isLastItem:i+1===E.length}),u={_name:a};if("object"===c(n[a])&&(r.forEach(function(e){var t=n[a][e];void 0!==t&&(u[e]=t,delete n[a][e])}),void 0!==n[a]._content&&Object.keys(n[a]).length>1)){var f=Object.assign({},n[a]);delete f._content,u._content=[].concat(t(l(f)),[n[a]._content])}return void 0===u._content&&(u._content=n[a]),e(u,s)},o).join("");break;case"function":var L=n(o);h=e(L,o);break;case"array":h=n.map(function(t,r){var a=Object.assign({},o,{_isFirstItem:0===r,_isLastItem:r+1===n.length});return e(t,a)}).join("");break;case"number":case"string":case"boolean":case"date":case"null":default:h=f(n,o.filter)}return h=""+v(o,0,m)+h}});

@@ -80,2 +80,3 @@ (function (global, factory) {

var attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var filter = arguments[1];

@@ -91,3 +92,4 @@ var isArray = Array.isArray(attributes);

var valStr = val === true ? '' : '="' + val + '"';
var filteredVal = filter ? filterStr(val, filter) : val;
var valStr = filteredVal === true ? '' : '="' + filteredVal + '"';
return '' + key + valStr;

@@ -101,3 +103,4 @@ });

// For boolean true, simply output the key.
var valStr = attributes[key] === true ? '' : '="' + attributes[key] + '"';
var filteredVal = filter ? filterStr(attributes[key], filter) : attributes[key];
var valStr = attributes[key] === true ? '' : '="' + filteredVal + '"';

@@ -119,4 +122,5 @@ return '' + key + valStr;

var attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var filter = arguments[1];
var keyVals = getAttributeKeyVals(attributes);
var keyVals = getAttributeKeyVals(attributes, filter);
if (keyVals.length === 0) return '';

@@ -259,3 +263,3 @@

var selfCloseStr = shouldSelfClose ? '/' : '';
var attributesString = formatAttributes(obj._attrs);
var attributesString = formatAttributes(obj._attrs, config.attributesFilter);
var tag = '<' + _name + attributesString + selfCloseStr + '>';

@@ -262,0 +266,0 @@

@@ -32,2 +32,16 @@ const privateVars = ['_selfCloseTag', '_attrs'];

/**
* Replaces matching values in a string with a new value.
* Example:
* filterStr('foo&bar', { '&': '&amp;' });
*/
const filterStr = (inputStr = '', filter = {}) => {
const searches = Object.keys(filter);
const joinedSearches = searches.join('|');
const regexpStr = `(${joinedSearches})`;
const regexp = new RegExp(regexpStr, 'g');
return String(inputStr).replace(regexp, (str, entity) => filter[entity] || '');
};
/**
* Maps an object or array of arribute keyval pairs to a string.

@@ -38,3 +52,3 @@ * Examples:

*/
const getAttributeKeyVals = (attributes = {}) => {
const getAttributeKeyVals = (attributes = {}, filter) => {
const isArray = Array.isArray(attributes);

@@ -49,3 +63,4 @@

const valStr = (val === true) ? '' : `="${val}"`;
const filteredVal = (filter) ? filterStr(val, filter) : val;
const valStr = (filteredVal === true) ? '' : `="${filteredVal}"`;
return `${key}${valStr}`;

@@ -59,3 +74,4 @@ });

// For boolean true, simply output the key.
const valStr = (attributes[key] === true) ? '' : `="${attributes[key]}"`;
const filteredVal = (filter) ? filterStr(attributes[key], filter) : attributes[key];
const valStr = (attributes[key] === true) ? '' : `="${filteredVal}"`;

@@ -75,4 +91,4 @@ return `${key}${valStr}`;

*/
const formatAttributes = (attributes = {}) => {
const keyVals = getAttributeKeyVals(attributes);
const formatAttributes = (attributes = {}, filter) => {
const keyVals = getAttributeKeyVals(attributes, filter);
if (keyVals.length === 0) return '';

@@ -85,16 +101,2 @@

/**
* Replaces matching values in a string with a new value.
* Example:
* filterStr('foo&bar', { '&': '&amp;' });
*/
const filterStr = (inputStr = '', filter = {}) => {
const searches = Object.keys(filter);
const joinedSearches = searches.join('|');
const regexpStr = `(${joinedSearches})`;
const regexp = new RegExp(regexpStr, 'g');
return String(inputStr).replace(regexp, (str, entity) => filter[entity] || '');
};
/**
* Converts an object to a jstoxml array.

@@ -201,3 +203,3 @@ * Example:

const selfCloseStr = (shouldSelfClose) ? '/' : '';
const attributesString = formatAttributes(obj._attrs);
const attributesString = formatAttributes(obj._attrs, config.attributesFilter);
const tag = `<${_name}${attributesString}${selfCloseStr}>`;

@@ -204,0 +206,0 @@

{
"name": "jstoxml",
"version": "1.0.0",
"version": "1.1.0",
"description": "Converts JavaScript/JSON to XML (for RSS, Podcasts, AMP, etc.)",

@@ -22,4 +22,3 @@ "homepage": "http://github.com/davidcalhoun/jstoxml",

"postinstall": "./install.sh",
"test": "./node_modules/mocha/bin/mocha test.js",
"test-dist": "./node_modules/mocha/bin/mocha dist/jstoxml.js"
"test": "./install.sh && ./node_modules/mocha/bin/mocha test.js"
},

@@ -26,0 +25,0 @@ "dependencies": {},

@@ -12,7 +12,2 @@ jstoxml

### Features
* supports a variety of inputs: objects, arrays, strings,
* tabbed output (optional)
* custom filters (```&``` -> ```&amp;```, etc) (optional)
### Installation

@@ -22,36 +17,9 @@ * npm install jstoxml

### Version 1.0.0
-Complete rewrite! The code should now be easier to understand and maintain.
-now supports emoji/UTF8 tag attributes (needed for AMP pages - e.g. `<html ⚡ lang="en">`) (see example 14)
-now supports duplicate attribute key names (see example 15)
-Fixed: functions returning objects now have now that output passed through toXML for XML conversion
-Fixed: empty text strings now properly output self-closing tags
-Migrated tests to mocha
* Complete rewrite! The code should now be easier to understand and maintain.
* now supports emoji/UTF8 tag attributes (needed for AMP pages - e.g. `<html ⚡ lang="en">`) (see example 14)
* now supports duplicate attribute key names (see example 15)
* Fixed: functions returning objects now have now that output passed through toXML for XML conversion
* Fixed: empty text strings now properly output self-closing tags
* Migrated tests to mocha
### Version 0.2.1
* IMPORTANT: empty text strings will now output as empty XML tags (NOT text content), which makes more sense and is more intuitive (see issue #3). To output text content, set the value to null instead (see Example 5 below).
For instance:
```
jstoxml.toXML({
a: '1',
foo: '',
b: '2'
});
// Output: <a>1</a><foo></foo><b>2</b>
```
```
jstoxml.toXML({
a: '1',
foo: null,
b: '2'
});
// Output: <a>1</a>foo<b>2</b>
```
### Version 0.1.0
* Added support for custom filters (for XML, UTF-8 entities, or whatever you need it for)
* Changed to a single options object, passed as the second parameter. This will break older versions that use the XML header or indentation! They will need to be updated (see the examples below).
### Examples

@@ -64,10 +32,2 @@ First you'll want to require jstoxml in your script, and assign the result to the namespace variable you want to use (in this case jstoxml):

#### Interface
jstoxml has a very simple interface: jstoxml.toXML(input, addHeader [Boolean or String], indent [String]);
* input: accepts objects, arrays, strings, and even functions
* addHeader (optional): pass in true to include the default XML header (&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;). For a custom XML header, pass in a string.
* indent (optional): string which is used as an indent (i.e. ' ')
#### Example 1: Simple object

@@ -479,3 +439,27 @@ ```javascript

#### Example 11b: Custom filter for XML attributes
```javascript
jstoxml.toXML({
_name: 'foo',
_attrs: { a: '<"\'&"foo>' }
},
{
attributesFilter: {
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&apos;',
'&': '&amp;'
}
});
```
Output:
```
<foo a="&lt;&quot;&apos;&amp;&quot;foo&gt;"/>
```
#### Example 12: Avoiding self-closing tags

@@ -548,3 +532,3 @@ If for some reason you want to avoid self-closing tags, you can pass in a special config option `_selfCloseTag`:

```
<html lang="sen" lang="klingon"/>
<html lang="en" lang="klingon"/>
```

@@ -551,0 +535,0 @@

@@ -403,3 +403,3 @@ const jstoxml = require('./dist/jstoxml');

describe('filtering', () => {
it('entities', () => {
it('values', () => {
const val = {

@@ -424,2 +424,21 @@ foo: '<a>',

});
it('attributes', () => {
const val = {
_name: 'foo',
_attrs: { a: '<"\'&"foo>' }
};
const config = {
attributesFilter: {
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&apos;',
'&': '&amp;'
}
};
const result = jstoxml.toXML(val, config);
const expectedResult = '<foo a="&lt;&quot;&apos;&amp;&quot;foo&gt;"/>';
assert.equal(result, expectedResult);
});
});

@@ -842,2 +861,26 @@

it('11b attributes filter', () => {
const val = {
_name: 'foo',
_content: 'bar',
_attrs: {
a: 'http://example.com/?test=\'1\'&foo=<bar>&whee="sha"',
b: 'http://example2.com/?test=\'2\'&md=<5>&sum="sha"'
}
};
const config = {
attributesFilter: {
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&apos;',
'&': '&amp;'
}
};
const result = jstoxml.toXML(val, config);
const expectedResult =
'<foo a="http://example.com/?test=&apos;1&apos;&amp;foo=&lt;bar&gt;&amp;whee=&quot;sha&quot;" b="http://example2.com/?test=&apos;2&apos;&amp;md=&lt;5&gt;&amp;sum=&quot;sha&quot;">bar</foo>';
assert.equal(result, expectedResult);
});
it('12 avoiding self closing tags', () => {

@@ -844,0 +887,0 @@ const val = [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc