@push.rocks/qenv 7.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/qenv',
6
- version: '7.0.0',
6
+ version: '8.1.0',
7
7
  description: 'A module for easily handling environment variables in Node.js projects with support for .yml and .json configuration.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHVIQUF1SDtDQUNySSxDQUFBIn0=
@@ -1 +1,4 @@
1
1
  export * from './qenv.classes.qenv.js';
2
+ export * from './qenv.classes.invalidqenvfileerror.js';
3
+ export * from './qenv.classes.missingqenvfileerror.js';
4
+ export * from './qenv.classes.missingrequiredenvvarserror.js';
package/dist_ts/index.js CHANGED
@@ -1,2 +1,5 @@
1
1
  export * from './qenv.classes.qenv.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDIn0=
2
+ export * from './qenv.classes.invalidqenvfileerror.js';
3
+ export * from './qenv.classes.missingqenvfileerror.js';
4
+ export * from './qenv.classes.missingrequiredenvvarserror.js';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyx3Q0FBd0MsQ0FBQztBQUN2RCxjQUFjLCtDQUErQyxDQUFDIn0=
@@ -0,0 +1,21 @@
1
+ /** which rule of the `required:` list a qenv.yml broke */
2
+ export type TQenvInvalidQenvFileReason = 'requiredNotAnArray' | 'requiredEntryNotAString';
3
+ export interface IQenvInvalidQenvFileErrorOptions {
4
+ qenvFilePathAbsolute: string;
5
+ reason: TQenvInvalidQenvFileReason;
6
+ /** the type name of the offending value, never the value itself */
7
+ invalidValueTypeName: string;
8
+ }
9
+ /**
10
+ * Thrown when qenv.yml declares a `required:` that qenv cannot read as a list of names. Such a
11
+ * declaration silently enforced nothing, which is the same fail-open as a missing qenv.yml.
12
+ * A file without any `required:` key, and one with an empty list, legitimately require nothing
13
+ * and never reach this error.
14
+ */
15
+ export declare class QenvInvalidQenvFileError extends Error {
16
+ readonly code = "QENV_INVALID_QENV_FILE";
17
+ readonly qenvFilePathAbsolute: string;
18
+ readonly reason: TQenvInvalidQenvFileReason;
19
+ readonly invalidValueTypeName: string;
20
+ constructor(optionsArg: IQenvInvalidQenvFileErrorOptions);
21
+ }
@@ -0,0 +1,25 @@
1
+ const reasonDescriptions = {
2
+ requiredNotAnArray: (typeNameArg) => `"required:" is of type ${typeNameArg} instead of a list of environment variable names`,
3
+ requiredEntryNotAString: (typeNameArg) => `"required:" contains an entry of type ${typeNameArg} instead of an environment variable name`,
4
+ };
5
+ /**
6
+ * Thrown when qenv.yml declares a `required:` that qenv cannot read as a list of names. Such a
7
+ * declaration silently enforced nothing, which is the same fail-open as a missing qenv.yml.
8
+ * A file without any `required:` key, and one with an empty list, legitimately require nothing
9
+ * and never reach this error.
10
+ */
11
+ export class QenvInvalidQenvFileError extends Error {
12
+ constructor(optionsArg) {
13
+ super(`The qenv.yml at ${optionsArg.qenvFilePathAbsolute} declares an unreadable requirement: ` +
14
+ `${reasonDescriptions[optionsArg.reason](optionsArg.invalidValueTypeName)}. ` +
15
+ `Write "required:" as a list of environment variable names, or omit it to require nothing.`);
16
+ this.code = 'QENV_INVALID_QENV_FILE';
17
+ this.name = 'QenvInvalidQenvFileError';
18
+ this.qenvFilePathAbsolute = optionsArg.qenvFilePathAbsolute;
19
+ this.reason = optionsArg.reason;
20
+ // only the type is carried and rendered: a malformed qenv.yml can hold a value where a name
21
+ // belongs, and a value may be a secret
22
+ this.invalidValueTypeName = optionsArg.invalidValueTypeName;
23
+ }
24
+ }
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWVudi5jbGFzc2VzLmludmFsaWRxZW52ZmlsZWVycm9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvcWVudi5jbGFzc2VzLmludmFsaWRxZW52ZmlsZWVycm9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVVBLE1BQU0sa0JBQWtCLEdBQXdFO0lBQzlGLGtCQUFrQixFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FDbEMsMEJBQTBCLFdBQVcsa0RBQWtEO0lBQ3pGLHVCQUF1QixFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FDdkMseUNBQXlDLFdBQVcsMENBQTBDO0NBQ2pHLENBQUM7QUFFRjs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyx3QkFBeUIsU0FBUSxLQUFLO0lBTWpELFlBQVksVUFBNEM7UUFDdEQsS0FBSyxDQUNILG1CQUFtQixVQUFVLENBQUMsb0JBQW9CLHVDQUF1QztZQUN2RixHQUFHLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUMsSUFBSTtZQUM3RSwyRkFBMkYsQ0FDOUYsQ0FBQztRQVZZLFNBQUksR0FBRyx3QkFBd0IsQ0FBQztRQVc5QyxJQUFJLENBQUMsSUFBSSxHQUFHLDBCQUEwQixDQUFDO1FBQ3ZDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxVQUFVLENBQUMsb0JBQW9CLENBQUM7UUFDNUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQ2hDLDRGQUE0RjtRQUM1Rix1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQztJQUM5RCxDQUFDO0NBQ0YifQ==
@@ -0,0 +1,16 @@
1
+ export interface IQenvMissingQenvFileErrorOptions {
2
+ qenvFilePathAbsolute: string;
3
+ qenvDir: string;
4
+ }
5
+ /**
6
+ * Thrown when a Qenv that is set to fail on missing variables finds no qenv.yml at all.
7
+ * Without the file there is no `required:` list to enforce, so every check would pass by
8
+ * accident - a deployable that forgot to ship its qenv.yml would look healthy. `code` identifies
9
+ * the refusal even when two copies of qenv end up in one tree, which makes `instanceof` unreliable.
10
+ */
11
+ export declare class QenvMissingQenvFileError extends Error {
12
+ readonly code = "QENV_MISSING_QENV_FILE";
13
+ readonly qenvFilePathAbsolute: string;
14
+ readonly qenvDir: string;
15
+ constructor(optionsArg: IQenvMissingQenvFileErrorOptions);
16
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Thrown when a Qenv that is set to fail on missing variables finds no qenv.yml at all.
3
+ * Without the file there is no `required:` list to enforce, so every check would pass by
4
+ * accident - a deployable that forgot to ship its qenv.yml would look healthy. `code` identifies
5
+ * the refusal even when two copies of qenv end up in one tree, which makes `instanceof` unreliable.
6
+ */
7
+ export class QenvMissingQenvFileError extends Error {
8
+ constructor(optionsArg) {
9
+ super(`qenv found no qenv.yml at ${optionsArg.qenvFilePathAbsolute}. It was constructed to fail ` +
10
+ `on missing required environment variables, and without qenv.yml there is no "required:" ` +
11
+ `list to enforce, so nothing would be checked. Ship qenv.yml with your deployable, or ` +
12
+ `construct Qenv with failOnMissing set to false.`);
13
+ this.code = 'QENV_MISSING_QENV_FILE';
14
+ this.name = 'QenvMissingQenvFileError';
15
+ this.qenvFilePathAbsolute = optionsArg.qenvFilePathAbsolute;
16
+ this.qenvDir = optionsArg.qenvDir;
17
+ }
18
+ }
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWVudi5jbGFzc2VzLm1pc3NpbmdxZW52ZmlsZWVycm9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvcWVudi5jbGFzc2VzLm1pc3NpbmdxZW52ZmlsZWVycm9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLHdCQUF5QixTQUFRLEtBQUs7SUFLakQsWUFBWSxVQUE0QztRQUN0RCxLQUFLLENBQ0gsNkJBQTZCLFVBQVUsQ0FBQyxvQkFBb0IsK0JBQStCO1lBQ3pGLDBGQUEwRjtZQUMxRix1RkFBdUY7WUFDdkYsaURBQWlELENBQ3BELENBQUM7UUFWWSxTQUFJLEdBQUcsd0JBQXdCLENBQUM7UUFXOUMsSUFBSSxDQUFDLElBQUksR0FBRywwQkFBMEIsQ0FBQztRQUN2QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsVUFBVSxDQUFDLG9CQUFvQixDQUFDO1FBQzVELElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQztJQUNwQyxDQUFDO0NBQ0YifQ==
@@ -0,0 +1,18 @@
1
+ export interface IQenvMissingRequiredEnvVarsErrorOptions {
2
+ missingEnvVars: string[];
3
+ requiredEnvVars: string[];
4
+ qenvFilePathAbsolute: string;
5
+ }
6
+ /**
7
+ * Thrown when a variable listed under `required:` in qenv.yml is not provided by any source.
8
+ * The names are carried as data so a caller can report or branch on them without parsing the
9
+ * message, and `code` identifies the refusal even when two copies of qenv end up in one tree,
10
+ * which makes `instanceof` unreliable.
11
+ */
12
+ export declare class QenvMissingRequiredEnvVarsError extends Error {
13
+ readonly code = "QENV_MISSING_REQUIRED_ENV_VARS";
14
+ readonly missingEnvVars: string[];
15
+ readonly requiredEnvVars: string[];
16
+ readonly qenvFilePathAbsolute: string;
17
+ constructor(optionsArg: IQenvMissingRequiredEnvVarsErrorOptions);
18
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Thrown when a variable listed under `required:` in qenv.yml is not provided by any source.
3
+ * The names are carried as data so a caller can report or branch on them without parsing the
4
+ * message, and `code` identifies the refusal even when two copies of qenv end up in one tree,
5
+ * which makes `instanceof` unreliable.
6
+ */
7
+ export class QenvMissingRequiredEnvVarsError extends Error {
8
+ constructor(optionsArg) {
9
+ super(`qenv is missing required environment variables: ${optionsArg.missingEnvVars.join(', ')}. ` +
10
+ `They are listed under "required:" in ${optionsArg.qenvFilePathAbsolute} and were found ` +
11
+ `neither in the process environment, nor in the env file, nor in the Docker secrets.`);
12
+ this.code = 'QENV_MISSING_REQUIRED_ENV_VARS';
13
+ this.name = 'QenvMissingRequiredEnvVarsError';
14
+ this.missingEnvVars = [...optionsArg.missingEnvVars];
15
+ this.requiredEnvVars = [...optionsArg.requiredEnvVars];
16
+ this.qenvFilePathAbsolute = optionsArg.qenvFilePathAbsolute;
17
+ }
18
+ }
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWVudi5jbGFzc2VzLm1pc3NpbmdyZXF1aXJlZGVudnZhcnNlcnJvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3FlbnYuY2xhc3Nlcy5taXNzaW5ncmVxdWlyZWRlbnZ2YXJzZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUE7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sK0JBQWdDLFNBQVEsS0FBSztJQU14RCxZQUFZLFVBQW1EO1FBQzdELEtBQUssQ0FDSCxtREFBbUQsVUFBVSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7WUFDekYsd0NBQXdDLFVBQVUsQ0FBQyxvQkFBb0Isa0JBQWtCO1lBQ3pGLHFGQUFxRixDQUN4RixDQUFDO1FBVlksU0FBSSxHQUFHLGdDQUFnQyxDQUFDO1FBV3RELElBQUksQ0FBQyxJQUFJLEdBQUcsaUNBQWlDLENBQUM7UUFDOUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsVUFBVSxDQUFDLG9CQUFvQixDQUFDO0lBQzlELENBQUM7Q0FDRiJ9
@@ -1,32 +1,82 @@
1
1
  import * as plugins from './qenv.plugins.js';
2
+ /**
3
+ * a reference to an environment variable: its name, or an async function that produces the value.
4
+ * The function form is only honoured by the async getters; the synchronous getter accepts names.
5
+ */
2
6
  export type TEnvVarRef = string | (() => Promise<string>);
3
- type TKeyValueObject = Record<string, any>;
7
+ /** the resolved value of every available required env var, always a string */
8
+ export type TEnvVarValueMap = Record<string, string>;
4
9
  export declare class Qenv {
10
+ /** the names listed under `required:` in qenv.yml */
5
11
  requiredEnvVars: string[];
12
+ /** the required names that a source provided */
6
13
  availableEnvVars: string[];
14
+ /** the required names that no source provided */
7
15
  missingEnvVars: string[];
8
- keyValueObject: TKeyValueObject;
16
+ /** the resolved value of every available required name */
17
+ keyValueObject: TEnvVarValueMap;
9
18
  logger: plugins.smartlog.ConsoleLog;
10
19
  qenvFilePathAbsolute: string;
11
20
  envFilePathAbsolute?: string;
21
+ /**
22
+ * Resolves every name listed under `required:` in qenv.yml while constructing.
23
+ * @param qenvFileBasePathArg directory that holds qenv.yml
24
+ * @param envFileBasePathArg directory that holds env.json, env.yml or env.yaml
25
+ * @param failOnMissing throws a QenvMissingRequiredEnvVarsError when a variable listed under
26
+ * `required:` in qenv.yml is not provided by any source, a QenvMissingQenvFileError when there
27
+ * is no qenv.yml to read that list from, and a QenvInvalidQenvFileError when the list cannot be
28
+ * read as names. Pass false to only record the names in `missingEnvVars` and continue.
29
+ * @throws QenvMissingQenvFileError
30
+ * @throws QenvInvalidQenvFileError
31
+ * @throws QenvMissingRequiredEnvVarsError
32
+ */
12
33
  constructor(qenvFileBasePathArg?: string, envFileBasePathArg?: string, failOnMissing?: boolean);
13
34
  private initializeFilePaths;
14
35
  private loadRequiredEnvVars;
36
+ /**
37
+ * Refuses a qenv.yml whose `required:` cannot be read as names: it enforces nothing, which is
38
+ * the fail-open a missing qenv.yml would be. A caller that opted out of failing keeps running,
39
+ * but hears the same named reason instead of losing the requirement silently.
40
+ */
41
+ private refuseInvalidQenvFile;
42
+ /** names the type of a value without rendering it: a value in a name's place may be a secret */
43
+ private describeValueType;
15
44
  private loadAvailableEnvVars;
16
45
  private checkForMissingEnvVars;
46
+ /**
47
+ * Resolves an env var from the process environment, the env file and the Docker secrets, in that
48
+ * order. An array is tried left to right and the first defined value wins.
49
+ * @param envVarNameOrNames a name, an async resolver function, or a list of either
50
+ */
17
51
  getEnvVarOnDemand(envVarNameOrNames: TEnvVarRef | TEnvVarRef[]): Promise<string | undefined>;
18
52
  /**
19
- * Like getEnvVarOnDemand, but throws an error if the env var is not set.
20
- * @param envVarNameOrNames
21
- * @returns
53
+ * Like getEnvVarOnDemand, but throws when no source provides a value.
54
+ * @param envVarNameOrNames a name, an async resolver function, or a list of either
22
55
  */
23
56
  getEnvVarOnDemandStrict(envVarNameOrNames: TEnvVarRef | TEnvVarRef[]): Promise<string>;
57
+ /**
58
+ * The synchronous counterpart of getEnvVarOnDemand. It resolves names only: an async resolver
59
+ * function cannot be awaited here, so the function form of TEnvVarRef is not accepted.
60
+ * @param envVarNameOrNames a name or a list of names
61
+ */
24
62
  getEnvVarOnDemandSync(envVarNameOrNames: string | string[]): string | undefined;
25
- getEnvVarOnDemandAsObject(envVarNameOrNames: string | string[]): Promise<any>;
63
+ /**
64
+ * Resolves an env var whose value was stored as a base64 encoded object and decodes it. A plain
65
+ * value is returned as the string it is, so the caller narrows what it gets.
66
+ * @param envVarNameOrNames a name or a list of names
67
+ */
68
+ getEnvVarOnDemandAsObject(envVarNameOrNames: string | string[]): Promise<unknown>;
26
69
  private tryGetEnvVar;
27
70
  private tryGetEnvVarSync;
71
+ /** renders env var references for an error message, naming a resolver function where it has one */
72
+ private describeEnvVarRefs;
28
73
  private getFromEnvironmentVariable;
29
74
  private getFromEnvYamlOrJsonFile;
75
+ /**
76
+ * the directory Docker mounts secrets into. It is a method so a test can point both secret
77
+ * readers at a directory it is allowed to create; a process can never write /run/secrets itself.
78
+ */
79
+ protected getDockerSecretsDirectoryPath(): string;
30
80
  private getFromDockerSecret;
31
81
  private getFromDockerSecretJson;
32
82
  private encodeBase64;
@@ -35,4 +85,3 @@ export declare class Qenv {
35
85
  private directoryExists;
36
86
  private readObjectFromFile;
37
87
  }
38
- export {};
@@ -1,14 +1,33 @@
1
1
  import * as plugins from './qenv.plugins.js';
2
+ import { QenvInvalidQenvFileError, } from './qenv.classes.invalidqenvfileerror.js';
3
+ import { QenvMissingQenvFileError } from './qenv.classes.missingqenvfileerror.js';
4
+ import { QenvMissingRequiredEnvVarsError } from './qenv.classes.missingrequiredenvvarserror.js';
2
5
  export class Qenv {
6
+ /**
7
+ * Resolves every name listed under `required:` in qenv.yml while constructing.
8
+ * @param qenvFileBasePathArg directory that holds qenv.yml
9
+ * @param envFileBasePathArg directory that holds env.json, env.yml or env.yaml
10
+ * @param failOnMissing throws a QenvMissingRequiredEnvVarsError when a variable listed under
11
+ * `required:` in qenv.yml is not provided by any source, a QenvMissingQenvFileError when there
12
+ * is no qenv.yml to read that list from, and a QenvInvalidQenvFileError when the list cannot be
13
+ * read as names. Pass false to only record the names in `missingEnvVars` and continue.
14
+ * @throws QenvMissingQenvFileError
15
+ * @throws QenvInvalidQenvFileError
16
+ * @throws QenvMissingRequiredEnvVarsError
17
+ */
3
18
  constructor(qenvFileBasePathArg = process.cwd(), envFileBasePathArg, failOnMissing = true) {
19
+ /** the names listed under `required:` in qenv.yml */
4
20
  this.requiredEnvVars = [];
21
+ /** the required names that a source provided */
5
22
  this.availableEnvVars = [];
23
+ /** the required names that no source provided */
6
24
  this.missingEnvVars = [];
25
+ /** the resolved value of every available required name */
7
26
  this.keyValueObject = {};
8
27
  this.logger = new plugins.smartlog.ConsoleLog();
9
28
  this.qenvFilePathAbsolute = '';
10
29
  this.initializeFilePaths(qenvFileBasePathArg, envFileBasePathArg);
11
- this.loadRequiredEnvVars();
30
+ this.loadRequiredEnvVars(failOnMissing);
12
31
  this.loadAvailableEnvVars();
13
32
  this.checkForMissingEnvVars(failOnMissing);
14
33
  }
@@ -37,21 +56,66 @@ export class Qenv {
37
56
  }
38
57
  }
39
58
  }
40
- loadRequiredEnvVars() {
41
- if (this.fileExists(this.qenvFilePathAbsolute)) {
42
- const qenvFile = this.readObjectFromFile(this.qenvFilePathAbsolute);
43
- const requiredEnvVars = qenvFile.required;
44
- if (Array.isArray(requiredEnvVars)) {
45
- this.requiredEnvVars.push(...requiredEnvVars.filter((envVar) => typeof envVar === 'string'));
46
- }
47
- else {
48
- this.logger.log('warn', 'qenv.yml does not contain a "required" Array!');
59
+ loadRequiredEnvVars(failOnMissing) {
60
+ if (!this.fileExists(this.qenvFilePathAbsolute)) {
61
+ if (failOnMissing) {
62
+ // enforcing without the file that declares what to enforce would pass every check by
63
+ // accident: a deployable that forgot to ship qenv.yml must be refused by name, not
64
+ // silently exempted
65
+ throw new QenvMissingQenvFileError({
66
+ qenvFilePathAbsolute: this.qenvFilePathAbsolute,
67
+ qenvDir: plugins.path.dirname(this.qenvFilePathAbsolute),
68
+ });
49
69
  }
70
+ return;
71
+ }
72
+ const qenvFile = this.readObjectFromFile(this.qenvFilePathAbsolute);
73
+ const declaredRequirements = qenvFile['required'];
74
+ if (declaredRequirements === undefined || declaredRequirements === null) {
75
+ // a qenv.yml that lists no requirement legitimately requires nothing
76
+ return;
50
77
  }
78
+ if (!Array.isArray(declaredRequirements)) {
79
+ this.refuseInvalidQenvFile(failOnMissing, 'requiredNotAnArray', declaredRequirements);
80
+ return;
81
+ }
82
+ const declaredEntries = declaredRequirements;
83
+ const invalidEntryIndex = declaredEntries.findIndex((entry) => typeof entry !== 'string');
84
+ if (invalidEntryIndex !== -1) {
85
+ this.refuseInvalidQenvFile(failOnMissing, 'requiredEntryNotAString', declaredEntries[invalidEntryIndex]);
86
+ }
87
+ this.requiredEnvVars.push(...declaredEntries.filter((entry) => typeof entry === 'string'));
88
+ }
89
+ /**
90
+ * Refuses a qenv.yml whose `required:` cannot be read as names: it enforces nothing, which is
91
+ * the fail-open a missing qenv.yml would be. A caller that opted out of failing keeps running,
92
+ * but hears the same named reason instead of losing the requirement silently.
93
+ */
94
+ refuseInvalidQenvFile(failOnMissing, reason, invalidValue) {
95
+ const invalidQenvFileError = new QenvInvalidQenvFileError({
96
+ qenvFilePathAbsolute: this.qenvFilePathAbsolute,
97
+ reason,
98
+ invalidValueTypeName: this.describeValueType(invalidValue),
99
+ });
100
+ if (failOnMissing) {
101
+ throw invalidQenvFileError;
102
+ }
103
+ this.logger.log('warn', invalidQenvFileError.message);
104
+ }
105
+ /** names the type of a value without rendering it: a value in a name's place may be a secret */
106
+ describeValueType(valueArg) {
107
+ if (valueArg === null) {
108
+ return 'null';
109
+ }
110
+ return Array.isArray(valueArg) ? 'array' : typeof valueArg;
51
111
  }
52
112
  loadAvailableEnvVars() {
113
+ // resolved synchronously: a required env var is always a name, and every source a name can come
114
+ // from - process environment, env file, Docker secrets - is a synchronous read. Resolving it
115
+ // here as a promise would store a pending promise instead of a value and make the check below
116
+ // pass for every name.
53
117
  for (const envVar of this.requiredEnvVars) {
54
- const value = this.getEnvVarOnDemand(envVar);
118
+ const value = this.tryGetEnvVarSync(envVar);
55
119
  if (value !== undefined) {
56
120
  this.availableEnvVars.push(envVar);
57
121
  this.keyValueObject[envVar] = value;
@@ -60,18 +124,24 @@ export class Qenv {
60
124
  }
61
125
  checkForMissingEnvVars(failOnMissing) {
62
126
  this.missingEnvVars = this.requiredEnvVars.filter((envVar) => !this.availableEnvVars.includes(envVar));
63
- if (this.missingEnvVars.length > 0) {
64
- console.info('Required Env Vars are:', this.requiredEnvVars);
65
- console.error('Missing Env Vars:', this.missingEnvVars);
66
- if (failOnMissing) {
67
- this.logger.log('error', 'Exiting due to missing env vars!');
68
- process.exit(1);
69
- }
70
- else {
71
- this.logger.log('warn', 'qenv is not set to fail on missing environment variables');
72
- }
127
+ if (this.missingEnvVars.length === 0) {
128
+ return;
129
+ }
130
+ if (failOnMissing) {
131
+ // a library must not end the process: the caller decides what an incomplete environment means
132
+ throw new QenvMissingRequiredEnvVarsError({
133
+ missingEnvVars: this.missingEnvVars,
134
+ requiredEnvVars: this.requiredEnvVars,
135
+ qenvFilePathAbsolute: this.qenvFilePathAbsolute,
136
+ });
73
137
  }
138
+ this.logger.log('warn', `qenv is not set to fail on missing environment variables. Missing: ${this.missingEnvVars.join(', ')}`);
74
139
  }
140
+ /**
141
+ * Resolves an env var from the process environment, the env file and the Docker secrets, in that
142
+ * order. An array is tried left to right and the first defined value wins.
143
+ * @param envVarNameOrNames a name, an async resolver function, or a list of either
144
+ */
75
145
  async getEnvVarOnDemand(envVarNameOrNames) {
76
146
  if (Array.isArray(envVarNameOrNames)) {
77
147
  for (const envVarName of envVarNameOrNames) {
@@ -87,19 +157,22 @@ export class Qenv {
87
157
  }
88
158
  }
89
159
  /**
90
- * Like getEnvVarOnDemand, but throws an error if the env var is not set.
91
- * @param envVarNameOrNames
92
- * @returns
160
+ * Like getEnvVarOnDemand, but throws when no source provides a value.
161
+ * @param envVarNameOrNames a name, an async resolver function, or a list of either
93
162
  */
94
163
  async getEnvVarOnDemandStrict(envVarNameOrNames) {
95
164
  const value = await this.getEnvVarOnDemand(envVarNameOrNames);
96
165
  if (value === undefined) {
97
- throw new Error(`Env var ${envVarNameOrNames} is not set!`);
166
+ throw new Error(`Env var ${this.describeEnvVarRefs(envVarNameOrNames)} is not set!`);
98
167
  }
99
168
  return value;
100
169
  }
170
+ /**
171
+ * The synchronous counterpart of getEnvVarOnDemand. It resolves names only: an async resolver
172
+ * function cannot be awaited here, so the function form of TEnvVarRef is not accepted.
173
+ * @param envVarNameOrNames a name or a list of names
174
+ */
101
175
  getEnvVarOnDemandSync(envVarNameOrNames) {
102
- console.warn('requesting env var sync leaves out potentially important async env sources.');
103
176
  if (Array.isArray(envVarNameOrNames)) {
104
177
  for (const envVarName of envVarNameOrNames) {
105
178
  const value = this.tryGetEnvVarSync(envVarName);
@@ -113,6 +186,11 @@ export class Qenv {
113
186
  return this.tryGetEnvVarSync(envVarNameOrNames);
114
187
  }
115
188
  }
189
+ /**
190
+ * Resolves an env var whose value was stored as a base64 encoded object and decodes it. A plain
191
+ * value is returned as the string it is, so the caller narrows what it gets.
192
+ * @param envVarNameOrNames a name or a list of names
193
+ */
116
194
  async getEnvVarOnDemandAsObject(envVarNameOrNames) {
117
195
  const rawValue = await this.getEnvVarOnDemand(envVarNameOrNames);
118
196
  if (rawValue && rawValue.startsWith('base64Object:')) {
@@ -125,33 +203,36 @@ export class Qenv {
125
203
  if (typeof envVarRefArg === 'function') {
126
204
  return await envVarRefArg();
127
205
  }
128
- const sources = [
129
- this.getFromEnvironmentVariable(envVarRefArg),
130
- this.getFromEnvYamlOrJsonFile(envVarRefArg),
131
- this.getFromDockerSecret(envVarRefArg),
132
- this.getFromDockerSecretJson(envVarRefArg)
133
- ];
134
- for (const value of sources) {
135
- if (value !== undefined) {
136
- return value;
137
- }
138
- }
139
- return undefined;
206
+ // a name resolves from synchronous sources only, so both getters share one resolution order
207
+ return this.tryGetEnvVarSync(envVarRefArg);
140
208
  }
141
209
  tryGetEnvVarSync(envVarName) {
210
+ // read lazily: a source is only touched once every earlier one came back undefined, so a name
211
+ // the process environment answers never opens a secret file, and a malformed secret.json only
212
+ // ever affects the names that actually reach it
142
213
  const sources = [
143
- this.getFromEnvironmentVariable(envVarName),
144
- this.getFromEnvYamlOrJsonFile(envVarName),
145
- this.getFromDockerSecret(envVarName),
146
- this.getFromDockerSecretJson(envVarName)
214
+ () => this.getFromEnvironmentVariable(envVarName),
215
+ () => this.getFromEnvYamlOrJsonFile(envVarName),
216
+ () => this.getFromDockerSecret(envVarName),
217
+ () => this.getFromDockerSecretJson(envVarName),
147
218
  ];
148
- for (const value of sources) {
219
+ for (const readSource of sources) {
220
+ const value = readSource();
149
221
  if (value !== undefined) {
150
222
  return value;
151
223
  }
152
224
  }
153
225
  return undefined;
154
226
  }
227
+ /** renders env var references for an error message, naming a resolver function where it has one */
228
+ describeEnvVarRefs(envVarNameOrNames) {
229
+ const envVarRefs = Array.isArray(envVarNameOrNames) ? envVarNameOrNames : [envVarNameOrNames];
230
+ return envVarRefs
231
+ .map((envVarRef) => typeof envVarRef === 'function'
232
+ ? `${envVarRef.name || 'anonymous'}()`
233
+ : envVarRef)
234
+ .join(', ');
235
+ }
155
236
  getFromEnvironmentVariable(envVarName) {
156
237
  return process.env[envVarName];
157
238
  }
@@ -174,19 +255,27 @@ export class Qenv {
174
255
  return undefined;
175
256
  }
176
257
  }
258
+ /**
259
+ * the directory Docker mounts secrets into. It is a method so a test can point both secret
260
+ * readers at a directory it is allowed to create; a process can never write /run/secrets itself.
261
+ */
262
+ getDockerSecretsDirectoryPath() {
263
+ return '/run/secrets';
264
+ }
177
265
  getFromDockerSecret(envVarName) {
178
- const secretPath = `/run/secrets/${envVarName}`;
266
+ const secretPath = plugins.path.join(this.getDockerSecretsDirectoryPath(), envVarName);
179
267
  if (this.fileExists(secretPath)) {
180
268
  return plugins.fs.readFileSync(secretPath, 'utf8');
181
269
  }
182
270
  return undefined;
183
271
  }
184
272
  getFromDockerSecretJson(envVarName) {
185
- if (this.directoryExists('/run/secrets')) {
186
- const availableSecrets = plugins.fs.readdirSync('/run/secrets');
273
+ const secretsDirectoryPath = this.getDockerSecretsDirectoryPath();
274
+ if (this.directoryExists(secretsDirectoryPath)) {
275
+ const availableSecrets = plugins.fs.readdirSync(secretsDirectoryPath);
187
276
  for (const secret of availableSecrets) {
188
277
  if (secret.includes('secret.json')) {
189
- const secretObject = this.readObjectFromFile(`/run/secrets/${secret}`);
278
+ const secretObject = this.readObjectFromFile(plugins.path.join(secretsDirectoryPath, secret));
190
279
  const value = secretObject[envVarName];
191
280
  if (value === undefined) {
192
281
  continue;
@@ -227,7 +316,9 @@ export class Qenv {
227
316
  const parsedObject = filePath.endsWith('.json')
228
317
  ? JSON.parse(fileString)
229
318
  : plugins.yaml.parse(fileString);
230
- return typeof parsedObject === 'object' && parsedObject !== null ? parsedObject : {};
319
+ return typeof parsedObject === 'object' && parsedObject !== null
320
+ ? parsedObject
321
+ : {};
231
322
  }
232
323
  }
233
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWVudi5jbGFzc2VzLnFlbnYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9xZW52LmNsYXNzZXMucWVudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBSzdDLE1BQU0sT0FBTyxJQUFJO0lBVWYsWUFDRSxzQkFBOEIsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUMzQyxrQkFBMkIsRUFDM0IsZ0JBQXlCLElBQUk7UUFaeEIsb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFDL0IscUJBQWdCLEdBQWEsRUFBRSxDQUFDO1FBQ2hDLG1CQUFjLEdBQWEsRUFBRSxDQUFDO1FBQzlCLG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyxXQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRTNDLHlCQUFvQixHQUFHLEVBQUUsQ0FBQztRQVEvQixJQUFJLENBQUMsbUJBQW1CLENBQUMsbUJBQW1CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVPLG1CQUFtQixDQUFDLG1CQUEyQixFQUFFLGtCQUEyQjtRQUNsRixJQUFJLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQzNDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEVBQ3pDLFVBQVUsQ0FDWCxDQUFDO1FBRUYsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFakUsTUFBTSxlQUFlLEdBQUcsT0FBTyxD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
324
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWVudi5jbGFzc2VzLnFlbnYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9xZW52LmNsYXNzZXMucWVudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFDTCx3QkFBd0IsR0FFekIsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQWNoRyxNQUFNLE9BQU8sSUFBSTtJQWtCZjs7Ozs7Ozs7Ozs7T0FXRztJQUNILFlBQ0Usc0JBQThCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFDM0Msa0JBQTJCLEVBQzNCLGdCQUF5QixJQUFJO1FBaEMvQixxREFBcUQ7UUFDOUMsb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFFdEMsZ0RBQWdEO1FBQ3pDLHFCQUFnQixHQUFhLEVBQUUsQ0FBQztRQUV2QyxpREFBaUQ7UUFDMUMsbUJBQWMsR0FBYSxFQUFFLENBQUM7UUFFckMsMERBQTBEO1FBQ25ELG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUVyQyxXQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRTNDLHlCQUFvQixHQUFHLEVBQUUsQ0FBQztRQW9CL0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLG1CQUFtQixFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRU8sbUJBQW1CLENBQUMsbUJBQTJCLEVBQUUsa0JBQTJCO1FBQ2xGLElBQUksQ0FBQyxvQkFBb0Is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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/qenv",
3
- "version": "7.0.0",
3
+ "version": "8.1.0",
4
4
  "private": false,
5
5
  "description": "A module for easily handling environment variables in Node.js projects with support for .yml and .json configuration.",
6
6
  "main": "dist_ts/index.js",
@@ -22,14 +22,14 @@
22
22
  "author": "Task Venture Capital GmbH <hello@task.vc>",
23
23
  "license": "MIT",
24
24
  "bugs": {
25
- "url": "https://gitlab.com/pushrocks/qenv/issues"
25
+ "url": "https://code.foss.global/push.rocks/qenv/issues"
26
26
  },
27
27
  "homepage": "https://code.foss.global/push.rocks/qenv",
28
28
  "devDependencies": {
29
- "@git.zone/tsbuild": "^4.4.3",
29
+ "@git.zone/tsbuild": "^4.5.0",
30
30
  "@git.zone/tsrun": "^2.0.6",
31
- "@git.zone/tstest": "^6.1.0",
32
- "@types/node": "^26.5.0"
31
+ "@git.zone/tstest": "^6.1.1",
32
+ "@types/node": "^26.5.1"
33
33
  },
34
34
  "dependencies": {
35
35
  "@push.rocks/smartlog": "^3.2.2",