diff --git a/README.md b/README.md index 924b731..11d012b 100644 --- a/README.md +++ b/README.md @@ -383,6 +383,19 @@ Options: ``` - __strict__ - _Boolean_ This option can be used with the `comments` and `separators` options. If true, __only__ the tokens specified in these options are used to parse comments and separators. +- __casting__ - _Object_ + By default, property values will be cast to their JavaScript type equivalent. It is possible to disable this behaviour per type: + + ```javascript + casting: { + nulls: false, + undefineds: false, + booleans: false, + numbers: false + } + ``` + + For example, if your property values may contain numbers in octal, hexadecimal or exponential notation, think carefully about their range and their subsequent usage, or the automatic casting might surprise you. - __sections__ - _Boolean_ Parses INI sections. Read the [INI](#ini) section for further details. - __namespaces__ - _Boolean_ @@ -623,4 +636,4 @@ stringifier.section ({ name: "my section", comment: "My Section" }); */ ``` -Look at the [stringify-ini](https://github.com/gagle/node-properties/blob/master/examples/ini/stringify-ini.js) example for further details. \ No newline at end of file +Look at the [stringify-ini](https://github.com/gagle/node-properties/blob/master/examples/ini/stringify-ini.js) example for further details. diff --git a/lib/read.js b/lib/read.js index b9e37df..39211aa 100644 --- a/lib/read.js +++ b/lib/read.js @@ -3,17 +3,29 @@ var fs = require ("fs"); var path = require ("path"); var parse = require ("./parse"); +var merge = require('deepmerge'); var INCLUDE_KEY = "include"; var INDEX_FILE = "index.properties"; +var CASTING_DEFAULTS = { + nulls: true, + undefineds: true, + booleans: true, + numbers: true +}; -var cast = function (value){ - if (value === null || value === "null") return null; - if (value === "undefined") return undefined; - if (value === "true") return true; - if (value === "false") return false; - var v = Number (value); - return isNaN (v) ? value : v; +var cast = function (value, options){ + if (options.nulls) { if (value === null || value === "null") return null; } + if (options.undefineds) { if (value === "undefined") return undefined; } + if (options.booleans) { + if (value === "true") return true; + if (value === "false") return false; + } + if (options.numbers) { + var v = Number (value); + return isNaN (v) ? value : v; + } + return value; }; var expand = function (o, str, options, cb){ @@ -365,7 +377,7 @@ var build = function (data, options, dirname, cb){ function (error, value){ if (error) return abort (error); - line (key, cast (value || null)); + line (key, cast (value || null, options._casting)); }); }); }; @@ -381,7 +393,7 @@ var build = function (data, options, dirname, cb){ } }else{ handlers.line = function (key, value){ - line (key, cast (value || null)); + line (key, cast (value || null, options._casting)); }; if (options.sections){ @@ -436,6 +448,7 @@ module.exports = function (data, options, cb){ options = options || {}; options._strict = options.strict && (options.comments || options.separators); options._vars = options.vars || {}; + options._casting = merge(CASTING_DEFAULTS, options.casting); var comments = options.comments || []; if (!Array.isArray (comments)) comments = [comments]; @@ -477,4 +490,4 @@ module.exports = function (data, options, cb){ }else{ return build (data, options, ".", cb); } -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index a741bad..1f71a7d 100644 --- a/package.json +++ b/package.json @@ -2,20 +2,29 @@ "name": "properties", "version": "1.2.1", "description": ".properties parser/stringifier", - "keywords": ["properties", "ini", "parser", "stringifier", "config"], + "keywords": [ + "properties", + "ini", + "parser", + "stringifier", + "config" + ], "author": "Gabriel Llamas ", "repository": "git://github.com/gagle/node-properties.git", "engines": { "node": ">=0.10" }, + "dependencies": { + "deepmerge": "^0.2.7" + }, "devDependencies": { "ini": "1.1.x", - "speedy": "*", - "js-yaml": "2.1.x" + "js-yaml": "2.1.x", + "speedy": "*" }, "scripts": { "test": "node test/parse && node test/stringify" }, "license": "MIT", "main": "lib" -} \ No newline at end of file +} diff --git a/test/parse.js b/test/parse.js index 830c49c..a52ebd6 100644 --- a/test/parse.js +++ b/test/parse.js @@ -43,11 +43,6 @@ var tests = { a19: "É", "←": "→", "→": "→", - a20: true, - a21: false, - a22: 123, - a23: null, - a24: undefined, "[a]": null }); @@ -592,6 +587,50 @@ var tests = { done (); }); + }, + "cast values according to defaults": function(done) { + var options = { path: true }; + + properties.parse ("types", options, + function (error, p){ + assert.ifError (error); + + assert.deepEqual (p, { + a1: true, + a2: false, + a3: 123, + a4: null, + a5: undefined, + a6: 123, + a7: 291, + a8: 1230 + }); + + done (); + } + ); + }, + "cast values according to options": function(done) { + var options = { path: true, casting: { nulls: false, undefineds: false, booleans: false, numbers: false } }; + + properties.parse ("types", options, + function (error, p){ + assert.ifError (error); + + assert.deepEqual (p, { + a1: 'true', + a2: 'false', + a3: '123', + a4: 'null', + a5: 'undefined', + a6: '0123', + a7: '0x123', + a8: '123e1' + }); + + done (); + } + ); } }; @@ -610,4 +649,4 @@ var keysLength = keys.length; again (i + 1); } } -})(0); \ No newline at end of file +})(0); diff --git a/test/properties b/test/properties index 0c70476..80d7064 100644 --- a/test/properties +++ b/test/properties @@ -45,12 +45,5 @@ a19 \u00c9 92=\u\21\ 92 -#Type conversion -a20 true -a21 false -a22 123 -a23 null -a24 undefined - #No sections -[a] \ No newline at end of file +[a] diff --git a/test/types b/test/types new file mode 100644 index 0000000..8f5ead5 --- /dev/null +++ b/test/types @@ -0,0 +1,9 @@ +#Type conversion +a1 true +a2 false +a3 123 +a4 null +a5 undefined +a6 0123 +a7 0x123 +a8 123e1