configparser
Advanced tools
+7
-7
| { | ||
| "name": "configparser", | ||
| "version": "0.1.6", | ||
| "version": "0.2.6", | ||
| "description": "A basic config parser language based off the Python ConfigParser module.", | ||
@@ -16,8 +16,8 @@ "main": "src/configparser.js", | ||
| "keywords": [ | ||
| "config", | ||
| "parser", | ||
| "configparser", | ||
| "config-parser", | ||
| "ini", | ||
| "node" | ||
| "config", | ||
| "parser", | ||
| "configparser", | ||
| "config-parser", | ||
| "ini", | ||
| "node" | ||
| ], | ||
@@ -24,0 +24,0 @@ "dependencies": {}, |
+8
-0
@@ -13,2 +13,6 @@ ### Config Parser [](https://circleci.com/gh/ZachPerkitny/configparser) | ||
| ##### Writing | ||
| There are two methods available for writing the contents | ||
| of the config file to disk: [write](https://zachperkitny.github.io/configparser/ConfigParser.html#write) and [writeAsync](https://zachperkitny.github.io/configparser/ConfigParser.html#writeAsync). | ||
| ```js | ||
@@ -44,2 +48,6 @@ const ConfigParser = require('configparser'); | ||
| ##### Reading | ||
| There are two methods available for reading the contents | ||
| of the config file from disk: [read](https://zachperkitny.github.io/configparser/ConfigParser.html#read) and [readAsync](https://zachperkitny.github.io/configparser/ConfigParser.html#readAsync). | ||
| ```js | ||
@@ -46,0 +54,0 @@ config.read('my-cfg-file.cfg'); |
+77
-41
@@ -0,1 +1,2 @@ | ||
| const util = require('util'); | ||
| const fs = require('fs'); | ||
@@ -27,7 +28,14 @@ const errors = require('./errors'); | ||
| // RL1.6 Line Boundaries (for unicode) | ||
| // ... it shall recognize not only CRLF, LF, CR, | ||
| // but also NEL, PS and LS. | ||
| const LINE_BOUNDARY = new RegExp(/\r\n|[\n\r\u0085\u2028\u2029]/g); | ||
| const readFileAsync = util.promisify(fs.readFile); | ||
| const writeFileAsync = util.promisify(fs.writeFile); | ||
| /** | ||
| * @constructor | ||
| */ | ||
| function ConfigParser(){ | ||
| function ConfigParser() { | ||
| this._sections = {}; | ||
@@ -40,3 +48,3 @@ } | ||
| */ | ||
| ConfigParser.prototype.sections = function(){ | ||
| ConfigParser.prototype.sections = function() { | ||
| return Object.keys(this._sections); | ||
@@ -50,3 +58,3 @@ }; | ||
| */ | ||
| ConfigParser.prototype.addSection = function(section){ | ||
| ConfigParser.prototype.addSection = function(section) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -64,3 +72,3 @@ throw new errors.DuplicateSectionError(section) | ||
| */ | ||
| ConfigParser.prototype.hasSection = function(section){ | ||
| ConfigParser.prototype.hasSection = function(section) { | ||
| return this._sections.hasOwnProperty(section); | ||
@@ -74,3 +82,3 @@ }; | ||
| */ | ||
| ConfigParser.prototype.keys = function(section){ | ||
| ConfigParser.prototype.keys = function(section) { | ||
| try { | ||
@@ -98,32 +106,21 @@ return Object.keys(this._sections[section]); | ||
| */ | ||
| ConfigParser.prototype.read = function(file){ | ||
| // RL1.6 Line Boundaries (for unicode) | ||
| // ... it shall recognize not only CRLF, LF, CR, | ||
| // but also NEL, PS and LS. | ||
| ConfigParser.prototype.read = function(file) { | ||
| const lines = fs.readFileSync(file) | ||
| .toString('utf8') | ||
| .split(/\r\n|[\n\r\u0085\u2028\u2029]/g); | ||
| let curSec = null; | ||
| lines.forEach((line, lineNumber) => { | ||
| if(!line || line.match(COMMENT)) return; | ||
| let res = SECTION.exec(line); | ||
| if(res){ | ||
| const header = res[1]; | ||
| curSec = {}; | ||
| this._sections[header] = curSec; | ||
| } else if(!curSec) { | ||
| throw new errors.MissingSectionHeaderError(file, lineNumber, line); | ||
| } else { | ||
| res = KEY.exec(line); | ||
| if(res){ | ||
| const key = res[1]; | ||
| curSec[key] = res[2]; | ||
| } else { | ||
| throw new errors.ParseError(file, lineNumber, line); | ||
| } | ||
| } | ||
| }); | ||
| .split(LINE_BOUNDARY); | ||
| parseLines.call(this, lines); | ||
| }; | ||
| /** | ||
| * Reads a file asynchronously and parses the configuration data. | ||
| * @param {string|Buffer|int} file - Filename or File Descriptor | ||
| */ | ||
| ConfigParser.prototype.readAsync = async function(file) { | ||
| const lines = (await readFileAsync(file)) | ||
| .toString('utf8') | ||
| .split(LINE_BOUNDARY); | ||
| parseLines.call(this, lines); | ||
| } | ||
| /** | ||
| * Gets the value for the key in the named section. | ||
@@ -135,3 +132,3 @@ * @param {string} section - Section Name | ||
| */ | ||
| ConfigParser.prototype.get = function(section, key, raw){ | ||
| ConfigParser.prototype.get = function(section, key, raw) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -154,3 +151,3 @@ if(raw){ | ||
| */ | ||
| ConfigParser.prototype.getInt = function(section, key, radix){ | ||
| ConfigParser.prototype.getInt = function(section, key, radix) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -169,3 +166,3 @@ if(!radix) radix = 10; | ||
| */ | ||
| ConfigParser.prototype.getFloat = function(section, key){ | ||
| ConfigParser.prototype.getFloat = function(section, key) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -182,3 +179,3 @@ return parseFloat(this._sections[section][key]); | ||
| */ | ||
| ConfigParser.prototype.items = function(section){ | ||
| ConfigParser.prototype.items = function(section) { | ||
| return this._sections[section]; | ||
@@ -193,3 +190,3 @@ }; | ||
| */ | ||
| ConfigParser.prototype.set = function(section, key, value){ | ||
| ConfigParser.prototype.set = function(section, key, value) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -206,3 +203,3 @@ this._sections[section][key] = value; | ||
| */ | ||
| ConfigParser.prototype.removeKey = function(section, key){ | ||
| ConfigParser.prototype.removeKey = function(section, key) { | ||
| // delete operator returns true if the property doesn't not exist | ||
@@ -221,3 +218,3 @@ if(this._sections.hasOwnProperty(section) && | ||
| */ | ||
| ConfigParser.prototype.removeSection = function(section){ | ||
| ConfigParser.prototype.removeSection = function(section) { | ||
| if(this._sections.hasOwnProperty(section)){ | ||
@@ -234,3 +231,42 @@ return delete this._sections[section]; | ||
| */ | ||
| ConfigParser.prototype.write = function(file){ | ||
| ConfigParser.prototype.write = function(file) { | ||
| const out = getSectionsAsString.call(this); | ||
| fs.writeFileSync(file, out); | ||
| }; | ||
| /** | ||
| * Writes the representation of the config file to the | ||
| * specified file asynchronously. Comments are not preserved. | ||
| * @param {string|Buffer|int} file - Filename or File Descriptor | ||
| * @returns {Promise} | ||
| */ | ||
| ConfigParser.prototype.writeAsync = function(file) { | ||
| const out = getSectionsAsString.call(this); | ||
| return writeFileAsync(file, out); | ||
| } | ||
| function parseLines(lines) { | ||
| let curSec = null; | ||
| lines.forEach((line, lineNumber) => { | ||
| if(!line || line.match(COMMENT)) return; | ||
| let res = SECTION.exec(line); | ||
| if(res){ | ||
| const header = res[1]; | ||
| curSec = {}; | ||
| this._sections[header] = curSec; | ||
| } else if(!curSec) { | ||
| throw new errors.MissingSectionHeaderError(file, lineNumber, line); | ||
| } else { | ||
| res = KEY.exec(line); | ||
| if(res){ | ||
| const key = res[1]; | ||
| curSec[key] = res[2]; | ||
| } else { | ||
| throw new errors.ParseError(file, lineNumber, line); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function getSectionsAsString() { | ||
| let out = ''; | ||
@@ -250,5 +286,5 @@ let section; | ||
| } | ||
| fs.writeFileSync(file, out); | ||
| }; | ||
| return out; | ||
| } | ||
| module.exports = ConfigParser; | ||
| module.exports = ConfigParser; |
+5
-5
@@ -7,3 +7,3 @@ /** | ||
| */ | ||
| function DuplicateSectionError(section){ | ||
| function DuplicateSectionError(section) { | ||
| this.name = 'DuplicateSectionError'; | ||
@@ -20,3 +20,3 @@ this.message = section + ' already exists'; | ||
| */ | ||
| function NoSectionError(section){ | ||
| function NoSectionError(section) { | ||
| this.name = this.constructor.name; | ||
@@ -34,3 +34,3 @@ this.message = 'Section ' + section + ' does not exist.'; | ||
| */ | ||
| function ParseError(filename, lineNumber, line){ | ||
| function ParseError(filename, lineNumber, line) { | ||
| this.name = this.constructor.name; | ||
@@ -50,3 +50,3 @@ this.message = 'Source contains parsing errors.\nfile: ' + filename + | ||
| */ | ||
| function MissingSectionHeaderError(filename, lineNumber, line){ | ||
| function MissingSectionHeaderError(filename, lineNumber, line) { | ||
| this.name = this.constructor.name; | ||
@@ -67,3 +67,3 @@ this.message = 'File contains no section headers.\nfile: ' + filename + | ||
| */ | ||
| function MaximumInterpolationDepthError(section, key, value, maxDepth){ | ||
| function MaximumInterpolationDepthError(section, key, value, maxDepth) { | ||
| this.name = this.constructor.name; | ||
@@ -70,0 +70,0 @@ this.message = 'Exceeded Maximum Recursion Depth (' + maxDepth + |
@@ -23,3 +23,3 @@ const errors = require('./errors'); | ||
| */ | ||
| function interpolate(parser, section, key){ | ||
| function interpolate(parser, section, key) { | ||
| return interpolateRecurse(parser, section, key, 1); | ||
@@ -36,3 +36,3 @@ } | ||
| */ | ||
| function interpolateRecurse(parser, section, key, depth){ | ||
| function interpolateRecurse(parser, section, key, depth) { | ||
| let value = parser.get(section, key, true); | ||
@@ -39,0 +39,0 @@ if(depth > MAXIMUM_INTERPOLATION_DEPTH){ |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
18778
9.03%440
7.84%60
15.38%7
-12.5%2
100%