UNPKG

ts-env-support

Version:

Typescript support for .env files

203 lines (184 loc) 5.92 kB
require('reflect-metadata'); const env = require('node-env-file'); const colors = require('colors'); const store = {}; exports.Value = function (options) { return function (target, propertyKey) { // store all the properties in a store const name = target.name; if (!store[name]) { store[name] = []; } const type = Reflect.getOwnMetadata('design:type', target, propertyKey); let value; const alias = options && options.alias; const validation = options && options.validate; switch (type.name) { case 'String': { value = { name: propertyKey, type: 'String', alias, validation }; break; } case 'Number': { value = { name: propertyKey, type: 'Number', alias, validation }; break; } case 'Boolean': { value = { name: propertyKey, type: 'Boolean', alias, validation }; break; } default: { throw `The value of type ${type.name} is not supported to be serialized`; }; } store[name].push(value); } } exports.Env = function (options) { return function (target) { const path = options && options.path; try { const name = target.name; try { env(path || '.env'); } catch (error) { throw `Couldn't find a .env file at ${path}`; } if (store.hasOwnProperty(undefined)) { const nonStaticMembers = store[typeof undefined]; if (nonStaticMembers.length) { const message = `Non static members are allowed in env class.\n` + '\nPlease fix the following non static members.'.red.bold + `\n${nonStaticMembers.map(nonStaticMember => ` - ${nonStaticMember.name}`).join('\n')}`; throw message; } } if (Object.keys(store).length > 1) { if (!store.hasOwnProperty(undefined)) { throw `Only one Environment file is supported`; } } if (!store[name]) { throw `Couldn't find 'env' class`; } const $env = process.env; store[name].forEach(property => { const { name, type, alias, validation } = property; if ($env[alias || name] === undefined) { throw `'${alias || name}' is not provided with a value in the ${path || '.env'} file`; } switch (type) { case 'String': { target[name] = $env[alias || name]; break; } case 'Number': { target[name] = Number($env[alias || name]); if (isNaN(target[name])) throw `'${name}' is not a number`; break; } case 'Boolean': { target[name] = $env[alias || name] == 'true'; break; } default: { throw `Unsupported type`; } } if (target[name] == undefined) throw `Couldn't find a value for ${name}`; // If a validation function is provided if (validation) { const result = !!validation.call(target, target[name]); if (!result) { throw `Validation failed for the key ${name}`; } } }); } catch (error) { console.log(`Stopped the Process because of the following error\n`.underline.red); console.log(`${error}\n`.bold.red); process.exit(0); } }; } // string functions exports.startsWith = function startsWith(str) { return function (value) { return !value.search(str); } } exports.endsWith = function endsWith(str) { return function (value) { return !!value.endsWith(str); } } exports.contains = function contains(str) { return function (value) { return value.includes(str); } } // number functions exports.greaterThan = function greaterThan(num) { return function (value) { return value > num; } } exports.lessThan = function lessThan(num) { return function (value) { return value < num; } } exports.equals = function equals(any) { return function (value) { return any === value; } } exports.notEquals = function notEquals(any) { return function (value) { return any !== value; } } // exports.is = equals; // export const isNot = notEquals; // URL operators exports.isUrl = function isUrl(value) { try { new URL(value); return true; } catch (e) { return false }; } exports.isPath = function isPath(pathname) { return function (value) { try { return new URL(value).pathname == pathname; } catch (e) { return false; } } } // Combinator Operators exports.and = function and(...functions) { return function (value) { for (const f of functions) { if (!f(value)) return false; } return true; } } exports.or = function or(...functions) { return function (value) { for (const f of functions) { if (f(value)) return true; } return false; } }