Skip to content

Commit

Permalink
New: Add requireFirst() method (fixes #13)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Apr 15, 2021
1 parent a04b84e commit 13e1b9d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ However, you can also import the unminified version for debugging purposes:
import { Env } from "https://cdn.skypack.dev/@humanwhocodes/env";
```


By default, an `Env` instance will read from an empty object.

## API
Expand All @@ -83,6 +82,9 @@ const username = env.first(["USERNAME", "USERNAME2"], "humanwhocodes");
// read a variable and throw an error if it doesn't exist
// or is an empty string
const username = env.require("USERNAME");

// read the first found variable throw an error if none exist
const username = env.requireFirst(["USERNAME", "USERNAME2"]);
```

To retrieve more than one required environment variable at one time, you can use the `required` property with destructuring assignment:
Expand Down
21 changes: 21 additions & 0 deletions src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ export class Env {
}
}

/**
* Retrieves the first environment variable found in a list of environment
* variable names and throws an error if none of the variables are found.
* @param {string[]} keys An array of environment variable names.
* @returns {string} The environment variable value.
* @throws {TypeError} If keys is not an array with at least one item.
* @throws {Error} When the environment variable doesn't exist or is an
* empty string.
*/
requireFirst(keys) {

const value = this.first(keys);
if (typeof value === "undefined") {
keyNotFound(`[${keys}]`);
} else if (value === "") {
throw emptyString(`[${keys}]`);
} else {
return value;
}
}

/**
* Lazy-loading property containing a proxy that can be used to
* automatically throw errors when an undefined environment variable
Expand Down
60 changes: 60 additions & 0 deletions tests/env.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,66 @@ describe("Env", () => {

});

describe("requireFirst()", () => {

const source = {
USERNAME: "humanwhocodes",
USERNAME2: "nzakas"
};

it("should throw an error when the first argument is not an array", () => {
const env = new Env(source);

assert.throws(() => {
env.requireFirst("USERNAME");
}, /First argument/);

});

it("should throw an error when the first argument doesn't have at least one item", () => {
const env = new Env(source);

assert.throws(() => {
env.requireFirst([]);
}, /First argument/);

});

it("should throw an error when none of the arguments exist", () => {
const env = new Env(source);

assert.throws(() => {
env.requireFirst(["foo", "bar"]);
}, /Required environment variable '\[foo,bar\]' not found/);

});

it("should get the first environment variable when one exists", () => {
const env = new Env(source);
const value = env.requireFirst(["USERNAME"]);
assert.strictEqual(value, source.USERNAME);
});

it("should get the first environment variable when only one exists", () => {
const env = new Env(source);
const value = env.requireFirst(["USERNAME", "ALT_USERNAME"]);
assert.strictEqual(value, source.USERNAME);
});

it("should get the first environment variable when both exist exists", () => {
const env = new Env(source);
const value = env.requireFirst(["USERNAME", "USERNAME2"]);
assert.strictEqual(value, source.USERNAME);
});

it("should get the second environment variable when it exists and the first doesn't", () => {
const env = new Env(source);
const value = env.requireFirst(["ALT_USERNAME", "USERNAME"]);
assert.strictEqual(value, source.USERNAME);
});

});

describe("exists", () => {

const source = {
Expand Down

0 comments on commit 13e1b9d

Please sign in to comment.