npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cool-ini-parser

v1.1.2

Published

Implementation for basic configuration language which provides a structure similar to what’s found in Microsoft Windows INI files.

Downloads

44

Readme

TypeScript parser for *.ini files

Yet another parser for INI files. This parser supports multiline values without escaping the new line symbol. Sections and key/values can be indented. Comes with API for content modifications. Currently the following modifications are supported:

  • Adding keys with/without values
  • Removing keys
  • Changing the value of a key

Each modification generates a string which holds the new configuration. Modifications respect the original content's formatting and comments.

Installation

To Install run:

npm install cool-ini-parser

API

Parse API

Parse the configuration.ini file using the function parseIniFromString(...). It will return a Configuration object.

import { parseIniFromString } from 'cool-ini-parser'
import { Configuration } from "cool-ini-parser/dist/types";

const content = "..."; // The ini file content
const config: Configuration = parseIniFromString(content);

Configuration

  • indentSymbol: string - The last key's indentation symbol (' ' or '\t'). This symbol will be used when new key/values are added and they need to be indented.
  • content: string - The string content of the configuration.
  • sections: Section[] - Array of parsed sections

Section

  • startOffset: number - Index in the Configuration.content string where this section starts. Used internally for modifications.
  • endOffset: number - Index in the Configuration.content string where this section ends. Used internally for modifications.
  • name: string - The name of the section
  • entries: SectionEntry[] - Array of parsed key/values

SectionEntry

  • key - The name of the key
  • value - The parsed value, trimmed of whitespaces. Multiline values will be separated by '\n'. Keys without a value will return empty string.
  • rawValue - The value with all whitespaces and indentations.
  • keyStartOffset - The start index of the key
  • valueStartOffset - The start index of the value. If no value is pressent, the index will be -1.
  • rawValueEndOffset - The index of the last symbol in the rawValue. Usually this will be a new line or the EOF. If no value is pressent, the index will be -1.
  • delimiterOffset - The index of the key/value delimiter. If no delimiter is pressent, the index will be -1.

Modification API

Adding a key with value

import { parseIniFromString, addConfigurationSectionKey } from 'cool-ini-parser';
import { Configuration } from "cool-ini-parser/dist/types";

const content: string = '...';
const config: Configuration = parseIniFromString(content);

const newContent: string = addConfigurationSectionKey(config, "section", "newKey", "newValue");
  • addConfigurationSectionKey(config: Configuration, section: string, key: string, value: string): string | undefined - adds a key with value at the end of the section to the configuration. If there are multiple sections with the same name, the key will be added to the first section.
    input parameters:
    config - The configuration object to modify
    section - The name of the section to which the key should be added.
    key - The name of the new key
    value - The value string. If a multilined value needs to be added, you can concatenate it with just new lines ('\n'). The API will format and indent it as necessary. If you want to add just a key without a value, pass an empty string for value. A key without a delimiter will be added.
    return value - A string with the modified content. The original content's comment and indentation is preserved. Returns undefined if any error is detected, like invalid section name.

  • addConfigurationSectionKeyByIndex(config: Configuration, sectionIdx: number, key: string, value: string): string | undefined - If the configuration file has multiple sections with the same name, this method will let you specify the section's index for better control of where to add the new key.

Removing a key

import { parseIniFromString, removeConfigurationSectionKey } from 'cool-ini-parser'
import { Configuration } from "cool-ini-parser/dist/types";

const content: string = '...';
const config: Configuration = parseIniFromString(content);

const newContent: string = removeConfigurationSectionKey(config, "section", "key");
  • removeConfigurationSectionKey(config: Configuration, section: string, key: string): string | undefined - removes a key from the section. If there are multiple sections with the same name, the first found section will be selected. Same goes for the key.
    input parameters:
    config - The configuration object to modify
    section - The name of the section from which the key should be removed.
    key - The name of the key to remove
    return value - A string with the modified content. The original content's comment and indentation is preserved. Returns undefined if any error is detected, like invalid section name.

  • removeConfigurationSectionKeyByIndex(config: Configuration, sectionIdx: number, keyIdx: number): string | undefined - If the configuration file has multiple sections with the same name and keys this method will let you specify the section and key indexes for better control of where to remove the key.

