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

@glitchdotcom/dotenv

v1.1.0

Published

a totally tubular ๐Ÿ„๐Ÿผ library to parse and manipulate dotenv syntax

Downloads

82

Readme

@glitchdotcom/dotenv

@glitchdotcom/dotenv is a totally tubular ๐Ÿ„๐Ÿผ library to parse and manipulate dotenv syntax while maintaining comments and whitespace. @glitchdotcom/dotenv has zero dependencies, is licensed under the MIT license, and has a simple, functional api.

install

# npm
npm install @glitchdotcom/dotenv

# yarn
yarn add @glitchdotcom/dotenv

# pnpm
pnpm install @glitchdotcom/dotenv

license, code of conduct, and contributing

@glitchdotcom/dotenv is licensed under the MIT license. a copy of this license can be found in the LICENSE file.

for this project's code of conduct, see the CODE_OF_CONDUCT.md file.

do you want to contribute to something ~amazing~ (this package)? yes?? well the CONTRIBUTING.md file should tell you everything you need to know! if it doesn't, let us know (which would make a perfect first contribution)!

quickstart

to see how dotenv syntax looks as a node list, you can play with an interactive parser over at glitch.com!

import * as dotenv from "@glitchdotcom/dotenv";
// or... const dotenv = require("@glitchdotcom/dotenv");

const envText = `SOME_KEY=some value`;

// node list represents the following as an array of objects...
// SOME_KEY=some value
let nodes = dotenv.textToNodes(envText);

// find index of the key value node with SOME_KEY as the key
const index = nodes.find((node) => node.key === "SOME_KEY");

// nodes now represents...
// ANOTHER_KEY=some value
nodes = dotenv.changeKey(nodes, index, "ANOTHER_KEY");

// nodes now represents...
// ANOTHER_KEY=another value
nodes = dotenv.changeValue(nodes, index, "another value");

// nodes now represents...
// ANOTHER_KEY=another value
// NEW_KEY=new value
nodes = dotenv.appendKeyValue(nodes, "NEW_KEY", "new value");

// nodes now represents...
// NEW_KEY=new value
nodes = dotenv.removeKeyValue(nodes, index);

// newText will be "NEW_KEY=new value"
const newText = dotenv.nodesToText(nodes);

// parsedText will be { NEW_KEY: "new value" }
const parsedText = dotenv.parseText(newText);

// parsedNodes will be { NEW_KEY: "new value" }
const parsedNodes = dotenv.parseNodes(nodes);

api

node types

dotenv exports a handful of consts that represent the different types of nodes. there are 3 node types, KEY_VALUE, COMMENT, and INVALID_LINE.

example:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=value
# some comment`);

let firstCommentNode = nodes.find((node) => node.type === dotenv.COMMENT);

if (!firstCommentNode) {
	// no comment node found!
} else {
	assert(firstCommentNode.comment === "some comment");
}

node objects and properties

KEY_VALUE nodes have the following properties: type (will always be "KEY_VALUE"), key (no whitespace), value (no whitespace), escapedValue (value including escaped newlines), fullKey (includes extraneous whitespace), fullValue (includes extraneous whitespace), quote (", ', or an empty string depending on what quotes are around the value), and originalQuote (the quotes that were around the value when the text was parsed). as an example, a key-value pair like this...

# extra whitespace intentional
  SOME_KEY= some value

...will be parsed into a node like this...

{
	type: "KEY_VALUE",
	key: "SOME_KEY",
	fullKey: "  SOME_KEY",
	value: "some value",
	escapedValue: "some value",
	fullValue: " some value",
	quote: "",
	originalQuote: ""
}

if the value contained escaped newlines and quotes around it like this...

# extra whitespace intentional
  SOME_KEY=" some \n value"

...then it will be parsed into something like this...

{
	type: "KEY_VALUE",
	key: "SOME_KEY",
	fullKey: "  SOME_KEY",
	value: " some \n value", // notice the extra space in front
	escapedValue: " some \\n value",
	fullValue: "\" some \\n value\"",
	quote: "\"", // quote and originalQuote contain the quote that was used
	originalQuote: "\""
}

COMMENT nodes have the following properties: type (will always be "COMMENT"), prefix (pound symbol and extraneous whitespace before comment body), and comment (the comment body). as an example, a comment line like this...

  # a comment! leading whitespace intentional

...will be parsed into a node like this...

{
	type: "COMMENT",
	prefix: "  # ", // note the whitespace in the prefix
	comment: "a comment! leading whitespace intentional"
}

INVALID_LINE nodes have the following properties: type (will always be INVALID_LINE), and line (the contents of the line). as an example, an invalid line like this...

i am an invalid line because i do not contain an equals sign!

...will be parsed into a node like this...

{
	type: "INVALID_LINE",
	line: "i am an invalid line because i do not contain an equals sign!"
}

an important thing to note with INVALID_LINE nodes is that an empty line is also an INVALID_LINE since it doesn't contain an equals sign! empty lines aren't ignored since one of the goals of @glitchdotcom/dotenv is to preserve as much whitespace as possible. we have to capture that data somehow, so we do it with an INVALID_LINE node that has an empty string as the line property.

{
	type: "INVALID_LINE",
	line: ""
}

textToNodes/nodesToText

textToNodes converts a string to a dotenv node list that can be manipulated. the node list represents the dotenv data contained within the string as an array of nodes. it maintains comments, empty/invalid lines, and extraneous whitespace. it does everything it can to return something even if the string passed to it is not valid dotenv syntax. nodesToText does the reverse of textToNodes. it takes a node list and converts it back into a string. like textToNodes, it maintains comments, empty/invalid lines, and extraneous whitespace.

example:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=value`);
let text = dotenv.nodesToText(nodes);

assert(text === `KEY=value`);

appendKeyValue

appendKeyValue adds a new key value pair to the end of the node list. like all dotenv manipulation functions, appendKeyValue is immutable and returns a new list instead of modifying the list in place.

example:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=value`);
nodes = dotenv.appendKeyValue(nodes, "SOMETHING", "anything");
let text = dotenv.nodesToText(nodes);

