Skip to content

eemeli/dot-properties

Repository files navigation

dot-properties

JavaScript parse() and stringify() for .properties (text/x-java-properties) files as defined in java.util.Properties.

To install:

npm install dot-properties

For usage examples, see below or take a look through the project's test suite.

API

parse(str: string | Line[] | Node[], path?: boolean | string): object

Parses an input string read from a .properties file into a JavaScript Object

If the second path parameter is true, dots . in keys will result in a multi-level object (use a string value to customise). If a parent level is directly assigned a value while it also has a child with an assigned value, the parent value will be assigned to its empty string '' key. Repeated keys will take the last assigned value. Key order is not guaranteed, but is likely to match the order of the input lines.

parseLines(str: string, ast?: false): Line[]

Splits the input string into an array of logical lines; useful if you want to preserve order, comments and/or empty lines while processing. Used internally by parse().

Key-value pairs are [key, value] arrays with string values. Escape sequences in keys and values are parsed. Empty lines are included as empty strings '', and comments as strings that start with # or ! characters. Leading whitespace is not included.

parseLines(str: string, ast: true): Node[]

Splits the input string into an array of AST nodes; see the source for more details.

stringify(input: object, options?: StringifyOptions): string

Stringifies a hierarchical object or an array of lines or nodes to .properties format

If input is a hierarchical object, keys will consist of the path parts joined by . characters. With array input, string values represent blank or comment lines and string arrays are [key, value] pairs. Control characters and \ will be appropriately escaped. If the latin1 option is not set to false, all non-Latin-1 characters will also be \u escaped. Non-empty string lines represent comments, and will have any existing # or ! prefix replaced by the commentPrefix.

Output styling is controlled by the second (optional) options parameter; by default a spaced = separates the key from the value, \n is the newline separator, lines are folded at 80 characters (at most, splitting at nice places), with subsequent lines indented by four spaces, and comment lines are prefixed with a #. '' as a key value is considered the default, and set as the value of a key corresponding to its parent object's path:

const defaultOptions = {
  commentPrefix: '# ',  // could also use e.g. '!'
  defaultKey: '',       // YAML 1.1 used '='
  indent: '    ',       // tabs are also valid
  keySep: ' = ',        // should have at most one = or :
  latin1: true,         // default encoding for .properties files
  lineWidth: 80,        // use null to disable
  newline: '\n',        // Windows uses \r\n
  pathSep: '.'          // if non-default, use the same in parse()
}

Example

example.properties

# You are reading the ".properties" entry.
! The exclamation mark can also mark text as comments.
# The key characters =, and : should be written with a preceding
# backslash to ensure that they are properly loaded. However, there
# is no need to precede the value characters =, and : by a backslash.
website = https://en.wikipedia.org/
language = English

# The backslash below tells the application to continue reading
# the value onto the next line.
message = Welcome to \
          Wikipedia!

# Add spaces to the key
key\ with\ spaces = This is the value that could be looked up with \
                    the key "key with spaces".

# Unicode
tab : \u0009

# If you want your property to include a backslash, it should be
# escaped by another backslash
path c:\\wiki\\templates
# However, some editors will handle this automatically

Source: Wikipedia

example.js

const fs = require('fs')
const { parse, parseLines, stringify } = require('dot-properties')
const src = fs.readFileSync('./example.properties', 'utf8')

const obj = parse(src)
// { website: 'https://en.wikipedia.org/',
//   language: 'English',
//   message: 'Welcome to Wikipedia!',
//   'key with spaces':
//    'This is the value that could be looked up with the key "key with spaces".',
//   tab: '',
//   path: 'c:wiki\templates' }

const str = stringify(obj, { lineWidth: 60 })
console.log(str)
// website = https://en.wikipedia.org/
// language = English
// message = Welcome to Wikipedia!
// key\ with\ spaces = This is the value that could be looked \
//     up with the key "key with spaces".
// tab = \t
// path = c:\\wiki\\templates

const lines = parseLines(src)
// [ '# You are reading the ".properties" entry.',
//   '! The exclamation mark can also mark text as comments.',
//   '# The key characters =, and : should be written with a preceding',
//   '# backslash to ensure that they are properly loaded. However, there',
//   '# is no need to precede the value characters =, and : by a backslash.',
//   [ 'website', 'https://en.wikipedia.org/' ],
//   [ 'language', 'English' ],
//   '',
//   '# The backslash below tells the application to continue reading',
//   '# the value onto the next line.',
//   [ 'message', 'Welcome to Wikipedia!' ],
//   '',
//   '# Add spaces to the key',
//   [ 'key with spaces',
//     'This is the value that could be looked up with the key "key with spaces".' ],
//   '',
//   '# Unicode',
//   [ 'tab', '' ],
//   '',
//   '# If you want your property to include a backslash, it should be',
//   '# escaped by another backslash',
//   [ 'path', 'c:wiki\templates' ],
//   '# However, some editors will handle this automatically' ]

const str2 = stringify(lines.slice(8, 14), { lineWidth: 60 })
console.log(str2)
// # The backslash below tells the application to continue
// # reading
// # the value onto the next line.
// message = Welcome to Wikipedia!
//
// # Add spaces to the key
// key\ with\ spaces = This is the value that could be looked \
//     up with the key "key with spaces".