@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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -1
- package/dist_ts/qenv.classes.invalidqenvfileerror.d.ts +21 -0
- package/dist_ts/qenv.classes.invalidqenvfileerror.js +25 -0
- package/dist_ts/qenv.classes.missingqenvfileerror.d.ts +16 -0
- package/dist_ts/qenv.classes.missingqenvfileerror.js +19 -0
- package/dist_ts/qenv.classes.missingrequiredenvvarserror.d.ts +18 -0
- package/dist_ts/qenv.classes.missingrequiredenvvarserror.js +19 -0
- package/dist_ts/qenv.classes.qenv.d.ts +56 -7
- package/dist_ts/qenv.classes.qenv.js +140 -49
- package/package.json +5 -5
- package/readme.md +120 -15
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +3 -0
- package/ts/qenv.classes.invalidqenvfileerror.ts +43 -0
- package/ts/qenv.classes.missingqenvfileerror.ts +28 -0
- package/ts/qenv.classes.missingrequiredenvvarserror.ts +30 -0
- package/ts/qenv.classes.qenv.ts +194 -65
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/qenv',
|
|
6
|
-
version: '
|
|
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=
|
package/dist_ts/index.d.ts
CHANGED
package/dist_ts/index.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export * from './qenv.classes.qenv.js';
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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.
|
|
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
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.
|
|
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
|
|
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
|
-
|
|
129
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
186
|
-
|
|
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(
|
|
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
|
|
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": "
|
|
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://
|
|
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.
|
|
29
|
+
"@git.zone/tsbuild": "^4.5.0",
|
|
30
30
|
"@git.zone/tsrun": "^2.0.6",
|
|
31
|
-
"@git.zone/tstest": "^6.1.
|
|
32
|
-
"@types/node": "^26.5.
|
|
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",
|