Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
varcor
Advanced tools
Readme
varcor
is a tool for streamlined management of config values, offering normalization and type enforcement.
To get started with varcor, install the package via npm:
npm install varcor
The Result
type is used to return values or errors throught varcor.
type ResultSuccess<T> = { success: true; value: T; };
type ResultFailure<F> = { success: false; error: F; };
type Result<T, F> = ResultSuccess<T> | ResultFailure<F>;
// Helper methods
const Result = Object.seal({
success: <T>(value: T): ResultSuccess<T> => ({ success: true, value }),
failure: <F>(error: F): ResultFailure<F> => ({ success: false, error })
} as const);
The Variable
class is used to create an instance of a Variable validator/transformer.
The primary method of the class is parse
. This will take an optional string and return a Result of T
or a list of error strings.
parse(value?: string | undefined): Result<T, string[]>
Variables are Immutable - each of the following methods will create a new Variable:
Marks a variable as optional. Type of variable becomes T | undefined
.optional(): Variable<T | undefined>
// type becomes string | undefined
const optionalVar = v.string().optional();
// Optional Status can be retrieved from the .isOptional property
console.log(optionalVar.isOptional);
Sets a default value for the variable if value is undefined.
.default(value: T | (() => T) ): Variable<T>
// if value is not supplied, result in default value
const defaultedVar = v.string().default('defaultValue');
// Default Value can be retrieved from the .defaultTo property
console.log(defaultedVar.defaultTo);
Sets the name of the variable
.from(name: string): Variable<T>
const namedVar = v.string().from('NAME');
// Variable Name can be retrieved from the .name property
console.log(namedVar.name)
Allows variable type unions
.else<S>(variable: Variable<S>): Variable<T | S>
// type becomes string | number
const stringOrNumber = v.string().else(v.number());
Applies a custom transformation function to the variable's value. An optional targetType can be provided for documentation purposes.
type Transformer<I, O> = (value: I) => Result<O, string[]>
.transform<S>(transform: Transformer<T, S>, type?: string): Variable<S>
// type number|undefind becomes boolean
const isOdd = v.number().optional().transform(
value => Result.success((Math.round(value || 0) % 2) === 1)
);
Transformations are particularly powerful, allowing for value conversion, additional validation and type conversion if necessary.
varcor provides a series of helper functions designed to define and enforce the types and constraints of your environment variables:
Define boolean variables, interpreting various string values ('true'
, 'false'
, '1'
, '0'
) as booleans.
import { v } from 'varcor';
const DEBUG = v.boolean();
Define numeric environment variables, with support for minimum and maximum constraints.
import { v } from 'varcor';
const PORT = v.number().min(3000).max(9000);
Similar to number variables, but specifically for integer values.
import { v } from 'varcor';
const RETRY_LIMIT = v.integer().min(1).max(5);
Define string variables, with optional validators or regex pattern matching.
import { v } from 'varcor';
const DATABASE_URL = v.string().regex(/mongodb:\/\/.+/, 'mongodb Url');
const MAIN_URL = v.string().url();
const EMAIL = v.string().email();
const UUID = v.string().uuid();
const PASSWORD = v.string().validate(value =>
value.length > 10 && value.length < 20
? Result.success(value)
: Result.failure(['must be between 10 and 20 characters.'])
)
Define enumerated string variables, ensuring the value matches one of the predefined options.
import { v } from 'varcor';
const ENVIRONMENT = v.enum().value('development').value('production').value('test');
You can use a single value enum - the v.literal(value: string)
helper function:
const RED = v.literal('RED');
Define variables for date and time, supporting a generic DateTime object, and both JavaScript Date
objects and luxon
DateTime objects.
Types:
type DateType = 'date' | 'time' | 'datetime' | 'timeTz' | 'datetimeTz';
type DateObject = {
year: number;
month: number;
day: number;
hour: number;
minute: number;
second: number;
ms: number;
tz: TimeZone;
};
// `from` defaults to DateTimeTz
v.dateobj:(from?: DateType): Variable<DateObject>
v.jsdate:(from?: DateType): Variable<Date>
v.luxdate:(from?: DateType): Variable<DateTime>
Usage:
import { v } from 'varcor';
const OBJ_DATE = v.dateobj('datetimeTz')
const JS_DATE = v.jsdate('date');
const LUX_DATE = v.luxdate('time');
Parse and validate JSON formatted string variables.
Types:
type JsonValidator<T> = (data: any) => Result<T, string[]>;
v.json<T = any>(validator?: JsonValidator<T>): Variable<T>
Usage:
import { v } from 'varcor';
const CONFIG = v.json().validate();
Leverage zod
schemas for complex JSON object validation.
import { z } from 'zod';
import { v } from 'varcor';
const MY_SCHEMA = z.object({ key: z.string() });
const CONFIG = v.tson(MY_SCHEMA);
DataObject
and DataObjectBuilder
are utilities for managing the configuration data within your applications. Here's how to use them effectively:
DataObject
is a simple key-value mapping where values are either strings or undefined
.
type DataObject = { [key: string]: string | undefined; };
The DataObjectBuilder
class provides an interface to incrementally build a DataObject
. It supports adding data from environment variables, JSON strings, .env
files, and more.
DataObjectBuilder is immutable, so each method creates a new DataObjectBuilder.
Creating a New DataObjectBuilder Instance
To start building a new DataObject
, simply instantiate DataObjectBuilder
:
import { DataObjectBuilder } from './DataObjectBuilder';
let builder = new DataObjectBuilder()
Adding DataObjects or DataObjectBuilders
Incorporate other DataObjects or DataObjectBuilders.
Signature
.addData(data: DataObject | DataObjectBuilder):
Example
const dataObject: DataObject = {
PORT: '8080',
NAME: 'MyApp'
};
const dataBuilder = v.data.new().addDataObject({
TYPE: 'Open',
DATE: '2024-01-01'
})
builder = builder.data(appConfig)
builder = builder.data(dataBuilder);
Adding Environment Variables
Easily include all current environment variables into your data object:
builder = builder.env();
Adding Data from an Object
Incorporate configuration data from a regular JavaScript object. Non-string values are automatically converted to JSON strings:
const appConfig = {
port: 8080,
name: "MyApp",
features: { logging: true, debugMode: false },
};
builder = builder.object(appConfig);
Adding Data from json
string
const jsonString = '{"apiUrl": "https://api.example.com", "timeout": 5000}';
builder = builder.json(jsonString);
Adding Data from dotenv
string
If you have a dotenv
formatted string containing environment variables, you can parse and add those variables:
const envFormat = `
# Variables
API_URL=http://api.example.com;
TIMEOUT="5000";
`
builder = builder.dotenv(envFormat);
File Helpers
DataObjectBuilder
has two methods that allow importing from json
and dotenv
files.
Each method takes the FileOptions type
// Signatures
.jsonFile(path: string, options: FileOptions);
.dotenvFile(path: string, options: FileOptions);
type FileOptions = {
// if set, will determine whether to attempt to load file
when?: boolean;
// if false, will error if file doesn't exist
optional?: boolean;
// function to check if file exists, defaults to fs.existsSync
fileExists?: (path: string) => boolean;
// function to read file contents, defaults to fs.readFile
readFile?: (path: string) => string;
};
//example
builder = builder.dotenvFile('./production.env', { when: process.env.NODE_ENV === 'production' });
builder = builder.dotenvFile('./development.env', { when: process.env.NODE_ENV === 'development' });
Chaining
As DataObjectBuilder
methods return a new builder instance, allowing for method chaining:
const finalDataObject = new DataObjectBuilder()
.env()
.object(appConfig)
.dotenvFile('./.env')
.data({});
console.log(finalDataObject);
Helper Methods All methods on DataObjectBuilder are available in v.data, to allow easy initializing
v.data.new();
v.data.env();
v.data.json(...);
v.data.jsonFile(...);
Finalizing and Retrieving the DataObject
Once you've added all your data sources, finalize the builder to get your DataObject
:
const finalDataObject: DataObject = builder.toDataObject();
console.log(finalDataObject);
FAQs
A tool for streamlined management of environment variables, offering normalization, type enforcement, and generation of configuration skeletons.
The npm package varcor receives a total of 4 weekly downloads. As such, varcor popularity was classified as not popular.
We found that varcor demonstrated a healthy version release cadence and project activity because the last version was released less than 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
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.