ini-config-parser
Parse ini file with nested config overriding made easier
According to INI file acticle on Wikipedia, there are many implementation on ini file parser. This is an attempt to create a customizable ini parser
Usage
IniConfigParser.parse(string, [object])
Parse an ini text with these default options
defaultOptions = merge: true # Return config as merge of global + sections env: processenv # Used for variable extension. Set to false to disable variable extension blockComment: ';;;''###'# Used to delimit block comment. Set to false if you don't want block comment lineComment: ';''#'# Used to delimit line comment. Set to false if you don't want line comment assign: ':''='# Define assign symbols nativeType: true # Transform boolean and numbers into native type unless quoted dotKey: true # Parse `a.b.c = value` as `{a: {b: {c: value}}}` instead of `{'a.b.c': value}` unless quoted inherit: true # Enable global and section inheritance. .i.e `[a: b : c : ...]` similar to `_.defaultsDeep(a, b, c)` array: true # Parse key[] = value as {key: [value]} instead of {'key[]': 'value'} unless quoted string: true # Parse 'key' as a javascript string. i.e decode `\t \r \n \v \f \uhhhh \u{hhhhh} \<octal>` mstring: true # Enable multiline strings ignoreInvalidStringKey: true # Parse `"tata" y = toto` => `{'"tata" y': 'toto'}` otherwise, throw an error ignoreInvalidStringValue: true # `toto = "tata"y` => `{toto: '"tata"y'}` emptyValue: '' # Empty value escapeCharKey: true # Escape `\` in not quoted key escapeCharValue: true # Escape `\` in value in not quoted value ignoreMissingAssign: true # Allow keys without assign token ignoreCase: false # All keys and values are lower case
IniConfigParser.Parser([object]).parse(string)
Parse an ini text with these default options
defaultOptions = merge: false # Return config as merge of global + sections env: processenv # Used for variable extension. Set to false to disable variable extension blockComment: ';;;''###'# Used to delimit block comment. Set to false if you don't want block comment lineComment: ';''#'# Used to delimit line comment. Set to false if you don't want line comment assign: ':''='# Define assign symbols nativeType: true # Transform boolean and numbers into native type unless quoted dotKey: true # Parse `a.b.c = value` as `{a: {b: {c: value}}}` instead of `{'a.b.c': value}` unless quoted inherit: true # Enable global and section inheritance. .i.e `[a: b : c : ...]` similar to `_.defaultsDeep(a, b, c)` array: true # Parse key[] = value as {key: [value]} instead of {'key[]': 'value'} unless quoted string: true # Parse 'key' as a javascript string. i.e decode `\t \r \n \v \f \uhhhh \u{hhhhh} \<octal>` mstring: true # Enable multiline strings ignoreInvalidStringKey: true # Parse `"tata" y = toto` => `{'"tata" y': 'toto'}` otherwise, throw an error ignoreInvalidStringValue: true # `toto = "tata"y` => `{toto: '"tata"y'}` emptyValue: '' # Empty value escapeCharKey: true # Escape `\` in not quoted key escapeCharValue: true # Escape `\` in value in not quoted value ignoreMissingAssign: true # Allow keys without assign token ignoreCase: false # All keys and values are lower case
Examples
config.ini
key = valuearray[] = g0array[] = g1 [production]server.port = $PORTserver.host = $HOSTredis.host = x.x.x.xredis.port = 7468redis.db = 1redis.ttl = 3600 [development : production]redis.host = localhostredis.port = 6379smtp.server = 127.0.0.1smtp.port = 587client.routes.defaults.language = frarray[] = item0array[] = item1'strkey' = 'strvalue''''mstrkey''' = '''mstrvalue'''
var IniConfigParser = Parser = IniConfigParserParser; var file = __dirname + '/config.ini' data = fs config expect; config = IniConfigParser; expect = key: 'value' array: 'g0' 'g1' production: key: 'value' server: port: '3000' host: '127.0.0.1' redis: host: 'x.x.x.x' port: 7468 db: 1 ttl: 3600 array: 'g0' 'g1' development: key: 'value' server: port: '3000' host: '127.0.0.1' redis: host: 'localhost' port: 6379 db: 1 ttl: 3600 smtp: server: '127.0.0.1' port: 587 client: routes: defaults: language: 'fr' array: 'item0' 'item1' strkey: 'strvalue' mstrkey: 'mstrvalue' ; assert; config = IniConfigParser;assert;
Seperate global and sections
var IniConfigParser = ; var file = __dirname + '/config.ini' data = fs; var config = IniConfigParser; assert; // by default, all sections inherit global propertiesassert; // however global properties can be overrided in sectionsassert; assert;
Options
env
type: object|falsedefault: process.env
Used for variable extension. Set to false to disable variable extension
var data = "user = $user" "password = ${password}" "missing = $missing" "unknown = ${unknown}"; assert; assert;
onEnvNotFound(variable, str)
type: function
Called when variable is not found
var data = "user = $user" "password = ${password}" "missing = $missing" "unknown = ${unknown}"; { return '==' + variable + '[' + str + ']' + '==';} assert; // disabling false also disable onEnvNotFoundassert;
blockComment
type: array|falsedefault: [';;;', '###']
Used to delimit block comment. Set to false if you don't want block comment
// ;;; and ### are the default block comment// ; and # are the default line commentassert; var data = "***a comment" "to ignore***" "oui*** =" "non***" "###a comment" "to ignore###" "user = name *** inline ***" "password = password ;;; inline ;;;"; // ; and # are the default line commentassert; // ; and # are the default line commentassert;
lineComment
type: array|falsedefault: [';', '#']
Used to delimit line comment. Set to false if you don't want line comment
var data = "user = name; inline" "; a comment" "# a comment" "password = password # inline"; // ; and # are the default line commentassert; assert; assert;
assign
type: arraydefault: [':', '=']
Define assign symbols
// : and = are the default line commentassert; // # is still a line commentassert;
nativeType
type: booleandefault: true
Transform boolean and numbers into native type unless quoted
var data = "int = 5" "scientific = 1e6" "float = 1.5" "true = true" "false = false" "sint = '5'" "sscientific = '1e6'" "sfloat = '1.5'" "strue = 'true'" "sfalse = 'false'"; assert; assert;
dotKey
type: booleandefault: true
Parse a.b.c = value
as {a: {b: {c: value}}}
instead of {'a.b.c': value}
unless quoted
type: booleandefault: true
var data = "x.y.z = 5" "'a.b.c' = 1e6"; assert; assert;
inherit
type: booleandefault: true
Enable global and section inheritance. .i.e [a: b : c : ...]
similar to _.defaultsDeep(a, b, c)
var data = "key = value" "array[] = g0" "array[] = g1" "[production]" "server.host = 127.0.0.1" "server.port = xxxx" "redis.host = x.x.x.x" "redis.port = 9876" "redis.db = 1" "redis.ttl = 3600" "[development : production]" "redis.host = localhost" "redis.port = 6379" "smtp.server = 127.0.0.1" "smtp.port = 587" "array[] = item0" "array[] = item1"; assert; assert;
array
type: booleandefault: true
Parse key[] = value
as {key: [value]}
instead of {'key[]': 'value'}
unless quoted
var data = "er[] =" "ar[] = 0" "'zr[]' = 0" "'[]' = 0" "'x.y.z[]' = 0" "x.y.z[] = 1" "x.y.z[] = 1" "x.y.z[] = 2"; assert; assert;
string
type: booleandefault: true
Parse 'key' as a javascript string. i.e decode \t \r \n \v \f \uhhhh \u{hhhhh} \<octal>
string.ini
'strkey' = 'value''strkey ; comment' = 'value ; comment''strkey ;;; comment ;;;' = 'value ;;; comment ;;;'"esca\"ped" = 'esca\'ped''htab = \t' = '\t''cr =\r' = '\r''lf = \n' = '\n''vtab = \v' = '\v''form-feed = \f' = '\f''backspace = \b' = '\b' ### completely ignored### '\\u00FF = \u00FF' = '\u00FF''\\u{456} = \u{456}' = '\u{456}''\\111 = \111' = '\111'; ignored text = "some\ttext with\nnew line and unicodes u\u0424u and u\u{201}u and octal o\111o"
// \t \r \n \v \f \uhhhh \u{hhhhh} \<octal>var data = fs; assert; assert;
mstring
type: booleandefault: true
Enable multiline strings
mstring.ini
'''strkey''' = '''value''' '''strkey ; comment''' = '''value ; comment''' '''strkey ;;; comment ;;;''' = '''value ;;; comment ;;;''' """\"\'escaped"'""" = '''\"\'escaped"'''' '''htab = \t''' = '''\t''' '''cr =\r''' = '''\r''' '''lf = \n''' = '''\n''' '''vtab = \v''' = '''\v''' '''form-feed = \f''' = '''\f''' '''backspace = \b''' = '''\b''' ### completely ignored### '''\\u00FF = \u00FF''' = '''\u00FF''' '''\\u{456} = \u{456}''' = '''\u{456}''' '''\\111 = \111''' = '''\111'''; ignored text = """some\ttext with\nnew line and unicodes u\u0424u and u\u{201}u and octal o\111o"""
// \t \r \n \v \f \uhhhh \u{hhhhh} \<octal>var data = fs; assert; assert;
ignoreInvalidStringKey
type: booleandefault: true
Parse "tata" y = toto
=> {'"tata" y': 'toto'}
otherwise, throw an error
assert; assert; assert;
ignoreInvalidStringValue
type: booleandefault: true
Parse "tata" y = toto
=> {'"tata" y': 'toto'}
otherwise, throw an error
assert; assert; assert;
emptyValue
type: booleandefault: true
Empty value
assert;
escapeCharKey
type: booleandefault: true
Escape \
in not quoted key
var data = 'ho\\st = 127.0.0.1'; assert; assert;
escapeCharValue
type: booleandefault: true
Escape \
in value in not quoted value
var data = 'host = 127.0\\.0.1' 'port = $port' 'eport = \\$port'; assert; assert;
ignoreMissingAssign
type: booleandefault: true
Allow keys without assign token
var data = 'host = ' 'port'; assert; assert;
ignoreCase
type: booleandefault: false
All keys and values are lower case
assert;
merge
type: booleandefault: false
Return config as merge of global + sections
License
The MIT License (MIT)
Copyright (c) 2014-2016 Stéphane MBAPE (http://smbape.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.