Modifing the value of a key

import { parseIniFromString, modifyConfigurationSectionKey } from 'cool-ini-parser'
import { Configuration } from "cool-ini-parser/dist/types";

const content: string = '...';
const config: Configuration = parseIniFromString(content);

const newContent: string = modifyConfigurationSectionKey(config, "section", "newKey", "newValue");
  • modifyConfigurationSectionKey(config: Configuration, section: string, key: string, newValue: string): string | undefined - modifies the value of a key. If there are multiple sections with the same name, the first found section will be selected. Same goes for the key.
    input parameters:
    config - The configuration object to modify
    section - The name of the section in which the key should be modified.
    key - The name of the key to modify
    value - The new value to set
    return value - A string with the modified content. The original content's comment and indentation is preserved. Returns undefined if any error is detected, like invalid section name.

  • modifyConfigurationSectionKeyByIndex(config: Configuration, sectionIdx: number, keyIdx: number, newValue: string): string | undefined - If the configuration file has multiple sections with the same name and keys this method will let you specify the section and key indexes for better control of where to modify the key.

Basic rules

This parser follows the native Python 3 configparser rules (https://docs.python.org/3/library/configparser.html) which in turn follows the Microsoft Windows INI files structure.

Sections

  • Section headers are mandatory. If a key is declared before a section, the parser will throw an exception.
  • Sections must always be on a single line
  • No non-whitespace charecters are allowed on the same line outside the section's perimeter ('[' and ']'). Comments are allowed.
    ✅ [section name]
    ✅ [section name] ; Comment
    ❌ [section] name
    ❌ [section] name ; Comment
  • Sections can be indented
    ✅ |[section name]
    ✅ | [section name]

Keys and Values

  • A key/value pair is delimited by the symbols ':' and '='
    ✅ key : value
    ✅ key = value
  • Keys can have empty values:
    ✅ key
    ✅ key =
  • A value can spawn multiple lines. For a new line to be considered as a value line, it needs to be more indented than the key it belongs to.
key = value
 value

This will give us a single key key with value value\nvalue

key = value
value

This will give us two keys: key with value value and value with empty value

  • Key's indentationis not linked to the section's indentation. The following are all valid cases:
[section]
    key = value
    [section]
key = value
  • The keys in the same section are restricted to the same indentation. Multiple keys in the same section can have different indentation, but only in a decreasing amount.
[section]
        key1 = value1
    key2 = value2
key3 = value3

This example will give us 3 keys with their respective values.

[section]
    key1 = value1
        key2 = value2
key3 = value3

This example however will give us 2 keys:
      key1 with value: value1\nkey2 = value2
      key3 with value: value3

  • The key's value can have multiple blank lines. The indentation restriction of the value still applies
key =


    value

This will produce a key with value value

  • The key's delimiter MUST BE on the same line as the key's definition. The following are invalid examples

❌ Invalid example

    key
        = value

❌ Invalid example

    key
        =
        value

❌ Invalid example

    key
    =
     value

Comments

  • Comments start with the symbols ';' and/or '#' and end at the end of the line.
  • Once a comment is started, it always ends at the end of the line.
  • Comments are single line only. There is't a comment block symbol.
    ; Comment line 1
    ; Comment line 2
    # Comment line 3
    [section] ; Comment line 4
    key = value # Comment line 5
    # Comment ; line 6
    key2 = value
    ; Comment # line 7
    key3 = value
  • Every symbol after the comment symbol is ignored by the parser.
  • The TypeScript objects DO NOT hold any comments.
  • Comments are "invisible" to the parser and can not be retrieved.
  • The modification API will preserve any comments that are not intertwine in a value. This means that any comment that is on the same line as a value, which is going to change, will be lost. Values that spawn multiple lines and have comments inbetween their lines will also lose their comments.

Changelog

v1.1.2

  • Bugfix: Adding new key would always be inserted into the first section, instead of the target section.

v1.1.1

  • Update README.md

v1.1.0

  • Rename method parseInitFromString to parseIniFromString
  • Reorganize repository structure
  • Move tests next to sources
  • Build only with NodeNext flag
  • Update documentation

v1.0.0

  • Initial version