Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

utilities

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

utilities - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

test/array.js

55

lib/array.js
/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -21,21 +21,52 @@ *

/*
* humanize(array<Array>)
*
* Humanize returns a string of the array items in a
* readable format
*
* Examples:
* humanize(["array", "array", "array"])
* => "array, array and array"
*
* humanize(["array", "array"])
* => "array and array"
*
* humanize(["array"])
* => "array"
*/
this.humanize = function(array) {
// Return an array in a readable form, useful for outputting lists of items
// If array only has one item then just return it
if(array.length <= 1) {
return String(array);
}
var last = array.pop();
array = array.join(', ');
return array + ' and ' + last;
var last = array.pop()
, items = array.join(', ');
return items + ' and ' + last;
};
/*
* included(item<Any>, array<Array>)
*
* Included checks if an `item` is included in a `array`
* if it is found then the `array` is returned, otherwise
* false is returned
*
* Examples:
* included("array", ["array"])
* => ["array"]
*
* included("nope", ["array"])
* => false
*/
this.included = function(item, array) {
// Check if an `item` is included in an `array`
// If the `item` is found, it'll return and object with the key and value,
// - otherwise return undefined
if(!item) return undefined;
var result = array.indexOf(item);
if(result === -1) {
return undefined;
} else return { key: result, value: array[result] };
return false;
} else {
return array;
}
};

@@ -42,0 +73,0 @@

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -19,5 +19,9 @@ *

