Comparing version 0.2.0 to 1.0.0-0
@@ -176,3 +176,3 @@ 'use strict'; | ||
var output = ['================================'].concat(invalids, missing, ['================================']); | ||
var output = ['========================================'].concat(invalids, missing, ['========================================']); | ||
return output.join('\n'); | ||
@@ -198,2 +198,4 @@ } | ||
function getValueOrThrow(_ref) { | ||
var _validator$input; | ||
var env = _ref.env, | ||
@@ -203,3 +205,3 @@ validator = _ref.validator, | ||
var usingDevDefault = env.NODE_ENV !== 'production'; | ||
var raw = env[key]; | ||
var raw = (_validator$input = validator.input) !== null && _validator$input !== void 0 ? _validator$input : env[key]; | ||
@@ -215,3 +217,3 @@ if (raw === undefined && usingDevDefault && validator.devDefault !== undefined) { | ||
if (raw === undefined) { | ||
throw new MissingEnvError("Missing value for " + key); | ||
throw new MissingEnvError("Missing value"); | ||
} | ||
@@ -228,6 +230,8 @@ | ||
function cleanEnv(env, validators, _temp) { | ||
function envsafe(validators, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
_ref2$reporter = _ref2.reporter, | ||
reporter = _ref2$reporter === void 0 ? defaultReporter : _ref2$reporter; | ||
reporter = _ref2$reporter === void 0 ? defaultReporter : _ref2$reporter, | ||
_ref2$env = _ref2.env, | ||
env = _ref2$env === void 0 ? process.env : _ref2$env; | ||
@@ -350,6 +354,6 @@ var errors = {}; | ||
exports.bool = bool; | ||
exports.cleanEnv = cleanEnv; | ||
exports.defaultReporter = defaultReporter; | ||
exports.defaultReporterText = defaultReporterText; | ||
exports.email = email; | ||
exports.envsafe = envsafe; | ||
exports.invalidEnvError = invalidEnvError; | ||
@@ -356,0 +360,0 @@ exports.json = json; |
@@ -1,2 +0,2 @@ | ||
"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t}).apply(this,arguments)}function e(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}function r(t){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function n(t,e){return(n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function o(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}function i(t,e,r){return(i=o()?Reflect.construct:function(t,e,r){var o=[null];o.push.apply(o,e);var i=new(Function.bind.apply(t,o));return r&&n(i,r.prototype),i}).apply(null,arguments)}function u(t){var e="function"==typeof Map?new Map:void 0;return(u=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,o)}function o(){return i(t,arguments,r(this).constructor)}return o.prototype=Object.create(t.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),n(o,t)})(t)}function c(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}Object.defineProperty(exports,"__esModule",{value:!0});var s=function(t){function r(e){var n;return n=t.call(this,e)||this,Object.setPrototypeOf(c(n),r.prototype),n}return e(r,t),r}(u(TypeError)),a=function(t,e){return new s("Invalid "+t+' input: "'+e+'"')},f=function(t){function r(e){var n;return n=t.call(this,e)||this,Object.setPrototypeOf(c(n),r.prototype),n}return e(r,t),r}(u(ReferenceError));function p(t){for(var e=t.errors,r=[],n=[],o=0,i=Object.keys(e);o<i.length;o++){var u=i[o],c=e[u];c instanceof f?n.push(" "+u+": "+(c.message||"required")):r.push(" "+u+": "+(c.message||"invalid"))}return r.length&&r.unshift("❌ Invalid environment variables:"),n.length&&n.unshift("💨 Missing environment variables:"),["================================"].concat(r,n,["================================"]).join("\n")}function l(t){var e,r,n=p(t);throw console.error(n),"undefined"!=typeof process&&(null===(e=process)||void 0===e?void 0:e.exit)&&process.exit(1),"undefined"!=typeof window&&(null===(r=window)||void 0===r?void 0:r.alert)&&window.alert(n),new Error(n)}function v(t){var e=t.env,r=t.validator,n=t.key,o=e[n];if(void 0===o&&"production"!==e.NODE_ENV&&void 0!==r.devDefault&&(o=r.devDefault),void 0===o&&void 0!==r.default&&(o=r.default),void 0===o)throw new f("Missing value for "+n);var i=r._parse(o);if(r.choices&&!r.choices.includes(i))throw new s('Value "'+i+'" not in choices ['+r.choices+"]");return i}var d=/^[^@\s]+@[^@\s]+\.[^@\s]+$/;function h(e){return function(r){return void 0===r&&(r={}),t({},r,{_parse:e})}}var y=h((function(t){switch(t){case!0:case"true":case"t":case"1":return!0;case!1:case"false":case"f":case"0":return!1;default:throw a("str",t)}})),w=h((function(t){if("string"!=typeof t)throw a("str",t);return t})),b=h((function(t){if(!d.test(t))throw a("email",t);return t})),O=h((function(t){var e=+t;if(Number.isNaN(e))throw a("num",t);return e})),x=h((function(t){var e=+t;if(Number.isNaN(e)||""+e!=""+t||e%1!=0||e<1||e>65535)throw a("port",t);return e})),g=h((function(t){try{return new URL(t),t}catch(e){throw a("url",t)}})),j=h((function(t){try{return"string"!=typeof t?t:JSON.parse(t)}catch(e){throw a("json",t)}}));exports.InvalidEnvError=s,exports.MissingEnvError=f,exports.bool=y,exports.cleanEnv=function(t,e,r){var n=(void 0===r?{}:r).reporter,o=void 0===n?l:n,i={},u={};for(var c in e){var s=e[c];try{var a=v({env:t,validator:s,key:c});u[c]=a}catch(t){i[c]=t}}return Object.keys(i).length&&o({errors:i,output:u,env:t}),Object.freeze?Object.freeze(u):u},exports.defaultReporter=l,exports.defaultReporterText=p,exports.email=b,exports.invalidEnvError=a,exports.json=j,exports.makeValidator=h,exports.num=O,exports.port=x,exports.str=w,exports.url=g; | ||
"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t}).apply(this,arguments)}function e(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}function r(t){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function n(t,e){return(n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function o(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}function i(t,e,r){return(i=o()?Reflect.construct:function(t,e,r){var o=[null];o.push.apply(o,e);var i=new(Function.bind.apply(t,o));return r&&n(i,r.prototype),i}).apply(null,arguments)}function u(t){var e="function"==typeof Map?new Map:void 0;return(u=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,o)}function o(){return i(t,arguments,r(this).constructor)}return o.prototype=Object.create(t.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),n(o,t)})(t)}function c(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}Object.defineProperty(exports,"__esModule",{value:!0});var s=function(t){function r(e){var n;return n=t.call(this,e)||this,Object.setPrototypeOf(c(n),r.prototype),n}return e(r,t),r}(u(TypeError)),a=function(t,e){return new s("Invalid "+t+' input: "'+e+'"')},f=function(t){function r(e){var n;return n=t.call(this,e)||this,Object.setPrototypeOf(c(n),r.prototype),n}return e(r,t),r}(u(ReferenceError));function p(t){for(var e=t.errors,r=[],n=[],o=0,i=Object.keys(e);o<i.length;o++){var u=i[o],c=e[u];c instanceof f?n.push(" "+u+": "+(c.message||"required")):r.push(" "+u+": "+(c.message||"invalid"))}return r.length&&r.unshift("❌ Invalid environment variables:"),n.length&&n.unshift("💨 Missing environment variables:"),["========================================"].concat(r,n,["========================================"]).join("\n")}function l(t){var e,r,n=p(t);throw console.error(n),"undefined"!=typeof process&&(null===(e=process)||void 0===e?void 0:e.exit)&&process.exit(1),"undefined"!=typeof window&&(null===(r=window)||void 0===r?void 0:r.alert)&&window.alert(n),new Error(n)}function v(t){var e,r=t.env,n=t.validator,o=null!==(e=n.input)&&void 0!==e?e:r[t.key];if(void 0===o&&"production"!==r.NODE_ENV&&void 0!==n.devDefault&&(o=n.devDefault),void 0===o&&void 0!==n.default&&(o=n.default),void 0===o)throw new f("Missing value");var i=n._parse(o);if(n.choices&&!n.choices.includes(i))throw new s('Value "'+i+'" not in choices ['+n.choices+"]");return i}var d=/^[^@\s]+@[^@\s]+\.[^@\s]+$/;function h(e){return function(r){return void 0===r&&(r={}),t({},r,{_parse:e})}}var y=h((function(t){switch(t){case!0:case"true":case"t":case"1":return!0;case!1:case"false":case"f":case"0":return!1;default:throw a("str",t)}})),w=h((function(t){if("string"!=typeof t)throw a("str",t);return t})),b=h((function(t){if(!d.test(t))throw a("email",t);return t})),O=h((function(t){var e=+t;if(Number.isNaN(e))throw a("num",t);return e})),x=h((function(t){var e=+t;if(Number.isNaN(e)||""+e!=""+t||e%1!=0||e<1||e>65535)throw a("port",t);return e})),g=h((function(t){try{return new URL(t),t}catch(e){throw a("url",t)}})),j=h((function(t){try{return"string"!=typeof t?t:JSON.parse(t)}catch(e){throw a("json",t)}}));exports.InvalidEnvError=s,exports.MissingEnvError=f,exports.bool=y,exports.defaultReporter=l,exports.defaultReporterText=p,exports.email=b,exports.envsafe=function(t,e){var r=void 0===e?{}:e,n=r.reporter,o=void 0===n?l:n,i=r.env,u=void 0===i?process.env:i,c={},s={};for(var a in t){var f=t[a];try{var p=v({env:u,validator:f,key:a});s[a]=p}catch(t){c[a]=t}}return Object.keys(c).length&&o({errors:c,output:s,env:u}),Object.freeze?Object.freeze(s):s},exports.invalidEnvError=a,exports.json=j,exports.makeValidator=h,exports.num=O,exports.port=x,exports.str=w,exports.url=g; | ||
//# sourceMappingURL=envsafe.cjs.production.min.js.map |
@@ -172,3 +172,3 @@ function _extends() { | ||
var output = ['================================'].concat(invalids, missing, ['================================']); | ||
var output = ['========================================'].concat(invalids, missing, ['========================================']); | ||
return output.join('\n'); | ||
@@ -194,2 +194,4 @@ } | ||
function getValueOrThrow(_ref) { | ||
var _validator$input; | ||
var env = _ref.env, | ||
@@ -199,3 +201,3 @@ validator = _ref.validator, | ||
var usingDevDefault = env.NODE_ENV !== 'production'; | ||
var raw = env[key]; | ||
var raw = (_validator$input = validator.input) !== null && _validator$input !== void 0 ? _validator$input : env[key]; | ||
@@ -211,3 +213,3 @@ if (raw === undefined && usingDevDefault && validator.devDefault !== undefined) { | ||
if (raw === undefined) { | ||
throw new MissingEnvError("Missing value for " + key); | ||
throw new MissingEnvError("Missing value"); | ||
} | ||
@@ -224,6 +226,8 @@ | ||
function cleanEnv(env, validators, _temp) { | ||
function envsafe(validators, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
_ref2$reporter = _ref2.reporter, | ||
reporter = _ref2$reporter === void 0 ? defaultReporter : _ref2$reporter; | ||
reporter = _ref2$reporter === void 0 ? defaultReporter : _ref2$reporter, | ||
_ref2$env = _ref2.env, | ||
env = _ref2$env === void 0 ? process.env : _ref2$env; | ||
@@ -343,3 +347,3 @@ var errors = {}; | ||
export { InvalidEnvError, MissingEnvError, bool, cleanEnv, defaultReporter, defaultReporterText, email, invalidEnvError, json, makeValidator, num, port, str, url }; | ||
export { InvalidEnvError, MissingEnvError, bool, defaultReporter, defaultReporterText, email, envsafe, invalidEnvError, json, makeValidator, num, port, str, url }; | ||
//# sourceMappingURL=envsafe.esm.js.map |
@@ -1,2 +0,2 @@ | ||
export * from './cleanEnv'; | ||
export * from './envsafe'; | ||
export * from './errors'; | ||
@@ -3,0 +3,0 @@ export * from './reporter'; |
@@ -22,3 +22,3 @@ export interface Spec<TValue> { | ||
*/ | ||
example?: string; | ||
example?: string | TValue; | ||
/** | ||
@@ -28,2 +28,7 @@ * A url that leads to more detailed documentation about the env var. | ||
docs?: string; | ||
/** | ||
* If you want to override what is passed to the parser, defaults to `env[key]` | ||
* Can be useful on the front-end when webpack makes the vars disappear | ||
*/ | ||
input?: string | undefined; | ||
} | ||
@@ -41,4 +46,5 @@ export interface ValidatorSpec<TValue> extends Spec<TValue> { | ||
export declare type Reporter<TCleanEnv> = (opts: ReporterOpts<TCleanEnv>) => void; | ||
export declare type CleanEnvOpts<TCleanEnv> = { | ||
export declare type envsafeOpts<TCleanEnv> = { | ||
reporter?: Reporter<TCleanEnv>; | ||
env?: Environment; | ||
}; | ||
@@ -45,0 +51,0 @@ export declare type Validators<TCleanEnv> = { |
{ | ||
"version": "0.2.0", | ||
"version": "1.0.0-0", | ||
"license": "MIT", | ||
@@ -31,3 +31,3 @@ "main": "dist/index.js", | ||
"singleQuote": true, | ||
"trailingComma": "es5" | ||
"trailingComma": "all" | ||
}, | ||
@@ -34,0 +34,0 @@ "name": "envsafe", |
100
README.md
@@ -7,3 +7,3 @@ [![Maintainability](https://api.codeclimate.com/v1/badges/c17614f0d80b810e47a6/maintainability)](https://codeclimate.com/github/KATT/envsafe/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c17614f0d80b810e47a6/test_coverage)](https://codeclimate.com/github/KATT/envsafe/test_coverage) | ||
- Rewritten in 100% TypeScript | ||
- Written in 100% TypeScript | ||
- Always strict - only get the props you have defined | ||
@@ -14,8 +14,8 @@ - No dependencies - smaller bundle for browser/isomorphic apps | ||
Works the same in the browser and in node. | ||
Works the same in the browser and in node. See the [`./examples`](./examples)-folder for more examples. | ||
```ts | ||
import { str, cleanEnv, url } from 'envsafe'; | ||
import { str, envsafe, url } from 'envsafe'; | ||
export const env = cleanEnv(process.env, { | ||
export const env = envsafe({ | ||
NODE_ENV: str({ | ||
@@ -42,2 +42,90 @@ devDefault: 'development', | ||
It defaults to using `process.env` as a base for plucking the vars, but it can be overridden like this: | ||
```ts | ||
export const env = envsafe( | ||
{ | ||
ENV_VAR: str({ | ||
devDefault: 'myvar', | ||
}), | ||
}, | ||
{ | ||
env: window.__ENVIRONMENT__, | ||
}, | ||
); | ||
``` | ||
## Built-in validators | ||
| Function | return value | Description | | ||
| --------- | ------------ | ------------------------------------------------------------------------------------------------ | | ||
| `str()` | `string` | Passes string values through, will ensure an value is present unless a `default` value is given. | | ||
| `bool()` | `boolean` | Parses env var strings `"0", "1", "true", "false", "t", "f"` into booleans | | ||
| `num()` | `number` | Parses an env var (eg. "42", "0.23", "1e5") into a Number | | ||
| `port()` | `number` | Ensures an env var is a TCP port (1-65535) | | ||
| `url()` | `string` | Ensures an env var is a url with a protocol and hostname | | ||
| `email()` | `string` | Ensures an env var is an email address | | ||
| `json()` | `unknown` | Parses an env var with `JSON.parse` | | ||
### Possible options | ||
All optional. | ||
| Name | Type | Description | | ||
| ------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `choices` | `TValue[]` | Allow-list for values | | ||
| `default` | `TValue` / `string` | A fallback value, which will be used if the env var wasn't specified. Providing a default effectively makes the env var optional. | | ||
| `devDefault` | `TValue` / `string` | A fallback value to use only when `NODE_ENV` is not `production`. This is handy for env vars that are required for production environments, but optional for development and testing. | | ||
These values below are not used by the library and only for description of the variables. | ||
| Name | Type | Description | | ||
| --------- | ------------------- | ------------------------------------------------------------------ | | ||
| `desc` | `string` | A string that describes the env var. | | ||
| `example` | `string` / `TValue` | An example value for the env var. | | ||
| `docs` | `string` | A url that leads to more detailed documentation about the env var. | | ||
## Custom validators/parsers | ||
```ts | ||
import { makeValidator, envsafe } from 'envsafe'; | ||
const barParser = makeValidator<'bar'>(input => { | ||
if (input !== 'bar') { | ||
throw new InvalidEnvError(`Expected '${input}' to be 'bar'`); | ||
} | ||
return 'bar'; | ||
}); | ||
const env = envsafe({ | ||
FOO: barParser(), | ||
}); | ||
``` | ||
## Error reporting | ||
By default the reporter will | ||
- Make a readable summary of your issues | ||
- `console.error`-log an error | ||
- Call `process.exit(1)` / `window.alert(text)` | ||
- Throw an error | ||
Can be overridden by the `reporter`-property | ||
```ts | ||
const env = envsafe( | ||
{ | ||
MY_VAR: str(), | ||
}, | ||
{ | ||
reporter({ errors, output, env }) { | ||
// do stuff | ||
}, | ||
}, | ||
); | ||
``` | ||
# Contributing | ||
## Running the project locally | ||
@@ -107,1 +195,5 @@ | ||
Per Palmer Group guidelines, [always use named exports.](https://github.com/palmerhq/typescript#exports) Code split inside your React app instead of your React library. | ||
``` | ||
``` |
@@ -1,2 +0,2 @@ | ||
export * from './cleanEnv'; | ||
export * from './envsafe'; | ||
export * from './errors'; | ||
@@ -3,0 +3,0 @@ export * from './reporter'; |
@@ -28,6 +28,6 @@ import { MissingEnvError } from './errors'; | ||
const output: string[] = [ | ||
'================================', | ||
'========================================', | ||
...invalids, | ||
...missing, | ||
'================================', | ||
'========================================', | ||
]; | ||
@@ -34,0 +34,0 @@ |
@@ -22,3 +22,3 @@ export interface Spec<TValue> { | ||
*/ | ||
example?: string; | ||
example?: string | TValue; | ||
/** | ||
@@ -28,2 +28,7 @@ * A url that leads to more detailed documentation about the env var. | ||
docs?: string; | ||
/** | ||
* If you want to override what is passed to the parser, defaults to `env[key]` | ||
* Can be useful on the front-end when webpack makes the vars disappear | ||
*/ | ||
input?: string | undefined; | ||
} | ||
@@ -47,4 +52,5 @@ | ||
export type CleanEnvOpts<TCleanEnv> = { | ||
export type envsafeOpts<TCleanEnv> = { | ||
reporter?: Reporter<TCleanEnv>; | ||
env?: Environment; | ||
}; | ||
@@ -51,0 +57,0 @@ |
@@ -6,3 +6,3 @@ import { invalidEnvError } from './errors'; | ||
export function makeValidator<TValue>( | ||
parser: (input: string | TValue) => TValue | ||
parser: (input: string | TValue) => TValue, | ||
): (spec?: Spec<TValue>) => ValidatorSpec<TValue> { | ||
@@ -9,0 +9,0 @@ return (spec = {}) => { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
72622
920
196