Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@evs-chris/ts-typed-config
Advanced tools
Read typed custom config files written in typescript because reasons
If you prefer config files to env vars, like the benefits of typescript's type checking, and would like to have strongly typed, verifiable config files, then this module is probably for you.
This wraps up typescripts compiler API in such a way that you specify a source config definition consisting of a Config
interface, a list of config files to pull in, an initial config state, and an optional result callback to handle logging and errors to execute your config files in a safe way against the initial state. Everything is synchronous, so you can safely reference config variables in other modules as long as your config module is the first thing you reference in your entry file.
eval
, so if you can't trust your config files, don't use it.src/config.ts
import { Config } from './config-type';
import { config as readConfig } from '@evs-chris/ts-typed-config';
import * as path from 'path';
// everything will import { config } from './config'
export let config: Config = {};
const handle = readConfig({
// config files we want to consider - missing files are ignored
configFilePaths: [
'/etc/mythingy/config.ts', // system-wide mythingy
path.join(process.env.HOME, '.mythingy.config.ts') // my very own special mythingy
// files are applied in order to the existing config object, and you can put them
// wherever you want
],
// if your config only has the Config interface in it and/or other type-only defs, you
// can reference the ts source otherwise, you probably want to reference the compiled
// file and make sure it has a companion definition file
// __dirname can be your friend here as well
localSource: path.resolve('./dist/config-type.js'),
// the initial config object in case there are no config files - defaults
// you could supply a reload function that returns a Config if you want to
// start fresh on any reloads - then init is optional, but at least one is required
init: config,
// the result callback is also optional, but it gives you an opportunity to handle
// any errors in both syntax and execution of config files
result(res) {
// if the file loaded, say so
if (f.loaded) {
console.log(`Loaded config from ${res.name}`);
}
// if there were errors, pop 'em out - files with errors never load
else if (f.errors.length) {
console.error(f.errors.map(e => {
return `${e.type}: ${e.file} - ${e.message
}\n ${e.line}| ${e.text
}\n ${Array.apply(Array, new Array(e.line.toString().length + e.col)).map(_ => ' ').join('')} ^`;
}).join('\n'));
// and bail
process.exit(1);
}
// if there was an exception running the file
else if (f.exception) {
console.error(`Error: Exception loading config from ${f.name
}\n ${f.exception}`);
process.exit(1);
}
}
});
// not strictly necessary, but if you want to pull in changes without punting the whole process
export function reload() {
handle.reload();
}
src/config-type.ts
// you can feel free to import whatever here, as the import space is swizzled around
// such that it appears to typescript to be coming from the localSource during execution
// this is your main config interface/class/type
export interface Config {
debug?: boolean;
mailers?: {
user?: MailConfig,
system?: MailConfig
};
port?: number
}
export type MailConfig = MockMailConfig | ServerMailConfig;
export interface MockMailConfig {
mock: true;
}
export interface ServerMailConfig {
transport: string;
server: string;
user: string;
password: string;
port: number;
}
~/.mythingy.config.ts
// config is set up as a global for the scope of this code and will already have
// the defaults plus any prior config files/runs applied
// note that the Config type from your localSource is automatically imported
// if you need to import other things the special $CONFIG variable will be swapped with
// the path to the localSource file before the config is evaluated
// make sure that you also include the Config type if you do so e.g.
// import { Config, Other, Things } from '$CONFIG';
// this is my mythingy dev machine, and oogieboogie is always running on port 3000
config.port = 3001;
// give me all those sweet, sweet log messages on the console
config.debug = true;
// send system generated mail, but mock mail generated by user interaction
config.mailers = {
user: { mock: true },
system: {
transport: 'gmail',
server: 'mail.google.com',
user: 'larry',
password: 'totes not doing evil',
port: 5454
}
}
If you just want the darn config loaded and don't care about anything else:
import { Config } from './config-type';
import { config as readConfig } from '@evs-chris/ts-typed-config';
import * as path from 'path';
export let config: Config = {};
readConfig({
configFilePaths: [
path.join(process.env.HOME, '.mythingy.config.ts'),
'/etc/mythingy/config.ts'
],
localSource: path.resolve('./dist/config-type.js'),
init: config
});
FAQs
Read typed custom config files written in typescript because reasons
We found that @evs-chris/ts-typed-config demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.