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

@mbarlocker/typescript-config

v0.0.7

Published

Remote, reloadable, typesafe configuration for node apps.

Downloads

357

Readme

typescript-config

CI NPM version License

A configuration utility that can load and reload values from remote sources.

Installation

yarn add @mbarlocker/typescript-config

Features

The entire purpose for this project is to get simple, promise-based, pre-cached configuration capable of loading from remote data stores like files, ec2 instance metadata, AWS secrets manager, and AWS Parameter Store.

  • Object like configuration
  • Branch for environments, roles, etc
  • Promise-based with local caching
  • Reload individual or all values
  • Remote data stores
  • Custom data stores

Things that it doesn't do:

  • Local override files (although you can accomplish this by using any of the remote loaders to store a local file)

Usage

The API was designed for a config file that looks like this:

import { Config } from '@mbarlocker/typescript-config'

export const config = new Config({
	db: {
		hostname: {
			$env_production: '1.1.1.1',
			$env_development: 'localhost',
		},
		user: 'myuser',
		password: {
			$env_production: '${file:///secrets/db.password}',
			$default: 'dev',
		},
		port: {
			$default: 3306,
		},
	},
	...
})

config.branch('env', 'development' /* would likely use process.env.NODE_ENV or similar */)
await config.load()

const hostname = config.value('db.hostname').string() // localhost
const user = config.value('db.user').string() // myuser
const password = config.value('db.password').string() // dev
const port = config.value('db.port').int() // 3306

It also works with promises and reloading

export const config = new Config({ ...fromAbove })

config.branch('env', 'production')
// waiting isn't necessary if you're using promises
// await config.load() 

const password = (await config.promise('db.password')).string() // whatever the contents of /secrets/db.password are, as text

Supported Loaders

Built in loaders support the following schemas.

| Schema | Description | Example | | :----- | :---------- | :------ | | file:// | Read the contents of a file on the local filesystem with the utf-8 encoding | file:///a/b/c will read /a/b/c | | bfile:// | Read the contents of a file on the local filesystem as a buffer | bfile:///a/b/c will read /a/b/c as a buffer | | http:// | Make an HTTP GET request to the specified location and return the body as a string using utf-8 encoding | http://www.google.com/ will return Google's homepage as a string | | https:// | Same as http:// but for HTTPS | https://www.google.com/ will return Google's homepage as a string | | bhttp:// | Same as http:// but return a Buffer | bhttp://www.google.com/ will return Google's homepage as a Buffer | | bhttps:// | Same as https:// but return a Buffer | bhttps://www.google.com/ will return Google's homepage as a Buffer |

Custom loaders can be registered with the Config prior to the .load() call.

import { Loader } from '@mbarlocker/typescript-config'
import { Config } from '@mbarlocker/typescript-config'

const config = new Config({
	host: {
		ipv4: {
			$ENV_local: '127.0.0.1',
			$default: '${ec2://latest/meta-data/public-ipv4}',
		},
	},
})

config.branch('ENV', process.env.NODE_ENV)
config.registerLoader('ec2://', (data) => fetch(`http://169.254.169.254/${data.url}`))
await config.load()

config.value('host.ipv4') // returns either 127.0.0.1 or the response from the EC2 metadata server

Remote Values

All values that are to be loaded by the registered loaders have to be designated. The way to do this is to use ${url}. This has the potential to conflict and cause errors if you surround them with backticks, but is meant to indicate to your brain that these are variables. Just be careful when using quotes and backticks and you shouldn't have an issue.

// GOOD values - notice the single quotes
const config = new Config({
	db: {
		url: 'mysql://user:pass@host:port/db',
		key: '${http://secrets.host.com/db/key.txt}',
	},
})

// BAD values - notice the backticks
const config = new Config({
	db: {
		url: 'mysql://user:pass@host:port/db',
		key: `${http://secrets.host.com/db/key.txt}`,
	},
})

Reloading

It's easy to set up configuration reloading. Just remember that you'll need to await the response if you want to verify that all of them have been loaded. Entries that fail to refresh will continue to be cached.

await config.refresh()

While the values are being refreshed, the old cached values will continue to be served. If you'd like to make sure that the new values are being used, get the .promise('path.to.my.value') version. That will always return the newest value, even if that value hasn't been finished or will end with an error.

License

Copyright © 2023-present Matthew Barlocker.

@mbarlocker/typescript-config is licensed under the MIT License. See LICENSE for the full license text.