Socket
Socket
Sign inDemoInstall

varcor

Package Overview
Dependencies
2
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    varcor

A tool for streamlined management of environment variables, offering normalization, type enforcement, and generation of configuration skeletons.


Version published
Weekly downloads
9
decreased by-40%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

varcor

varcor is a tool for streamlined management of config values, offering normalization and type enforcement.

Installation

To get started with varcor, install the package via npm:

npm install varcor

Result

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);

Variables

The Variable class is used to create an instance of a Variable validator/transformer.

Common Functionalities

Parsing Values

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:

Making Variables Optional

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);
Setting Default Values

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);
Setting Variable Names

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)
Variable Unions with Else

Allows variable type unions

.else<S>(variable: Variable<S>): Variable<T | S>

// type becomes string | number
const stringOrNumber = v.string().else(v.number());
Applying Transformations

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.


Typed Variables and Helper Functions

varcor provides a series of helper functions designed to define and enforce the types and constraints of your environment variables:

Boolean Variables

Define boolean variables, interpreting various string values ('true', 'false', '1', '0') as booleans.

import { v } from 'varcor';

const DEBUG = v.boolean();
Number Variables

Define numeric environment variables, with support for minimum and maximum constraints.

import { v } from 'varcor';

const PORT = v.number().min(3000).max(9000);
Integer Variables

Similar to number variables, but specifically for integer values.

import { v } from 'varcor';

const RETRY_LIMIT = v.integer().min(1).max(5);
String Variables

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.'])
)
Enum Variables

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');
Date and Time Variables

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');
JSON Variables

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();
Zod Schema Validation

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 Usage

DataObject and DataObjectBuilder are utilities for managing the configuration data within your applications. Here's how to use them effectively:

DataObject

DataObject is a simple key-value mapping where values are either strings or undefined.

type DataObject = { [key: string]: string | undefined; };

DataObjectBuilder

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.

Basic Usage
  1. Creating a New DataObjectBuilder Instance

    To start building a new DataObject, simply instantiate DataObjectBuilder:

    import { DataObjectBuilder } from './DataObjectBuilder';
    
    let builder = new DataObjectBuilder()
    
  2. 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);
    
  3. Adding Environment Variables

    Easily include all current environment variables into your data object:

    builder = builder.env();
    
  4. 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);
    
  5. Adding Data from json string

    const jsonString = '{"apiUrl": "https://api.example.com", "timeout": 5000}';
    builder = builder.json(jsonString);
    
  6. 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);
    
  7. 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' });
    
  8. 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);
    
  9. 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(...);
    
  10. 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);
    

Type Inference and Parsing

  • TODO

FAQs

Last updated on 28 Mar 2024

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc