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

properties-files

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

properties-files

.properties files parser, JSON converter and Webpack loader.

  • 0.1.2
  • unpublished
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

properties-files

License npm download Coverage Dependencies Known Vulnerabilities

.properties files parser, JSON converter and Webpack loader.

Installation 💻

Add the package as a dependency:

npm install properties-files

What's in it for me? 🤔

  • A modern TypeScript library that reproduces exactly the Properties Java implementation.
  • Flexible APIs:
    • propertiesToJson allows quick conversion from .properties files to JSON.
    • getProperties returns a Properties object that allows insights into parsing issues such as key collisions.
    • propertiesToJson & getProperties also have a browser-compatible version when passing directly the content of a file.
    • Out of the box Webpack loader to import .properties files directly in your application.
  • 100% test coverage based on the output from a Java implementation.
  • Active maintenance (many popular .properties packages have been inactive years).

Usage 🎬

We put a lot of effort into adding TSDoc to all our APIs. Please check directly in your IDE if you are unsure how to use certain APIs provided in our examples.

All APIs under properties-files/file depend on fs which means they cannot be used by browsers. If you cannot use fs and already have a .properties file content, the same APIs are available under properties-files/content. Instead of taking the filePath as the first argument, they take content. The example below will use properties-files/file since they are the most common use cases.

propertiesToJson

This API is probably the most used. You have a .properties file that you want to open and access like a simple key/value JSON object. Here is how this can be done with a single API call:

import { propertiesToJson } from 'properties-files/file';

console.log(propertiesToJson('hello-world.properties'));

Output:

{ hello: 'hello', world: 'world' }

getProperties (advanced use case)

Java's implementation of Properties is quite resilient. In fact, there are only two ways an exception can be thrown:

  • The file is not found.
  • A (\u) Unicode escape character is malformed.

This means that almost all files will be valid.

But what about a file that has duplicate keys? Duplicate keys have no reason to exist and they probably should have thrown errors as well but instead Java decided to simply overwrite the value with the latest occurrence in a file.

So how can we know if there were duplicate keys if we want to log some warnings? Simply by using getProperties which will return all the data that was used to parse the content. Here is an example on how it can be used:

# collisions-test.properties
hello: hello1
world: world1
world: world2
hello: hello2
world: world3
import { getProperties } from 'properties-files/file';

const properties = getProperties('assets/tests/collisions-test.properties');

properties.collection.forEach((property) => {
  console.log(`${property.key} => '${property.value}'`);
});

/**
 * Outputs:
 *
 * hello => 'hello2'
 * world => 'world3'
 *
 */

const keyCollisions = properties.getKeyCollisions();

keyCollisions.forEach((keyCollision) => {
  console.warn(
    `Found a key collision for key '${
      keyCollision.key
    }' on lines ${keyCollision.startingLineNumbers.join(
      ', '
    )} (will use the value at line ${keyCollision.getApplicableLineNumber()}).`
  );
});

/**
 * Outputs:
 *
 * Found a key collision for key 'hello' on lines 1, 4 (will use the value at line 4).
 * Found a key collision for key 'world' on lines 2, 3, 5 (will use the value at line 5).
 *
 */

Webpack File Loader

If you would like to import .properties directly using import, this package comes with its own Webpack file loader located under properties-files/webpack-loader. Here is an example of how to configure it:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.properties$/i,
        use: [
          {
            loader: 'properties-files/webpack-loader',
          },
        ],
      },
    ],
  },
};

As soon as you configure Webpack, the .properties type should be available in your IDE when using import. If you ever need to add it manually, you can add a *.properties type declaration file at the root of your application, like this:

// properties-files.d.ts
declare module '*.properties' {
  const properties: { readonly [key: string]: string };
  export default properties;
}

By adding these configurations you should now be able to import directly .properties files just like this:

import helloWorld from './hello-world.properties';

console.dir(helloWorld);

Output:

{ "hello": "world" }

Why another .properties file package?

There are probably over 20 similar packages available but:

  • A lot of the most popular packages have had no activity for over 5 years.
  • A large portion of the packages will not replicate the current Java implementation.
  • No package offers the same capabilities as this one.

Unfortunately the .properties file specification is not well documented. One reason for this is that it was originally used in Java to store configurations. Most applications will handle this using JSON, YAML or other modern formats today because the formats are more flexible.

So why .properties files?

While many options exists today to handle configurations, .properties file remain one of the best option to store localizable strings (also known as messages). On the Java side, PropertyResourceBundle is how most implementations handle localization today. Because of its simplicity and maturity, .properties files remain one of the best options today when it comes to internationalization (i18n):

File formatKey/value basedSupports inline commentsBuilt for localizationGood linguistic tools support
.propertiesYesYesYes (Resource Bundles)Yes
JSONNo (can do more)No (requires JSON5)NoDepends on the schema
YAMLNo (can do more)YesNoDepends on the schema

By having good JavaScript/TypeScript support for .properties files, it provides more options when it comes to i18n.

How does this package work?

Basically our goal was to offer parity with the Java implementation, which is the closest thing to a specification .properties file have. Here is in a nutshell the logic behind this package:

  1. Split the file content by lines (create line objects)
  2. Create LineObjects by combining multi-line properties and removing trailing backslash
  3. Create PropertyObjects from LineObjects that combined all lines of a property
  4. Identify the key/value delimiter and populate escaped keys and values.
  5. Unescape keys and values
  6. Create a PropertiesObject that will include all PropertyObjects while removing collisions

Just like Java, if a Unicode escaped characters (\u) is malformed, it will throw an error. But of course, we do not recommend using Unicode escaped characters but rather UTF-8 encoding that supports more characters.

Additional references

Keywords

FAQs

Package last updated on 04 Jun 2022

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