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

properties

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

properties

Properties parser/stringifier

  • 0.3.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
443K
decreased by-38.3%
Maintainers
1
Weekly downloads
 
Created
Source

properties

Node.js project

Properties parser/stringifier

Version: 0.3.1

The module implements the Java properties specification and gives to you a powerful set of features that can be enabled or disabled at any time. Json files can be used to store complex data structures such as arrays or nested objects, but if you only want to save some properties, e.g. the database uri connection and credentials, valid json files can become a bit overloaded with metadata: curly braces, colons, commas and especially a lot of double quotes. Compare this two versions:

c = 1
[a]
a = 1
[b]
b = 1
{
	"a": {
		"a": "1"
	},
	"b": {
		"b": "1"
	},
	"c": "1"
}

Which do you prefer? Which is more readable? Can you write comments in json files?

The stringified properties are parsed the right way reading character by character instead of reading lines, splitting them, using regular expressions and all the easy to implement but slow techniques.

There are several additional features you can use, some of them are: sections, variables, define your custom comment and key-value separator characters, replacers and revivers similar to the json callbacks, pretty print the stringified properties, convert special characters to their unicode string representation, write comments, parse/stringify INI files and much more.

The disk access is buffered to reduce the memory footprint. The default buffer size is 16KB, a quite large for a simple properties file. Most often you'll have small files (less than 1KB, maybe 2KB), so a single I/O call will be done, but it's better to support buffering, just in case. If you prefer, you can avoid the buffers and work with strings with the parse() and stringify() functions, so you decide how to do the I/O access -typically you'll use fs.readFile() and fs.writeFile()-

The properties are case sensitive.

Installation
npm install properties
Example
var properties = require ("properties");

properties.config ({
	comment: "# ",
	separator: " = ",
	sections: true
});

var p = {
	p1: "v1",
	p2: null,
	p3: {
		$comment: "A property",
		$value: "v3"
	},
	p4: {
		$comment: "An empty property\nwith multi-line comment"
	},
	s1: {
		p1: 1,
		p2: 2
	}
};

properties.store ("file", p, { header: "My header" }, function (error){
	if (error) return console.log (error);
	properties.load ("file", function (error, p){
		if (error) return console.log (error);
		console.log (p);
		
		/*
		Prints:
		
		{
			p1: "v1",
			p2: null,
			p3: "v3",
			p4: null,
			s1: {
				p1: 1,
				p2: 2
			}
		}
		*/
	});
});

file:

# My header

p1 = v1
p2 = 
# A property
p3 = v3
# An empty property
# with multi-line comment
p4 = 
Features
Sections

To add a section just write:

[<name>]

Example:

[My Section]

Additional information:

  • The keys next to a section header will belong to that section.
  • Different sections can have keys with the same name.
  • The keys added before the first section are considered global and don't belong to any section.
  • It's not possible to nest sections inside other sections.
  • Duplicate sections replaces the previous section with the same name, they are not merged.

Enable:

properties.config ({ sections: true });

Disable:

properties.config ({ sections: false });

Sections are disabled by default.

Variables

To get the value of a key:

a = 1
b = ${a}

The value of b will be 1.

Take into account that the keys can belong to sections. In the previous example, a and b are global properties. To reference a key within a section just prefix the section followed by a |. Example:

a = 1
[Section1]
a = 2
[Section2]
a = 3
b = ${a}${Section1|a}${Section2|a}

The value of b will be 123.

You can also nest variables inside other variables, in other words, you can create variables dynamically. Example:

[Section1]
a = 12
[Section2]
123 = a
b = ${Section2|${Section1|a}3}

The value of b will be a.

You can use a variable anywhere. Look at the examples to see what you can do with variables.

Enable:

properties.config ({ variables: true });

Disable:

properties.config ({ variables: false });

Variables are disabled by default.

If you want to enable both the sections and the variables just write:

properties.config ({ variables: true, sections: true });
Customize tokens

You can also add new characters that can be used to write comments or to separate keys from values. For example, we want parse a text that uses ; to write comments:

properties.config ({ allowedComments: [";"] });

The properties specification says that # and ! can be used to write comments. These characters will always be allowed, so the allowedComments property adds ; to the valid set of tokens to write comments.

Similarly, you can add new characters to separate keys from values:

properties.config ({ allowedSeparators: ["-", ">"] });

allowedComments and allowedSeparators are used to parse the files. If you want to stringify an object and write comments with ; and separators with - you have to use comment and separator:

properties.config ({ comment: "; ", separator: " - " });

To reset to the default values:

properties.config ({
	comment: null,
	allowedComments: [],
	separator: null,
	allowedSeparators: []
});
INI files

Enabling the sections and adding ; to the set of valid characters to write comments this module can also parse and stringify INI files:

properties.config ({
	sections: true,
	comment: "; ",
	allowedComments: [";"]
});

Take into account that comment and separator can contain blank spaces (space, \t or \f) but allowedComments and allowedSeparators expect an array of characters.