var date = new (function () {
var _this = this;
var string = require('./string')
, date;
date = new (function () {
var _this = this
, _date = new Date();
var _US_DATE_PAT = /^(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{4})/;

@@ -65,3 +69,3 @@ var _DATETIME_PAT = /^(\d{4})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:T| )?(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?(?: *)?(Z|[+-]\d{4}|[+-]\d{2}:\d{2}|[+-]\d{2})?/;

'A': function (dt) { return _this.weekdayLong[dt.getDay()]; },
// abbreviated month name according to the current locale
// abbreviated month name according to the current locale
'b': function (dt) { return _this.monthShort[dt.getMonth()]; },

@@ -208,9 +212,3 @@ 'h': function (dt) { return _this.strftime(dt, '%b'); },

this.leftPad = function (instr, len, spacer) {
var str = instr.toString();
// spacer char optional, default to space
var sp = spacer ? spacer : ' ';
while (str.length < len) {
str = sp + str;
}
return str;
return string.lpad(instr, spacer, len);
};

@@ -220,9 +218,20 @@

* Calculate the century to which a particular year belongs
* @param y Integer year number
* @param year Integer year number
* @return Integer century number
*/
this.calcCentury = function (y) {
var ret = parseInt(y/100);
ret = ret.toString();
return this.leftPad(ret);
this.calcCentury = function (year) {
if(!year) {
year = _date.getFullYear();
}
var ret = parseInt((year / 100) + 1);
year = year.toString();
// If year ends in 00 subtract one, because it's still the century before the one
// it divides to
if(year.substring(year.length - 2) === '00') {
ret--;
}
return ret.toString();
};

@@ -269,6 +278,8 @@

*/
this.getMeridian = function (h) {
this.getMeridiem = function (h) {
return h > 11 ? this.meridian.PM :
this.meridian.AM;
};
// Compat for mispelled version
this.getMeridian = this.getMeridiem;

@@ -441,10 +452,10 @@ /**

this.diff = function (date1, date2, interv) {
// date1
// Date object or Number equivalent
//
// date2
// Date object or Number equivalent
//
// interval
// A constant representing the interval, e.g. YEAR, MONTH, DAY. See this.dateParts.
// date1
// Date object or Number equivalent
//
// date2
// Date object or Number equivalent
//
// interval
// A constant representing the interval, e.g. YEAR, MONTH, DAY. See this.dateParts.

@@ -679,3 +690,3 @@ // Accept timestamp input

// plain or UTC setters
for (var i = matches.length - 1; i >= 0; i--) {
for (var i = matches.length - 1; i >= 0; i--) {
curr = parseInt(matches[i], 10) || 0;

@@ -682,0 +693,0 @@ dt['set' + prefix + _dateMethods[i]](curr);

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -21,2 +21,8 @@ *

/*
* merge(object, otherObject)
*
* Merge merges `otherObject` into `object` and takes care of deep
* merging of objects
*/
this.merge = function(object, otherObject) {

@@ -35,3 +41,3 @@ // Merges two objects together, then returns the final object

// If value is an object
if(typeof value === 'object' && !value instanceof Array) {
if(typeof value === 'object' && !(value instanceof Array)) {
// Update value of object to the one from otherObject

@@ -48,2 +54,7 @@ object[key] = merge(object[key], value);

/*
* reverseMerge(object<Object>, defaultObject<Object>)
*
* ReverseMerge merges `object` into `defaultObject`
*/
this.reverseMerge = function(object, defaultObject) {

@@ -55,2 +66,7 @@ // Same as `merge` except `defaultObject` is the object being changed

/*
* isEmpty(object<Object>)
*
* IsEmpty returns true if it's empty otherwise false
*/
this.isEmpty = function(object) {

@@ -62,2 +78,12 @@ // Returns true if a object is empty false if not

/*
* toArray(object<Object>)
*
* ToArray takes each key/value in the `object` and puts in array with the value
* as an object with the original key and value
*
* Examples:
* toArray({ex: "json"})
* => [{key: "ex", value: "json"}]
*/
this.toArray = function(object) {

@@ -64,0 +90,0 @@ // Converts an object into an array of objects with the original key, values

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -4,0 +4,0 @@ *

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -23,105 +23,269 @@ *

string = new (function () {
// Regexes used in trimming functions
var _LTR = /^\s+/;
var _RTR = /\s+$/;
var _TR = /^\s+|\s+$/g;
var _NL = /\n|\r|\r\n/g;
// From/to char mappings -- for the XML escape,
// unescape, and test for escapable chars
var _CHARS = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;'
};
var _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
// Builds the escape/unescape methods using a common
// Regexes for trimming, and character maps for escaping
var _LTR = /^\s+/
, _RTR = /\s+$/
, _TR = /^\s+|\s+$/g
, _NL = /\n|\r|\r\n/g
, _CHARS = {
'&': '&amp;'
, '<': '&lt;'
, '>': '&gt;'
, '"': '&quot;'
, '\'': '&#39;'
}
, _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
, _buildEscape
, _buildEscapeTest;
// Builds the escape/unescape methods using a
// map of characters
var _buildEscapes = function (direction) {
return function (str) {
s = str || '';
s = s.toString();
var fr, to;
for (var p in _CHARS) {
fr = direction == 'to' ? p : _CHARS[p];
_buildEscape = function(direction) {
return function(string) {
string = string || '';
string = string.toString();
var from, to, p;
for(p in _CHARS) {
from = direction == 'to' ? p : _CHARS[p];
to = direction == 'to' ? _CHARS[p] : p;
s = s.replace(new RegExp(fr, 'gm'), to);
string = string.replace(new RegExp(from, 'gm'), to);
}
return s;
};
return string;
}
};
// Builds a method that tests for any of the escapable
// characters -- useful for avoiding double-escaping if
// you're not sure whether a string is already escaped
var _buildEscapeTest = function (direction) {
return function (s) {
var pat = '';
for (var p in _CHARS) {
// Builds a method that tests for any escapable
// characters, useful for avoiding double-scaping if
// you're not sure if a string has already been escaped
_buildEscapeTest = function(direction) {
return function(string) {
var pat = ''
, p;
for(p in _CHARS) {
pat += direction == 'to' ? p : _CHARS[p];
pat += '|';
}
pat = pat.substr(0, pat.length - 1);
pat = new RegExp(pat, "gm");
return pat.test(s);
};
return pat.test(string)
}
};
// Escape special chars to entities
this.escapeXML = _buildEscapes('to');
// Escape special XMl chars
this.escapeXML = _buildEscape('to');
// Unescape entities to special chars
this.unescapeXML = _buildEscapes('from');
// Unescape XML chars to literal representation
this.unescapeXML = _buildEscape('from');
// Test if a string includes special chars that
// require escaping
// Test if a string includes special chars
// that need escaping
this.needsEscape = _buildEscapeTest('to');
// Test if a string includes escaped chars
// that need unescaping
this.needsUnescape = _buildEscapeTest('from');
this.toArray = function (str) {
var arr = [];
for (var i = 0; i < str.length; i++) {
arr[i] = str.substr(i, 1);
/*
* toArray(string<String>)
*
* ToArray converts a String to an Array
*
* Examples:
* toArray("geddy")
* => ["g", "e", "d", "d", "y"]
*/
this.toArray = function(string) {
if(!string) {
return;
}
var arr = []
, i = -1;
while(++i < string.length) {
arr.push(string.substr(i, 1));
}
return arr;
};
this.reverse = function (str) {
return this.toArray(str).reverse().join('');
/*
* reverse(string<String>)
*
* Reverse returns a Strings with `string` reversed
*
* Examples:
* reverse("yddeg")
* => "geddy"
*/
this.reverse = function(string) {
if(!string) {
return;
}
return this.toArray(string).reverse().join('');
};
this.ltrim = function (str, chr) {
var pat = chr ? new RegExp('^' + chr + '+') : _LTR;
return str.replace(pat, '');
/*
* ltrim(string<String>, char<String>)
*
* Ltrim trims `char` from the left of a `string` and returns it
* if no `char` is given it will trim spaces
*/
this.ltrim = function(string, char) {
if(!string) {
return;
}
var pat = char ? new RegExp('^' + char + '+') : _LTR;
return string.replace(pat, '');
};
this.rtrim = function (str, chr) {
var pat = chr ? new RegExp(chr + '+$') : _RTR;
return str.replace(pat, '');
/*
* rtrim(string<String>, char<String>)
*
* Rtrim trims `char` from the right of a `string` and returns it
* if no `char` is given it will trim spaces
*/
this.rtrim = function (string, char) {
if(!string) {
return;
}
var pat = char ? new RegExp(char + '+$') : _RTR;
return string.replace(pat, '');
};
this.trim = function (str, chr) {
var pat = chr ? new RegExp('^' + chr + '+|' + chr + '+$', 'g') : _TR;
return str.replace(pat, '');
/*
* trim(string<String>, char<String>)
*
* Trim trims `char` from the right and left of a `string` and returns it
* if no `char` is given it will trim spaces
*/
this.trim = function (string, char) {
if(!string) {
return;
}
var pat = char ? new RegExp('^' + char + '+|' + char + '+$', 'g') : _TR;
return string.replace(pat, '');
};
this.lpad = function (str, chr, width) {
var s = str || ''
, len = s.length;
if (width > len) {
s = (new Array(width - len + 1)).join(chr) + s;
/*
* lpad(string<String>, char<String>, width<Number>)
*
* Lpad adds `char` to the left of `string` until the length
* of `string` is more than `width`
*
* Examples:
* lpad("geddy", "&", 7)
* => "&&geddy"
*/
this.lpad = function(string, char, width) {
if(!string) {
return;
}
// Should width be string.length + 1? or the same to be safe
width = Number(width) || string.length;
char = char || ' ';
var s = string.toString();
while(s.length < width) {
s = char + s;
}
return s;
};
this.rpad = function (str, chr, width) {
var s = str || ''
, len = s.length;
if (width > len) {
s = s + (new Array(width - len + 1)).join(chr);
/*
* rpad(string<String>, char<String>, width<Number>)
*
* Rpad adds `char` to the right of `string` until the length
* of `string` is more than `width`
*
* Examples:
* rpad("geddy", "&", 7)
* => "geddy&&"
*/
this.rpad = function(string, char, width) {
if(!string) {
return;
}
// Should width be string.length + 1? or the same to be safe
width = Number(width) || string.length;
char = char || ' ';
var s = string;
while(s.length < width) {
s += char;
}
return s;
};
/*
* pad(string<String>, char<String>, width<Number>)
*
* Pad adds `char` to the right and left of `string` until the length
* of `string` is more than `width`
*
* Examples:
* pad("geddy", "&", 7)
* => "&geddy&"
*/
this.pad = function(string, char, width) {
if(!string) {
return;
}
// Should width be string.length + 1? or the same to be safe
width = Number(width) || string.length;
char = char || ' ';
var s = string;
while(s.length < width) {
s = char + s + char;
}
return s;
};
/*
* truncate(string<String>, options<Integer/Object>, callback[Function])
*
* Truncates a given `string` after a specified `length` if `string` is longer than
* `length`. The last characters will be replaced with an `omission` for a total length not
* exceeding `length`. If `callback` is given it will fire if `string` is truncated.
*
* Options:
* length <Integer> Length the output string will be(default: 30)
* len <Integer> Alias for length
* omission <String> Replace last letters with an omission(default: '...')
* ellipsis <String> Alias for omission
* seperator <String>/<RegExp> Break the truncated text at the nearest `seperator`
*
* Warnings:
* Please be aware that truncating HTML tags or entities may result in malformed HTML returned
*
* Examples:
* truncate('Once upon a time in a world', { length: 10 })
* => 'Once up...'
*
* truncate('Once upon a time in a world', { length: 20, omission: '...(continued)' })
* => 'Once u...(continued)'
*
* truncate('Once upon a time in a world', { length: 15, seperator: /\s/ })
* => 'Once upon a...'
* Normal Output: => 'Once upon a ...'
*
* truncate('Once upon a time in a world', { length: 15, seperator: ' ' })
* => 'Once upon a...'
* Normal Output: => 'Once upon a ...'
*
* truncate('<p>Once upon a time</p>', { length: 20 })
* => '<p>Once upon a ti...'
*/
this.truncate = function(string, options, callback) {

@@ -208,16 +372,46 @@ if (!string) {

/*
* truncateHTML(string<String>, options<Object>, callback[Function])
*
* Truncates a given `string` inside HTML tags after a specified `length` if string` is longer than
* `length`. The last characters will be replaced with an `omission` for a total length not
* exceeding `length`. If `callback` is given it will fire if `string` is truncated. If `once` is
* true only the first string in the first HTML tags will be truncated leaving the others as they
* were
*
* Options:
* once <Boolean> If true it will only truncate the first text found in the first
* set of HTML tags(default: false)
*
* Notes:
* * All options available in the `truncate` helper are also available in `truncateHTML`
* * HTML tags will not be truncated, so return value will always be safe for rendering
*
* Examples:
* truncateHTML('<p>Once upon a time in a world</p>', { length: 10 })
* => '<p>Once up...</p>'
*
* truncateHTML('<p>Once upon a time <small>in a world</small></p>', { length: 10 })
* => '<p>Once up...<small>in a wo...</small></p>'
*
* truncateHTML('<p>Once upon a time <small>in a world</small></p>', { length: 10, once: true })
* => '<p>Once up...<small>in a world</small></p>'
*/
this.truncateHTML = function(string, options, callback) {
if (!string) return;
var returnString = '';
if(!string) {
return;
}
var returnString = ''
, opts = options;
// If `options` is a number assume it's the length and create a options object with length
if (typeof options === 'number') {
var num = options;
if(typeof opts === 'number') {
var num = opts;
options = {};
options.length = num;
} else options = options || {};
opts = {};
opts.length = num;
} else opts = opts || {};
// Set `default` options for HTML specifics
options.once = options.once || false;
opts.once = opts.once || false;

@@ -230,10 +424,11 @@ var pat = /(<[^>]*>)/ // Patter for matching HTML tags

, firstPos
, lastPos;
, lastPos
, i;
// Gather the HTML tags and content into the array
while (result) {
while(result) {
firstPos = result.index;
lastPos = pat.lastIndex;
if (firstPos !== 0) {
if(firstPos !== 0) {
// Should be content not HTML tags

@@ -251,7 +446,8 @@ arr.push(string.substring(0, firstPos));

}
if (string !== '') arr.push(string);
if(string !== '') arr.push(string);
// Loop through array items appending the tags to the string,
// - and truncating the text then appending it to content
for(var i in arr) {
i = -1;
while(++i < arr.length) {
item = arr[i];

@@ -271,6 +467,6 @@ switch(true) {

default:
if (options.once && truncated) {
if(opts.once && truncated) {
returnString += item;
} else {
returnString += this.truncate(item, options, callback);
returnString += this.truncate(item, opts, callback);
truncated = true;

@@ -285,8 +481,29 @@ }

/*
* nl2br(string<String>)
*
* Nl2br returns a string where all newline chars are turned
* into line break HTML tags
*
* Examples:
* nl2br("geddy\n")
* => "geddy<br />"
*/
this.nl2br = function(string) {
if(!string) {
return;
}
this.nl2br = function (str) {
return str.replace(_NL,'<br />');
return string.replace(_NL,'<br />');
};
// Converts someVariableName to some_variable_name
/*
* snakeize(string<String>)
*
* Snakeize converts camelCase and CamelCase strings to snake_case strings
*
* Examples:
* snakeize("geddyJs")
* => "geddy_js"
*/
this.snakeize = (function () {

@@ -311,3 +528,26 @@ // Only create regexes once on initial load

// Converts some_variable_name to someVariableName or SomeVariableName
/*
* camelize(string<String>, options<Object>)
*
* Camelize takes a string and optional options and
* returns a camelCase version of the given `string`
*
* Options:
* initialCap <Boolean> If initialCap is true the returned
* string will have a capitalized first letter
* leadingUnderscore <Boolean> If leadingUnderscore os true then if
* an underscore exists at the beggining
* of the string, it will stay there.
* Otherwise it'll be removed.
*
* Examples:
* camelize("geddy_js")
* => "geddyJs"
*
* camelize("geddy_js", {initialCap: true})
* => "GeddyJs"
*
* camelize("geddy_js", {leadingUnderscore: true})
* => "_geddyJs"
*/
this.camelize = (function () {

@@ -352,18 +592,67 @@ // Only create regex once on initial load

this.capitalize = function (s) {
return s.substr(0, 1).toUpperCase() + s.substr(1);
/*
* decapitalize(string<String>)
*
* Decapitalize returns the given string with the first letter
* uncapitalized.
*
* Examples:
* decapitalize("String")
* => "string"
*/
this.decapitalize = function (string) {
if(!string) {
return;
}
return string.substr(0, 1).toLowerCase() + string.substr(1);
};
this.decapitalize = function (s) {
return s.substr(0, 1).toLowerCase() + s.substr(1);
/*
* capitalize(string<String>)
*
* Capitalize returns the given string with the first letter
* capitalized.
*
* Examples:
* decapitalize("string")
* => "String"
*/
this.capitalize = function (string) {
if(!string) {
return;
}
return string.substr(0, 1).toUpperCase() + string.substr(1);
};
/*
* dasherize(string<String>, replace<String>)
*
* Dasherize returns the given `string` converting camelCase and snakeCase
* to dashes or replace them with the `replace` character.
*/
this.dasherize = function(s, replace) {
return this.snakeize(s, '-');
var repl = replace || '-'
return this.snakeize(s, repl);
};
/*
* underscorize(string<String>)
*
* Underscorize returns the given `string` converting camelCase and snakeCase
* to underscores.
*/
this.underscorize = function(string) {
if(!string) {
return;
}
return this.dasherize(string, '_');
};
/*
* getInflections(name<String>, initialCap<String>)
*
* Returns an object that contains different inflections
* Inflection returns an object that contains different inflections
* created from the given `name`

@@ -417,15 +706,19 @@ */

// From Math.uuid.js, http://www.broofa.com/Tools/Math.uuid.js
// From Math.uuid.js, https://github.com/broofa/node-uuid
// Robert Kieffer (robert@broofa.com), MIT license
this.uuid = function (len, rad) {
this.uuid = function(length, radix) {
var chars = _UUID_CHARS
, uuid = []
, radix = rad || chars.length
, r;
, r
, i;
if (len) {
radix = radix || chars.length;
if(length) {
// Compact form
for (var i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
}
else {
i = -1;
while(++i < length) {
uuid[i] = chars[0 | Math.random()*radix];
}
} else {
// rfc4122, version 4 form

@@ -439,3 +732,4 @@

// per rfc4122, sec. 4.1.5
for (var i = 0; i < 36; i++) {
i = -1;
while(++i < 36) {
if (!uuid[i]) {

@@ -442,0 +736,0 @@ r = 0 | Math.random()*16;

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -18,3 +18,6 @@ *

*/
var uri = new (function () {
var uri
, string = require('./string');
uri = new (function () {
var _isArray = function (obj) {

@@ -80,3 +83,3 @@ return obj &&

key = opts.snakeize ? geddy.string.snakeize(p) : p;
key = opts.snakeize ? string.snakeize(p) : p;
if (isValid) {

@@ -94,3 +97,3 @@ // Multiple vals -- array

if (opts.escapeVals) {
itemArray[i] = geddy.string.escapeXML(itemArray[i]);
itemArray[i] = string.escapeXML(itemArray[i]);
}

@@ -113,3 +116,3 @@ }

if (opts.escapeVals) {
val = geddy.string.escapeXML(val);
val = string.escapeXML(val);
}

@@ -116,0 +119,0 @@ arr.push(key + '=' + encodeURIComponent(val));

/*
* JSTools JavaScript utilities
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)

@@ -19,200 +19,233 @@ *

var core = require('./core')
, inflection = require('../deps/inflection');
, inflection = require('../deps/inflection')
exports.XML = new (function () {
var indentLevel = 4;
var tagFromType = function (item, prev) {
var ret
, type
, types;
if (item instanceof Array) {
ret = 'array';
// Default indention level
var indentLevel = 4
, tagFromType
, obj2xml;
tagFromType = function(item, prev) {
var ret
, type
, types;
if (item instanceof Array) {
ret = 'array';
} else {
types = ['string', 'number', 'boolean', 'object'];
for (var i = 0, ii = types.length; i < ii; i++) {
type = types[i];
if (typeof item == type) {
ret = type;
}
else {
types = ['string', 'number', 'boolean', 'object'];
for (var i = 0, ii = types.length; i < ii; i++) {
type = types[i];
if (typeof item == type) {
ret = type;
}
}
if (prev && ret != prev) {
return 'record'
} else {
return ret;
}
};
obj2xml = function(o, opts) {
var name = opts.name
, level = opts.level
, arrayRoot = opts.arrayRoot
, pack
, item
, n
, currentIndent = (new Array(level * indentLevel)).join(' ')
, nextIndent = (new Array((level + 1) * indentLevel)).join(' ')
, xml = '';
switch (typeof o) {
case 'string':
case 'number':
case 'boolean':
xml = o.toString();
break;
case 'object':
// Arrays
if (o instanceof Array) {
// Pack the processed version of each item into an array that
// can be turned into a tag-list with a `join` method below
// As the list gets iterated, if all items are the same type,
// that's the tag-name for the individual tags. If the items are
// a mixed, the tag-name is 'record'
pack = [];
for (var i = 0, ii = o.length; i < ii; i++) {
item = o[i];
if (!name) {
// Pass any previous tag-name, so it's possible to know if
// all items are the same type, or it's mixed types
n = tagFromType(item, n);
}
pack.push(obj2xml(item, {
name: name
, level: level + 1
, arrayRoot: arrayRoot
}));
}
}
if (prev && ret != prev) {
return 'record'
}
else {
return ret;
}
}
, obj2xml = function (o, opts) {
var name = opts.name
, level = opts.level
, arrayRoot = opts.arrayRoot
, pack
, item
, n
, currentIndent = (new Array(level * indentLevel)).join(' ')
, nextIndent = (new Array((level + 1) * indentLevel)).join(' ')
, xml = '';
// If this thing is attached to a named property on an object,
// use the name for the containing tag-name
if (name) {
n = name;
}
switch (typeof o) {
case 'string':
case 'number':
case 'boolean':
xml = o.toString();
break;
case 'object':
// Arrays
if (o instanceof Array) {
// If this is a top-level item, wrap in a top-level containing tag
if (level == 0) {
xml += currentIndent + '<' + inflection.pluralize(n) + ' type="array">\n'
}
xml += nextIndent + '<' + n + '>' +
pack.join('</' + n + '>\n' + nextIndent +
'<' + n + '>') + '</' + n + '>\n';
// Pack the processed version of each item into an array that
// can be turned into a tag-list with a `join` method below
// As the list gets iterated, if all items are the same type,
// that's the tag-name for the individual tags. If the items are
// a mixed, the tag-name is 'record'
pack = [];
for (var i = 0, ii = o.length; i < ii; i++) {
item = o[i];
if (!name) {
// Pass any previous tag-name, so it's possible to know if
// all items are the same type, or it's mixed types
n = tagFromType(item, n);
}
pack.push(obj2xml(item, {
name: name
, level: level + 1
, arrayRoot: arrayRoot
}));
}
// If this is a top-level item, close the top-level containing tag
if (level == 0) {
xml += currentIndent + '</' + inflection.pluralize(n) + '>';
}
}
// Generic objects
else {
n = name || 'object';
// If this thing is attached to a named property on an object,
// use the name for the containing tag-name
if (name) {
n = name;
// If this is a top-level item, wrap in a top-level containing tag
if (level == 0) {
xml += currentIndent + '<' + n;
// Lookahead hack to allow tags to have attributes
for (var p in o) {
if (p.indexOf('attr:') == 0) {
xml += ' ' + p.replace(/^attr:/, '') + '="' +
o[p] + '"'
}
}
xml += '>\n';
}
for (var p in o) {
item = o[p];
// If this is a top-level item, wrap in a top-level containing tag
if (level == 0) {
xml += currentIndent + '<' + inflection.pluralize(n) + ' type="array">\n'
}
xml += nextIndent + '<' + n + '>' +
pack.join('</' + n + '>\n' + nextIndent +
'<' + n + '>') + '</' + n + '>\n';
// Data properties only
if (typeof item == 'function') {
continue;
}
// No attr hack properties
if (p.indexOf('attr:') == 0) {
continue;
}
// If this is a top-level item, close the top-level containing tag
if (level == 0) {
xml += currentIndent + '</' + inflection.pluralize(n) + '>';
}
xml += nextIndent;
if (p == '#cdata') {
xml += '<![CDATA[' + item + ']]>\n';
}
// Generic objects
else {
n = name || 'object';
// If this is a top-level item, wrap in a top-level containing tag
if (level == 0) {
xml += currentIndent + '<' + n;
// Lookahead hack to allow tags to have attributes
for (var p in o) {
if (p.indexOf('attr:') == 0) {
xml += ' ' + p.replace(/^attr:/, '') + '="' +
o[p] + '"'
// Complex values, going to have items with multiple tags
// inside
if (typeof item == 'object') {
if (item instanceof Array) {
if (arrayRoot) {
xml += '<' + p + ' type="array">\n'
}
}
xml += '>\n';
}
for (var p in o) {
item = o[p];
// Data properties only
if (typeof item == 'function') {
continue;
}
// No attr hack properties
if (p.indexOf('attr:') == 0) {
continue;
}
xml += nextIndent;
if (p == '#cdata') {
xml += '<![CDATA[' + item + ']]>\n';
}
else {
// Complex values, going to have items with multiple tags
// inside
if (typeof item == 'object') {
if (item instanceof Array) {
if (arrayRoot) {
xml += '<' + p + ' type="array">\n'
}
xml += '<' + p;
// Lookahead hack to allow tags to have attributes
for (var q in item) {
if (q.indexOf('attr:') == 0) {
xml += ' ' + q.replace(/^attr:/, '') + '="' +
item[q] + '"'
}
else {
xml += '<' + p;
// Lookahead hack to allow tags to have attributes
for (var q in item) {
if (q.indexOf('attr:') == 0) {
xml += ' ' + q.replace(/^attr:/, '') + '="' +
item[q] + '"'
}
}
xml += '>\n';
}
}
// Scalars, just a value and closing tag
else {
xml += '<' + p + '>'
}
xml += obj2xml(item, {
name: p
, level: level + 1
, arrayRoot: arrayRoot
});
xml += '>\n';
}
}
// Scalars, just a value and closing tag
else {
xml += '<' + p + '>'
}
xml += obj2xml(item, {
name: p
, level: level + 1
, arrayRoot: arrayRoot
});
// Objects and Arrays, need indentation before closing tag
if (typeof item == 'object') {
if (item instanceof Array) {
if (arrayRoot) {
xml += nextIndent;
xml += '</' + p + '>\n';
}
}
else {
xml += nextIndent;
xml += '</' + p + '>\n';
}
}
// Scalars, just close
else {
// Objects and Arrays, need indentation before closing tag
if (typeof item == 'object') {
if (item instanceof Array) {
if (arrayRoot) {
xml += nextIndent;
xml += '</' + p + '>\n';
}
}
else {
xml += nextIndent;
xml += '</' + p + '>\n';
}
}
// If this is a top-level item, close the top-level containing tag
if (level == 0) {
xml += currentIndent + '</' + n + '>\n';
// Scalars, just close
else {
xml += '</' + p + '>\n';
}
}
break;
default:
// No default
}
// If this is a top-level item, close the top-level containing tag
if (level == 0) {
xml += currentIndent + '</' + n + '>\n';
}
}
return xml;
};
break;
default:
// No default
}
return xml;
}
/*
* XML configuration
*
*/
this.config = {
whitespace: true
, name: null
, fragment: false
, level: 0
, arrayRoot: true
whitespace: true
, name: null
, fragment: false
, level: 0
, arrayRoot: true
};
/*
* setIndentLevel(level<Number>)
*
* SetIndentLevel changes the indent level for XML.stringify and returns it
*
* Example:
* setIndentLevel(5)
* => 5
*/
this.setIndentLevel = function (level) {
indentLevel = level;
if(!level) {
return;
}
return indentLevel = level;
};
this.stringify = function (o, opts) {
/*
* stringify(obj<Any>, opts<Object>)
*
* Stringify returns an XML representation of the given `obj`
*
* Options:
* whitespace <Boolean> Don't insert indents and newlines after xml entities(Default: true)
* name <String> Use custom name as global namespace(Default: type of object)
* fragment <Boolean> If true no header fragment is added to the top(Default: false)
* level <Number> Remove this many levels from the output(Default: 0)
* arrayRoot <Boolean> (Default: true)
*/
this.stringify = function (obj, opts) {
var config = core.mixin({}, this.config)

@@ -230,3 +263,3 @@ , xml = '';

xml += obj2xml(o, {
xml += obj2xml(obj, {
name: config.name

@@ -245,1 +278,2 @@ , level: config.level

})();

@@ -10,3 +10,3 @@ {

],
"version": "0.0.5",
"version": "0.0.6",
"author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",

@@ -13,0 +13,0 @@ "main": "./lib/index.js",

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

/*
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* 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.
*
*/

@@ -2,0 +19,0 @@ var Stream = require('stream').Stream

@@ -0,6 +1,25 @@

/*
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* 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 assert = require('assert')
, fs = require('fs')
, file = require('../lib/file');
, file = require('../lib/file')
, tests;
var tests = {
tests = {

@@ -7,0 +26,0 @@ 'before': function () {

@@ -0,66 +1,254 @@

/*
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* 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 assert = require('assert')
, string = require('../lib/string');
, string = require('../lib/string')
, tests;
tests = {
'test reverse': function () {
var str = 'abcdef'
, actual = string.reverse(str);
assert.equal('fedcba', actual);
'test toArray for string': function() {
var data = string.toArray('geddy')
, actual = ['g', 'e', 'd', 'd', 'y'];
// Loop through each item and check
// if not, then the arrays aren't _really_ the same
var i = actual.length;
while(--i >= 0) {
assert.equal(data[i], actual[i]);
}
}
, 'test ltrim': function () {
var str = ' foo'
, actual = string.ltrim(str);
assert.equal('foo', actual);
, 'test reverse for string': function() {
var data = string.reverse('yddeg')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test rtrim': function () {
var str = 'foo '
, actual = string.rtrim(str);
assert.equal('foo', actual);
, 'test basic ltrim for string': function() {
var data = string.ltrim(' geddy')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test trim': function () {
var str = ' foo '
, actual = string.trim(str);
assert.equal('foo', actual);
, 'test custom char ltrim for string': function() {
var data = string.ltrim('&&geddy', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test lpad': function () {
var str = 'foo'
, actual = string.lpad(str, 'x', 7);
assert.equal('xxxxfoo', actual);
, 'test basic rtrim for string': function() {
var data = string.rtrim('geddy ')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test rpad': function () {
var str = 'foo'
, actual = string.rpad(str, 'x', 7);
assert.equal('fooxxxx', actual);
, 'test custom char rtrim for string': function() {
var data = string.rtrim('geddy&&', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test camelize basic': function () {
var str = 'foo_bar_baz'
, actual = string.camelize(str);
assert.equal('fooBarBaz', actual);
, 'test basic trim for string': function() {
var data = string.trim(' geddy ')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test camelize no initial cap from capitalized snake': function () {
var str = 'Foo_bar_baz'
, actual = string.camelize(str);
assert.equal('fooBarBaz', actual);
, 'test custom char trim for string': function() {
var data = string.trim('&geddy&&', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test camelize initial cap': function () {
var str = 'foo_bar_baz'
, actual = string.camelize(str, {initialCap: true});
assert.equal('FooBarBaz', actual);
, 'test basic lpad for string': function() {
var data = string.lpad('geddy', '&', 7)
, actual = '&&geddy';
assert.equal(data, actual);
}
, 'test camelize leading underscore': function () {
var str = '_foo_bar_baz'
, actual = string.camelize(str, {leadingUnderscore: true});
assert.equal('_fooBarBaz', actual);
, 'test lpad without width for string': function() {
var data = string.lpad('geddy', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test lpad without width of char for string': function() {
var data = string.lpad('geddy')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test basic rpad for string': function() {
var data = string.rpad('geddy', '&', 7)
, actual = 'geddy&&';
assert.equal(data, actual);
}
, 'test rpad without width for string': function() {
var data = string.rpad('geddy', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test rpad without width of char for string': function() {
var data = string.rpad('geddy')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test basic pad for string': function() {
var data = string.pad('geddy', '&', 7)
, actual = '&geddy&';
assert.equal(data, actual);
}
, 'test pad without width for string': function() {
var data = string.pad('geddy', '&')
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test pad without width of char for string': function() {
var data = string.pad('geddy')
, actual = 'geddy';
assert.equal(data, actual);
}
// We could test truncate and truncateHTML here, but helper tests already
// include tests for them
, 'test nl2br for string': function() {
var data = string.nl2br("geddy\n")
, actual = 'geddy<br />';
assert.equal(data, actual);
}
, 'test snakeize for string': function() {
var data = string.snakeize("geddyJs")
, actual = 'geddy_js';
assert.equal(data, actual);
}
, 'test snakeize with beginning caps for string': function() {
var data = string.snakeize("GeddyJs")
, actual = 'geddy_js';
assert.equal(data, actual);
}
, 'test camelize for string': function() {
var data = string.camelize("geddy_js")
, actual = 'geddyJs';
assert.equal(data, actual);
}
, 'test camelize with initialCap for string': function() {
var data = string.camelize("geddy_js", {initialCap: true})
, actual = 'GeddyJs';
assert.equal(data, actual);
}
, 'test camelize with leadingUnderscore with no underscore for string': function() {
var data = string.camelize("geddy_js", {leadingUnderscore: true})
, actual = 'geddyJs';
assert.equal(data, actual);
}
, 'test camelize with leadingUnderscore with underscore for string': function() {
var data = string.camelize("_geddy_js", {leadingUnderscore: true})
, actual = '_geddyJs';
assert.equal(data, actual);
}
, 'test decapitalize for string': function() {
var data = string.decapitalize("Geddy")
, actual = 'geddy';
assert.equal(data, actual);
}
, 'test capitalize for string': function() {
var data = string.capitalize("geddy")
, actual = 'Geddy';
assert.equal(data, actual);
}
, 'test dasherize for string': function() {
var data = string.dasherize("geddyJs")
, actual = 'geddy-js';
assert.equal(data, actual);
}
, 'test dasherize with custom replace char for string': function() {
var data = string.dasherize("geddyJs", "_")
, actual = 'geddy_js';
assert.equal(data, actual);
}
, 'test underscorize for string': function() {
var data = string.underscorize("geddyJs")
, actual = 'geddy_js';
assert.equal(data, actual);
}
, 'test inflection for string': function() {
var actual = string.getInflections("string")
, expected = {
filename: {
singular: "string"
, plural: "strings"
},
constructor: {
singular: "String"
, plural: "Strings"
},
property: {
singular: "string"
, plural: "strings"
},
};
assert.deepEqual(expected, actual);
}
, 'test inflection with odd name for string': function() {
var actual = string.getInflections("snow_dog")
, expected = {
filename: {
singular: "snow_dog"
, plural: "snow_dogs"
},
constructor: {
singular: "SnowDog"
, plural: "SnowDogs"
},
property: {
singular: "snowDog"
, plural: "snowDogs"
},
};
assert.deepEqual(expected, actual);
}
, 'test uuid length for string': function() {
var data = string.uuid(5).length
, actual = 5;
assert.equal(data, actual);
}
};

@@ -67,0 +255,0 @@

@@ -1,2 +0,19 @@

// Load the basic Geddy toolkit
/*
* Utilities: A classic collection of JavaScript utilities
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* 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 XML = require('../lib/xml').XML

@@ -6,9 +23,11 @@ , assert = require('assert')

, xml
, res;
, res
, serialize
, tests;
var serialize = function (o) {
serialize = function (o) {
return XML.stringify(o, {whitespace: false});
};
var tests = {
tests = {

@@ -50,2 +69,53 @@ 'test serialized object': function () {

, 'test setIndentLevel for xml': function() {
var data = XML.setIndentLevel(5)
, actual = 5;
assert.equal(data, actual)
}
, 'test stringify with object for xml': function() {
var data = XML.stringify({user: 'name'})
, actual = '<?xml version="1.0" encoding="UTF-8"?>\n<object>\n <user>name</user>\n</object>\n';
assert.equal(data, actual)
}
, 'test stringify with array for xml': function() {
var data = XML.stringify(['user'])
, actual = '<?xml version="1.0" encoding="UTF-8"?>\n<strings type="array">\n\
<string>user</string>\n</strings>';
assert.equal(data, actual)
}
, 'test stringify with object and no whitespace for xml': function() {
var data = XML.stringify({user: 'name'}, {whitespace: false})
, actual = '<?xml version="1.0" encoding="UTF-8"?><object><user>name</user></object>';
assert.equal(data, actual)
}
, 'test stringify with object and name for xml': function() {
var data = XML.stringify({user: 'name'}, {name: 'omg'})
, actual = '<?xml version="1.0" encoding="UTF-8"?>\n<omg>\n<user>name</user>\n</omg>\n';
assert.equal(data, actual)
}
, 'test stringify with object and fragment for xml': function() {
var data = XML.stringify({user: 'name'}, {fragment: true})
, actual = '<object>\n<user>name</user>\n</object>\n';
assert.equal(data, actual)
}
, 'test stringify with object for xml': function() {
var data = XML.stringify({user: 'name'}, {level: 1})
, actual = '<?xml version="1.0" encoding="UTF-8"?>\n <user>name</user>\n';
assert.equal(data, actual)
}
, 'test stringify with array and no arrayRoot for xml': function() {
var data = XML.stringify(['user'], {arrayRoot: false})
, actual = '<?xml version="1.0" encoding="UTF-8"?>\n<strings type="array">\n\
<string>user</string>\n</strings>';
assert.equal(data, actual)
}
};

@@ -52,0 +122,0 @@

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