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

@nodecraft/ini

Package Overview
Dependencies
Maintainers
4
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nodecraft/ini - npm Package Compare versions

Comparing version 2.1.1 to 2.1.2

145

ini.js
'use strict';
/* eslint-disable no-use-before-define */
exports.parse = exports.decode = decode;
const {hasOwnProperty} = Object.prototype;
exports.stringify = exports.encode = encode;
exports.safe = safe;
exports.unsafe = unsafe;
const eol = require('os').EOL;
function encode(obj, opt){
const encode = (obj, opt) => {
const children = [];

@@ -31,3 +26,3 @@ let out = '';

if(val && Array.isArray(val)){
val.forEach(function(item){
for(const item of val){
if(opt.inlineArrays){

@@ -39,3 +34,3 @@ out += safe(key) + separator + safe(item) + eol;

}
});
}
}else if(val && typeof val === 'object'){

@@ -48,7 +43,7 @@ children.push(key);

if(opt.section && out.length){
if(opt.section && out.length > 0){
out = '[' + safe(opt.section) + ']' + eol + out;
}
children.forEach(function(key){
for(const key of children){
const parsedSection = dotSplit(key).join('\\.');

@@ -61,21 +56,18 @@ const section = (opt.section ? opt.section + '.' : '') + parsedSection;

});
if(out.length && child.length){
if(out.length > 0 && child.length > 0){
out += eol;
}
out += child;
});
}
return out;
}
};
function dotSplit(str){
return str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002')
.replace(/\\\./g, '\u0001')
.split(/\./).map(function(part){
return part.replace(/\1/g, '\\.')
.replace(/\2LITERAL\\1LITERAL\2/g, '\u0001');
});
}
const dotSplit = str => str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002')
.replace(/\\\./g, '\u0001')
.split(/\./)
.map(part => part.replace(/\1/g, '\\.')
.replace(/\2LITERAL\\1LITERAL\2/g, '\u0001'));
function decode(str, opt = {}){
const decode = (str, opt = {}) => {
const defaultValue = typeof opt.defaultValue !== 'undefined' ? opt.defaultValue : '';

@@ -87,9 +79,9 @@

// section |key = value
const re = /^\[([^\]]*)\]$|^([^=]+)(?:=(.*))?$/i;
const lines = str.split(/[\r\n]+/g);
const commentMatch = /^\s*[;#]/;
lines.forEach(function(line){
if(!line || line.match(commentMatch)){ return; }
const re = /^\[([^\]]*)]$|^([^=]+)(?:=(.*))?$/i;
const lines = str.split(/[\n\r]+/g);
const commentMatch = /^\s*[#;]/;
for(const line of lines){
if(!line || commentMatch.test(line)){ continue; }
const match = line.match(re);
if(!match){ return; }
if(!match){ continue; }
if(match[1] !== undefined){

@@ -101,9 +93,9 @@ section = unsafe(match[1]);

ref = Object.create(null);
return;
continue;
}
ref = out[section] = out[section] || Object.create(null);
return;
continue;
}
let key = unsafe(match[2]);
if(key === '__proto__'){ return; }
if(key === '__proto__'){ continue; }
let value = match[3] ? unsafe(match[3]) : defaultValue;

@@ -122,5 +114,5 @@ switch(value){

if(key.length > 2 && key.slice(-2) === '[]'){
key = key.substring(0, key.length - 2);
if(key === '__proto__'){ return; }
if(!ref[key]){
key = key.slice(0, Math.max(0, key.length - 2));
if(key === '__proto__'){ continue; }
if(!hasOwnProperty.call(ref, key)){
ref[key] = [];

@@ -141,9 +133,10 @@ }else if(!Array.isArray(ref[key])){

}
});
}
// {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}}
// use a filter to return the keys that have to be deleted.
Object.keys(out).filter(function(key){
if(!out[key] || typeof out[key] !== 'object' || Array.isArray(out[key])){
return false;
const remove = [];
for(const key of Object.keys(out)){
if(!hasOwnProperty.call(out, key) || typeof out[key] !== 'object' || Array.isArray(out[key])){
continue;
}

@@ -153,33 +146,34 @@ // see if the parent section is also an object.

const parts = dotSplit(key);
let p = out;
let outPart = out;
console.log('parts', parts);
const lastKey = parts.pop();
const unescapedLastKey = lastKey.replace(/\\\./g, '.');
parts.forEach(function(part){
if(part === '__proto__'){ return; }
if(!p[part] || typeof p[part] !== 'object'){
p[part] = Object.create(null);
for(const part of parts){
if(part === '__proto__'){ continue; }
if(!hasOwnProperty.call(outPart, part) || typeof outPart[part] !== 'object'){
outPart[part] = Object.create(null);
}
p = p[part];
});
if(p === out && unescapedLastKey === lastKey){
return false;
outPart = outPart[part];
}
p[unescapedLastKey] = out[key];
return true;
}).forEach(function(del){
if(outPart === out && unescapedLastKey === lastKey){
continue;
}
outPart[unescapedLastKey] = out[key];
remove.push(key);
}
for(const del of remove){
delete out[del];
});
}
return out;
}
};
// determines if string is encased in quotes
function isQuoted(val){
return (val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"));
}
const isQuoted = val => (val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"));
// escapes the string val such that it is safe to be used as a key or value in an ini-file. Basically escapes quotes
function safe(val){
const safe = (val) => {
// all kinds of values and keys
if(typeof val !== 'string' || val.match(/[=\r\n]/) || val.match(/^\[/) || (val.length > 1 && isQuoted(val)) || val !== val.trim()){
if(typeof val !== 'string' || /[\n\r=]/.test(val) || /^\[/.test(val) || (val.length > 1 && isQuoted(val)) || val !== val.trim()){
return JSON.stringify(val);

@@ -189,6 +183,6 @@ }

return val.replace(/;/g, '\\;').replace(/#/g, '\\#');
}
};
// unescapes the string val
function unsafe(val){
const unsafe = (val) => {
const escapableChars = '\\;#';

@@ -201,7 +195,7 @@ const commentChars = ';#';

if(val.charAt(0) === "'"){
val = val.substr(1, val.length - 2);
val = val.substr(1, val.length - 2); // eslint-disable-line unicorn/prefer-string-slice
}
try{
val = JSON.parse(val);
}catch(e){
}catch{
// we tried :(

@@ -214,18 +208,18 @@ }

let escapedVal = '';
for(let i = 0, l = val.length; i < l; i++){
const c = val.charAt(i);
for(let i = 0, len = val.length; i < len; i++){
const char = val.charAt(i);
if(isEscaping){
// check if this character is an escapable character like \ or ; or #
if(escapableChars.indexOf(c) !== -1){
escapedVal += c;
if(escapableChars.includes(char)){
escapedVal += char;
}else{
escapedVal += '\\' + c;
escapedVal += '\\' + char;
}
isEscaping = false;
}else if(commentChars.indexOf(c) !== -1){
}else if(commentChars.includes(char)){
break;
}else if(c === '\\'){
}else if(char === '\\'){
isEscaping = true;
}else{
escapedVal += c;
escapedVal += char;
}

@@ -238,2 +232,11 @@ }

return escapedVal.trim();
}
};
module.exports = {
parse: decode,
decode,
stringify: encode,
encode,
safe,
unsafe
};
{
"name": "@nodecraft/ini",
"version": "2.1.1",
"version": "2.1.2",
"description": "An ini encoder/decoder for node",

@@ -24,12 +24,13 @@ "repository": {

"devDependencies": {
"eslint": "^7.15.0",
"eslint-config-nodecraft": "^6.2.0",
"eslint": "^7.18.0",
"eslint-config-nodecraft": "^7.2.0",
"eslint-plugin-json": "^2.1.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-unicorn": "^26.0.1",
"tap": "^14"
},
"engines": {
"node": ">=8.11.1",
"npm": ">=5.10.0"
"node": ">=12.20.0",
"npm": ">=6.14.9"
}
}
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