Methods

properties.config([settings])
Enables and configures additional features.

The possible settings are:

  • comment. String. The characters used to write comments. It's used when the object is stringified. Default is #.
  • separator. String. The characters used to separate keys from values. It's used when the object is stringified. Default is =.
  • allowedComments. Array. An array of characters that can be used to parse comments. # and ! are always considered comment tokens.
  • allowedSeparators. Array. An array of characters that can be used to parse key-value separators. =, : and <blank space> are always considered separator tokens.
  • sections. Boolean. Enables the sections usage. Default is false.
  • variables. Boolean. Enables the variables usage. Default is false.

properties.load(file[, settings], callback)
Loads a properties file. The callback receives the error and the loaded properties. The loaded properties are just a JavaScript object in literal notation.

The possible settings are:

  • encoding. String. ascii or utf8. Default is utf8.

  • bufferSize. Number. The buffer size used while reading the file. Default is 16KB.

  • reviver. Function. Callback executed for each property and section. Its funcionality is similar than the json reviver callback. The reviver receives two parameters, the key and the value. The returned value will be stored in the final object. If the function returns undefined the property is not added. If sections are enabled the reviver receives a third parameter, the section. When a section is found, the key and the value are set to null. The returnd value will be used to store the section, if it's undefined the section is not added.

    For example, a reviver that does nothing:

    properties.config ({ sections: true });
    
    var reviver = function (key, value, section){
    	console.log (key, value, section);
    	
    	/*
    	Prints:
    	
    	a 1 null
    	null null "section 1"
    	a 1 section 1
    	null null "section 2"
    	a 1 section 2
    	*/
    	
    	if (key === null){
    		//Section found
    		return section;
    	}
    	return value;
    }
    
    properties.load ("file", { reviver: reviver }, function (error, props){
    	console.log (props);
    	
    	/*
    	Prints:
    	
    	{
    		a: 1,
    		"section 1": {
    			a: 1
    		},
    		"section 2": {
    			a: 1
    		}
    	}
    	*/
    });
    

    file:

    a = 1
    [section 1]
    a = 1
    [section 2]
    a = 1
    

properties.parse(str[, settings]) Does the same as load() but does not perform any I/O access, the input is the given string. The only setting property is the reviver. Only throws exceptions if the variable substitution is enabled.

properties.store(file, obj[, settings], callback)
Stores a JavaScript object in literal notation -the properties- to a file. The callback receives a possible error.

All the non printable unicode characters (C0 and C1 control codes: 0-31 and 127-159) are converted to its unicode string representation, e.g. 0x00 (NUL) is converted to \u0000.

The properties can be null and can have comments. To write comments you must use an object with a $comment and $value properties. Some examples:

var props = {
	a: "a value",
	b: null,
	c: {
		comment: "c comment",
		value: "c value"
	},
	d: {
		comment: "d comment",
		value: null
	},
	e: {
		comment: "e comment"
		//No value, the same as d
	},
	f: {
		//No comment, the same as a
		value: "f value"
	},
	g: {
		//No comment and no value, the same as b if sections are disabled
		//If sections are enabled this is a section with no properties
	},
	h: {
		$comment: "h section",
		$value: {
			a: "a value",
			b: {
				$comment: "b comment",
				$value: "b value"
			}
		}
	}
};

The possible settings are:

  • encoding. String. ascii or utf8. If ascii is used, all the characters with code greater than 127 are converted to its unicode string representation. Default is utf8.
  • bufferSize. Number. The buffer size used while writing the file. Default is 16KB.
  • header. String. A comment to write at the beginning of the file.
  • pretty. Boolean. If true, the stringified properties are well formatted: tabbed and word wrapped at 80 columns.
  • replacer. Function. The same as the reviver function but if the returned value is undefined the property or section is not stringified. Receives two parameters and optionally three if section are enabled.

The comments (from properties and header) can be written as a multi-line comment, for example, if you write a property:

a: {
	comment: "line 1\nline2"
	value: "b"
}

Then this will be written:

#line 1
#line 2
a=b

The line separator could also be \r\n. Line separators are only used to split the comment, that is, if you're on Linux and write a comment line1\r\nline2, a \n will be used to write these lines.

Please, note that the ECMAScript specification does not guarantee the order of the object properties, so the module cannot guaranteee that the properties will be stored with the same order. This modules guarantees that if sections are enabled, the global properties will be written before the sections to avoid possible errors.

ECMA-262 does not specify enumeration order. The de facto standard is to match insertion order, which V8 also does, but with one exception: V8 gives no guarantees on the enumeration order for array indices (i.e., a property name that can be parsed as a 32-bit unsigned integer).

properties.stringify(obj[, settings]) Does the same as store() but does not perform any I/O access, the output is a string. The possible setting properties are the pretty boolean and the reviver.

Keywords

FAQs

Package last updated on 03 Jan 2013

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

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