assert(
	text ===
		`KEY=value
SOMETHING=anything`,
);

changeKey

changeKey changes the key of a key-value node. using changeKey does not modify any whitespace that was present in the original text. like all dotenv manipulation functions, changeKey is immutable and returns a new list instead of modifying the list in place.

examples:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=value`);
let index = nodes.find((node) => node.key === "KEY");
nodes = dotenv.changeKey(nodes, index, "SOMETHING_ELSE");
let text = dotenv.nodesToText(nodes);

assert(text === `SOMETHING_ELSE=value`);

// now with whitespace!
let nodes = dotenv.textToNodes(` KEY   =value`);
let index = nodes.find((node) => node.key === "KEY"); // the `key` property does not include whitespace
nodes = dotenv.changeKey(nodes, index, "SOMETHING_ELSE");
let text = dotenv.nodesToText(nodes);

assert(text === ` SOMETHING_ELSE   =value`); // when converting back to text, the original whitespace is preserved!

changeValue

changeValue changes the value of a key-value node. it automatically escapes newlines and adds quotes around the value if necessary. like changeKey, the original whitespace is not modified. like all dotenv manipulation functions, changeValue is immutable and returns a new list instead of modifying the list in place.

example:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=  value`); // notice whitespace
let index = nodes.find((node) => node.key === "KEY");
nodes = dotenv.changeValue(nodes, index, "another\nvalue"); // new value contains a newline
let text = dotenv.nodesToText(nodes);

// the value is now quoted and the newline was escaped! also, the preceding whitespace
// was kept intact!
assert(text === `KEY=  "another\\nvalue"`);

removeKeyValue

removeKeyValue removes a key-value node from the node list. like all dotenv manipulation functions, removeKeyValue is immutable and returns a new list instead of modifying the list in place.

example:

import * as dotenv from "@glitchdotcom/dotenv";

let nodes = dotenv.textToNodes(`KEY=value
SOMETHING=anything`);
let index = nodes.find((node) => node.key === "SOMETHING");
nodes = dotenv.removeKeyValue(nodes, index); // removing the `SOMETHING` property
let text = dotenv.nodesToText(nodes);

assert(text === `KEY=value`);

parseText

parseText takes dotenv text and extracts the key-value pairs into an object (similar to the original dotenv package).

example:

import * as dotenv from "@glitchdotcom/dotenv";

let env = dotenv.parseText(`KEY=value`);

assert(env.KEY === `value`);

parseNodes

parseNodes takes a node list and extracts the key-value pairs into an object. generally you'd want to use parseText, however if you've already converted the text into a node list, parseNodes would skip the text parsing step.

example:

import * as dotenv from "@glitchdotcom/dotenv";
let nodes = dotenv.textToNodes(`KEY=value`);
let env = dotenv.parseNodes(nodes);
assert(env.KEY === `value`);

Made by Glitch

\ ใ‚œoใ‚œ)ใƒŽ