silk.npm.ini.

Parse the ini text of an .npmrc file into keys and values, the way npm reads it.

When to use#

Use NpmIni.parse to read one .npmrc file, or any other file in the ini dialect of npm's ini package. Find a key with NpmIni.find. To read npm's whole configuration, with environment variables, scoped registries, credentials, and the user, project, and global files, use silk.npm.config instead.

Details#

Each line is a comment, a [section] header, or a key = value assignment:

  • A line whose first non-blank character is ; or # is a comment. Blank lines are skipped.

  • [name] at the start of a line opens a section. npm reads only the keys before the first header; find them with NpmIni.find, and keys in a section with NpmIni.findIn.

  • key = value splits at the first =. A line without = sets the key to true. A line that starts with = is skipped.

  • Keys and values are trimmed. A value in " quotes that is a valid JSON string is decoded as JSON. A value in ' quotes loses the quotes, and is decoded as JSON if what is left is a JSON string. In an unquoted value, ; or # starts a comment, and \;, \#, and \\ stand for ;, #, and \.

  • After that, the text true, false, or null becomes a boolean or a null.

  • A key that ends with [] is a list. Each assignment adds one item.

  • When a key is assigned again, the last value wins, and the entry keeps the place of the first.

  • The key and section __proto__ are ignored, as npm ignores them.

The input is read as UTF-8, and each invalid sequence becomes U+FFFD. A byte order mark stays, as it does in npm: it is trimmed from a key, but a [section] header right after it is read as a key.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the entries. Parsing has no other error: like npm, it skips the lines it cannot read.

Gotchas#

The text of a value is not checked against npm's types: 2 stays the text 2. Dots in a section name are kept. npm does not nest sections in its configuration.

Examples#

Read a token and a list#

silk
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.core.option { Option }
import silk.npm.ini { NpmEntry, NpmIni, NpmScalar }
import silk.collections.list { List }

pub effect fn main() -> i32
  ! OutOfMemoryError {
  let mut allocator = Allocator.systemAllocatorProvider()
  let source = b"//registry.npmjs.org/:_authToken = abc ; a comment\nca[] = one\nca[] = two\n"
  let entries = run NpmIni.parse(source) |> Effect.provideMut<Allocator>(&mut allocator)
  let token = NpmIni.text(&entries, "//registry.npmjs.org/:_authToken") |> Option<string>.unwrapOr("")
  let count = match NpmIni.find(&entries, "ca") {
    Option<&NpmEntry>.Some { value } => List<NpmScalar>.length(&value.values)
    Option<&NpmEntry>.None => 0
  }
  if token != "abc" || count != 2 {
    return 1
  }
  return 0
}

Import as NpmIni with import silk.npm.ini { NpmIni }.

Public declarations: 3.

NpmScalar#

silk
pub union NpmScalar

One value of an ini entry: text, a boolean, or a null.

Null#

silk
Null

The text null.

Boolean#

silk
Boolean

The text true or false.

Field value#

silk
pub value: bool

The boolean.

Text#

silk
Text

Any other text, with quotes, escapes, and comments removed.

Field text#

silk
pub text: String

The decoded text.

NpmEntry#

silk
pub struct NpmEntry

One key of an ini file, with its section and its values.

Field section#

silk
pub section: String

The name of the section, or "" for keys before the first [section] header.

Field sectioned#

silk
pub sectioned: bool

false for keys before the first [section] header. A header [] opens a section named "", which is not the same as no section.

Field key#

silk
pub key: String

The decoded key. For a list, the [] at the end is removed.

Field values#

silk
pub values: List<NpmScalar>

The values in source order. A key that is not a list has exactly one value.

Field list#

silk
pub list: bool

true if the key was written with [] at the end.

NpmIni#

silk
pub struct NpmIni

Functions that parse the ini text of .npmrc files and find keys in the result.

When to use#

Use NpmIni.parse to read one .npmrc file, and NpmIni.find or NpmIni.text to read a key. Use silk.npm.config to read npm's whole configuration.

Implementation NpmIni#

silk
impl NpmIni

Associated function parse#

silk
pub effect fn parse(bytes: &[u8]) -> List<NpmEntry>
    ! OutOfMemoryError
    ? &mut Allocator

Returns the entries of the ini text bytes, in the order of their first assignment.

Details#

Each line is a comment (first non-blank character ; or #), a [section] header at the start of the line, or a key = value assignment split at the first =. A line without = sets the key to true. Keys and values are trimmed. A value in " quotes that is a valid JSON string is decoded as JSON. A value in ' quotes loses the quotes, and is decoded as JSON if what is left is a JSON string. In an unquoted value, ; or # starts a comment, and \;, \#, and \\ stand for ;, #, and \. The text true, false, or null then becomes a boolean or a null. A key that ends with [] is a list, and each assignment adds one item. For other keys the last assignment wins. The key and section __proto__ are ignored.

The input is read as UTF-8, and each invalid sequence becomes U+FFFD. A byte order mark stays, as it does in npm: it is trimmed from a key, but a [section] header right after it is read as a key.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the entries. Lines that cannot be read are skipped, as npm skips them.

Associated function find#

silk
pub fn find<'a>(entries: &'a List<NpmEntry>, key: string) -> Option<&'a NpmEntry>

Returns the entry for key before the first [section] header, or None if there is no such key.

Details#

npm reads only these keys. key is the decoded key; for a list, leave out the []. Keys compare byte for byte, so case matters.

Associated function findIn#

silk
pub fn findIn<'a>(entries: &'a List<NpmEntry>, section: string, key: string) -> Option<
    &'a NpmEntry
  >

Returns the entry for key in the section section, or None if there is no such key.

Details#

It finds only keys after a [section] header with the decoded name section. Use NpmIni.find for keys before the first header. key is the decoded key; for a list, leave out the []. Names compare byte for byte, so case matters.

Associated function text#

silk
pub fn text<'a>(entries: &'a List<NpmEntry>, key: string) -> Option<string<'a>>

Returns the text of the first value of key before the first [section] header.

Details#

Returns None if there is no such key, or if its first value is a boolean or a null. The text borrows from entries.

Associated function firstText#

silk
pub fn firstText<'a>(entry: &'a NpmEntry) -> Option<string<'a>>

Returns the text of the first value of entry, or None if that value is a boolean or a null. The text borrows from entry.

Category: Data formats.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.

View the source of this page