@adonisjs/env 4.2.0-2 → 4.2.0-4

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @adonisjs/env
2
2
  > Environment variables parser and validator used by the AdonisJS.
3
3
 
4
- [![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url] [![synk-image]][synk-url]
4
+ [![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
5
5
 
6
6
  > **Note:** This package is framework agnostic and can also be used outside of AdonisJS.
7
7
 
@@ -135,8 +135,8 @@ try {
135
135
  }
136
136
  ```
137
137
 
138
- [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/env/test.yml?style=for-the-badge
139
- [gh-workflow-url]: https://github.com/adonisjs/env/actions/workflows/test.yml "Github action"
138
+ [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/env/checks.yml?style=for-the-badge
139
+ [gh-workflow-url]: https://github.com/adonisjs/env/actions/workflows/checks.yml "Github action"
140
140
 
141
141
  [typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
142
142
  [typescript-url]: "typescript"
@@ -146,6 +146,3 @@ try {
146
146
 
147
147
  [license-image]: https://img.shields.io/npm/l/@adonisjs/env?color=blueviolet&style=for-the-badge
148
148
  [license-url]: LICENSE.md "license"
149
-
150
- [synk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/env?label=Synk%20Vulnerabilities&style=for-the-badge
151
- [synk-url]: https://snyk.io/test/github/adonisjs/env?targetFile=package.json "synk"
package/build/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export { Env } from './src/env.js';
2
2
  export { EnvParser } from './src/parser.js';
3
3
  export { EnvLoader } from './src/loader.js';
4
- export { EnvEditor } from './src/editor.js';
5
4
  export * as errors from './src/exceptions.js';
6
5
  export { EnvProcessor } from './src/processor.js';
7
- //# sourceMappingURL=index.d.ts.map
package/build/index.js CHANGED
@@ -1,6 +1,13 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  export { Env } from './src/env.js';
2
10
  export { EnvParser } from './src/parser.js';
3
11
  export { EnvLoader } from './src/loader.js';
4
- export { EnvEditor } from './src/editor.js';
5
12
  export * as errors from './src/exceptions.js';
6
13
  export { EnvProcessor } from './src/processor.js';
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
2
  declare const _default: import("util").DebugLogger;
3
3
  export default _default;
4
- //# sourceMappingURL=debug.d.ts.map
@@ -1,2 +1,10 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  import { debuglog } from 'node:util';
2
10
  export default debuglog('adonisjs:env');
@@ -1,14 +1,27 @@
1
- /// <reference types="node" resolution-mode="require"/>
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
2
  export declare class EnvEditor {
3
3
  #private;
4
+ /**
5
+ * Creates an instance of env editor and loads .env files
6
+ * contents.
7
+ */
4
8
  static create(appRoot: URL): Promise<EnvEditor>;
5
9
  constructor(appRoot: URL);
10
+ /**
11
+ * Loads .env files for editing. Only ".env" and ".env.example"
12
+ * files are picked for editing.
13
+ */
6
14
  load(): Promise<void>;
15
+ /**
16
+ * Add key-value pair to the dot-env files.
17
+ */
7
18
  add(key: string, value: string | number | boolean): void;
8
19
  toJSON(): {
9
20
  contents: string[];
10
21
  path: string;
11
22
  }[];
23
+ /**
24
+ * Save changes to the disk
25
+ */
12
26
  save(): Promise<void>;
13
27
  }
14
- //# sourceMappingURL=editor.d.ts.map
@@ -1,3 +1,11 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  import splitLines from 'split-lines';
2
10
  import lodash from '@poppinss/utils/lodash';
3
11
  import { writeFile } from 'node:fs/promises';
@@ -6,6 +14,10 @@ export class EnvEditor {
6
14
  #appRoot;
7
15
  #loader;
8
16
  #files = [];
17
+ /**
18
+ * Creates an instance of env editor and loads .env files
19
+ * contents.
20
+ */
9
21
  static async create(appRoot) {
10
22
  const editor = new EnvEditor(appRoot);
11
23
  await editor.load();
@@ -15,6 +27,10 @@ export class EnvEditor {
15
27
  this.#appRoot = appRoot;
16
28
  this.#loader = new EnvLoader(this.#appRoot, true);
17
29
  }
30
+ /**
31
+ * Loads .env files for editing. Only ".env" and ".env.example"
32
+ * files are picked for editing.
33
+ */
18
34
  async load() {
19
35
  const envFiles = await this.#loader.load();
20
36
  this.#files = envFiles
@@ -27,6 +43,9 @@ export class EnvEditor {
27
43
  };
28
44
  });
29
45
  }
46
+ /**
47
+ * Add key-value pair to the dot-env files.
48
+ */
30
49
  add(key, value) {
31
50
  this.#files.forEach((file) => {
32
51
  let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
@@ -37,6 +56,9 @@ export class EnvEditor {
37
56
  toJSON() {
38
57
  return this.#files;
39
58
  }
59
+ /**
60
+ * Save changes to the disk
61
+ */
40
62
  async save() {
41
63
  await Promise.all(this.#files.map((file) => {
42
64
  return writeFile(file.path, file.contents.join('\n'));
@@ -1,28 +1,82 @@
1
- /// <reference types="node" resolution-mode="require"/>
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
2
  import { type ValidateFn } from '@poppinss/validator-lite';
3
3
  import { EnvValidator } from './validator.js';
4
+ /**
5
+ * A wrapper over "process.env" with types information.
6
+ *
7
+ * ```ts
8
+ * const validate = Env.rules({
9
+ * PORT: Env.schema.number()
10
+ * })
11
+ *
12
+ * const validatedEnvVars = validate(process.env)
13
+ *
14
+ * const env = new EnvValues(validatedEnvVars)
15
+ * env.get('PORT') // type === number
16
+ * ```
17
+ */
4
18
  export declare class Env<EnvValues extends Record<string, any>> {
5
19
  #private;
6
20
  constructor(values: EnvValues);
21
+ /**
22
+ * Create an instance of the env class by validating the
23
+ * environment variables. Also, the `.env` files are
24
+ * loaded from the appRoot
25
+ */
7
26
  static create<Schema extends {
8
27
  [key: string]: ValidateFn<unknown>;
9
28
  }>(appRoot: URL, schema: Schema): Promise<Env<{
10
29
  [K in keyof Schema]: ReturnType<Schema[K]>;
11
30
  }>>;
31
+ /**
32
+ * The schema builder for defining validation rules
33
+ */
12
34
  static schema: {
13
35
  number: typeof import("@poppinss/validator-lite/build/src/schema/number.js").number;
14
36
  string: typeof import("@poppinss/validator-lite/build/src/schema/string.js").string;
15
37
  boolean: typeof import("@poppinss/validator-lite/build/src/schema/boolean.js").boolean;
16
38
  enum: typeof import("@poppinss/validator-lite/build/src/schema/oneOf.js").oneOf;
17
39
  };
40
+ /**
41
+ * Define the validation rules for validating environment
42
+ * variables. The return value is an instance of the
43
+ * env validator
44
+ */
18
45
  static rules<T extends {
19
46
  [key: string]: ValidateFn<unknown>;
20
47
  }>(schema: T): EnvValidator<T>;
48
+ /**
49
+ * Get the value of an environment variable by key. The values are
50
+ * lookedup inside the validated environment and "process.env"
51
+ * is used as a fallback.
52
+ *
53
+ * The second param is the default value, which is returned when
54
+ * the environment variable does not exist.
55
+ *
56
+ * ```ts
57
+ * Env.get('PORT')
58
+ *
59
+ * // With default value
60
+ * Env.get('PORT', 3000)
61
+ * ```
62
+ */
21
63
  get<K extends keyof EnvValues>(key: K): EnvValues[K];
22
64
  get<K extends keyof EnvValues>(key: K, defaultValue: Exclude<EnvValues[K], undefined>): Exclude<EnvValues[K], undefined>;
23
65
  get(key: string): string | undefined;
24
66
  get(key: string, defaultValue: string): string;
67
+ /**
68
+ * Update/set value of an environment variable.
69
+ *
70
+ * The value is not casted/validated using the validator, so make sure
71
+ * to set the correct data type.
72
+ *
73
+ * ```ts
74
+ * Env.set('PORT', 3000)
75
+ *
76
+ * Env.get('PORT') === 3000 // true
77
+ * process.env.PORT === '3000' // true
78
+ * ```
79
+ */
25
80
  set<K extends keyof EnvValues>(key: K, value: EnvValues[K]): void;
26
81
  set(key: string, value: string): void;
27
82
  }
28
- //# sourceMappingURL=env.d.ts.map
package/build/src/env.js CHANGED
@@ -1,29 +1,76 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  import { schema as envSchema } from '@poppinss/validator-lite';
2
10
  import { EnvValidator } from './validator.js';
3
11
  import { EnvProcessor } from './processor.js';
4
- class Env {
12
+ /**
13
+ * A wrapper over "process.env" with types information.
14
+ *
15
+ * ```ts
16
+ * const validate = Env.rules({
17
+ * PORT: Env.schema.number()
18
+ * })
19
+ *
20
+ * const validatedEnvVars = validate(process.env)
21
+ *
22
+ * const env = new EnvValues(validatedEnvVars)
23
+ * env.get('PORT') // type === number
24
+ * ```
25
+ */
26
+ export class Env {
27
+ /**
28
+ * A cache of env values
29
+ */
5
30
  #values;
6
31
  constructor(values) {
7
32
  this.#values = values;
8
33
  }
34
+ /**
35
+ * Create an instance of the env class by validating the
36
+ * environment variables. Also, the `.env` files are
37
+ * loaded from the appRoot
38
+ */
9
39
  static async create(appRoot, schema) {
10
40
  const values = await new EnvProcessor(appRoot).process();
11
41
  const validator = this.rules(schema);
12
42
  return new Env(validator.validate(values));
13
43
  }
44
+ /**
45
+ * The schema builder for defining validation rules
46
+ */
14
47
  static schema = envSchema;
48
+ /**
49
+ * Define the validation rules for validating environment
50
+ * variables. The return value is an instance of the
51
+ * env validator
52
+ */
15
53
  static rules(schema) {
16
54
  const validator = new EnvValidator(schema);
17
55
  return validator;
18
56
  }
19
57
  get(key, defaultValue) {
58
+ /**
59
+ * Return cached value
60
+ */
20
61
  if (this.#values[key] !== undefined) {
21
62
  return this.#values[key];
22
63
  }
64
+ /**
65
+ * Get value from "process.env" and update the cache
66
+ */
23
67
  const envValue = process.env[key];
24
68
  if (envValue) {
25
69
  return envValue;
26
70
  }
71
+ /**
72
+ * Return default value when unable to lookup any other value
73
+ */
27
74
  return defaultValue;
28
75
  }
29
76
  set(key, value) {
@@ -31,4 +78,3 @@ class Env {
31
78
  process.env[key] = value;
32
79
  }
33
80
  }
34
- export { Env };
@@ -1,4 +1,8 @@
1
- /// <reference types="node" resolution-mode="require"/>
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
+ /**
3
+ * Exception raised when one or more env variables
4
+ * are invalid
5
+ */
2
6
  export declare const E_INVALID_ENV_VARIABLES: {
3
7
  new (message?: string | undefined, options?: (ErrorOptions & {
4
8
  code?: string | undefined;
@@ -22,4 +26,3 @@ export declare const E_INVALID_ENV_VARIABLES: {
22
26
  prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
23
27
  stackTraceLimit: number;
24
28
  };
25
- //# sourceMappingURL=exceptions.d.ts.map
@@ -1,4 +1,16 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  import { Exception } from '@poppinss/utils';
10
+ /**
11
+ * Exception raised when one or more env variables
12
+ * are invalid
13
+ */
2
14
  export const E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
3
15
  static message = 'Validation failed for one or more environment variables';
4
16
  static code = 'E_INVALID_ENV_VARIABLES';
@@ -1,11 +1,36 @@
1
- /// <reference types="node" resolution-mode="require"/>
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
+ /**
3
+ * Read the contents of one or more dot-env files. Following is how the files
4
+ * are read.
5
+ *
6
+ * - Load file from the "ENV_PATH" environment file.
7
+ * (Raise error if file is missing)
8
+ *
9
+ * - If "ENV_PATH" is not defined, then find ".env" file in the app root.
10
+ * (Ignore if file is missing)
11
+ *
12
+ * - Find ".env.[NODE_ENV]" file in the app root.
13
+ * (Ignore if file is missing)
14
+ *
15
+ * ```ts
16
+ * const loader = new EnvLoader(new URL('./', import.meta.url))
17
+ *
18
+ * const { envContents, currentEnvContents } = await loader.load()
19
+ *
20
+ * // envContents: Contents of .env or file specified via ENV_PATH
21
+ * // currentEnvContents: Contents of .env.[NODE_ENV] file
22
+ * ```
23
+ */
2
24
  export declare class EnvLoader {
3
25
  #private;
4
26
  constructor(appRoot: string | URL, loadExampleFile?: boolean);
27
+ /**
28
+ * Load contents of the main dot-env file and the current
29
+ * environment dot-env file
30
+ */
5
31
  load(): Promise<{
6
32
  contents: string;
7
33
  path: string;
8
34
  fileExists: boolean;
9
35
  }[]>;
10
36
  }
11
- //# sourceMappingURL=loader.d.ts.map
@@ -1,7 +1,37 @@
1
+ /*
2
+ * @adonisjs/env
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
1
9
  import { fileURLToPath } from 'node:url';
2
10
  import { readFile } from 'node:fs/promises';
3
11
  import { isAbsolute, join } from 'node:path';
4
12
  import debug from './debug.js';
13
+ /**
14
+ * Read the contents of one or more dot-env files. Following is how the files
15
+ * are read.
16
+ *
17
+ * - Load file from the "ENV_PATH" environment file.
18
+ * (Raise error if file is missing)
19
+ *
20
+ * - If "ENV_PATH" is not defined, then find ".env" file in the app root.
21
+ * (Ignore if file is missing)
22
+ *
23
+ * - Find ".env.[NODE_ENV]" file in the app root.
24
+ * (Ignore if file is missing)
25
+ *
26
+ * ```ts
27
+ * const loader = new EnvLoader(new URL('./', import.meta.url))
28
+ *
29
+ * const { envContents, currentEnvContents } = await loader.load()
30
+ *
31
+ * // envContents: Contents of .env or file specified via ENV_PATH
32
+ * // currentEnvContents: Contents of .env.[NODE_ENV] file
33
+ * ```
34
+ */
5
35
  export class EnvLoader {
6
36
  #appRoot;
7
37
  #loadExampleFile;
@@ -9,18 +39,26 @@ export class EnvLoader {
9
39
  this.#appRoot = typeof appRoot === 'string' ? appRoot : fileURLToPath(appRoot);
10
40
  this.#loadExampleFile = loadExampleFile;
11
41
  }
42
+ /**
43
+ * Optionally read a file from the disk
44
+ */
12
45
  async #loadFile(filePath) {
13
46
  try {
14
47
  const contents = await readFile(filePath, 'utf-8');
15
48
  return { contents, fileExists: true };
16
49
  }
17
50
  catch (error) {
51
+ /* c8 ignore next 3 */
18
52
  if (error.code !== 'ENOENT') {
19
53
  throw error;
20
54
  }
21
55
  return { contents: '', fileExists: false };
22
56
  }
23
57
  }
58
+ /**
59
+ * Load contents of the main dot-env file and the current
60
+ * environment dot-env file
61
+ */
24
62
  async load() {
25
63
  const ENV_PATH = process.env.ENV_PATH;
26
64
  const NODE_ENV = process.env.NODE_ENV;
@@ -29,6 +67,9 @@ export class EnvLoader {
29
67
  debug('ENV_PATH variable is %s', ENV_PATH ? 'set' : 'not set');
30
68
  debug('NODE_ENV variable is %s', NODE_ENV ? 'set' : 'not set');
31
69
  }
70
+ /**
71
+ * Base path to load .env files from
72
+ */
32
73
  const baseEnvPath = ENV_PATH
33
74
  ? isAbsolute(ENV_PATH)
34
75
  ? ENV_PATH
@@ -37,6 +78,10 @@ export class EnvLoader {
37
78
  if (debug.enabled) {
38
79
  debug('dot-env files base path "%s"', baseEnvPath);
39
80
  }
81
+ /**
82
+ * 1st
83
+ * The top most priority is given to the ".env.[NODE_ENV].local" file
84
+ */
40
85
  if (NODE_ENV) {
41
86
  const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
42
87
  envFiles.push({
@@ -44,6 +89,10 @@ export class EnvLoader {
44
89
  ...(await this.#loadFile(nodeEnvLocalFile)),
45
90
  });
46
91
  }
92
+ /**
93
+ * 2nd
94
+ * Next, we give priority to the ".env.local" file
95
+ */
47
96
  if (!NODE_ENV || !['test', 'testing'].includes(NODE_ENV)) {
48
97
  const envLocalFile = join(baseEnvPath, '.env.local');
49
98
  envFiles.push({
@@ -51,6 +100,10 @@ export class EnvLoader {
51
100
  ...(await this.#loadFile(envLocalFile)),
52
101
  });
53
102
  }
103
+ /**
104
+ * 3rd
105
+ * Next, we give priority to the ".env.[NODE_ENV]" file
106
+ */
54
107
  if (NODE_ENV) {
55
108
  const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
56
109
  envFiles.push({
@@ -58,11 +111,17 @@ export class EnvLoader {
58
111
  ...(await this.#loadFile(nodeEnvFile)),
59
112
  });
60
113
  }
114
+ /**
115
+ * Finally, we push the contents of the ".env" file.
116
+ */
61
117
  const envFile = join(baseEnvPath, '.env');
62
118
  envFiles.push({
63
119
  path: envFile,
64
120
  ...(await this.#loadFile(envFile)),
65
121
  });
122
+ /**
123
+ * Load example file
124
+ */
66
125
  if (this.#loadExampleFile) {
67
126
  const envExampleFile = join(baseEnvPath, '.env.example');
68
127
  envFiles.push({
@@ -1,9 +1,51 @@
1
1
  import { DotenvParseOutput } from 'dotenv';
2
+ /**
3
+ * Env parser parses the environment variables from a string formatted
4
+ * as a key-value pair seperated using an `=`. For example:
5
+ *
6
+ * ```dotenv
7
+ * PORT=3333
8
+ * HOST=127.0.0.1
9
+ * ```
10
+ *
11
+ * The variables can reference other environment variables as well using `$`.
12
+ * For example:
13
+ *
14
+ * ```dotenv
15
+ * PORT=3333
16
+ * REDIS_PORT=$PORT
17
+ * ```
18
+ *
19
+ * The variables using characters other than letters can wrap variable
20
+ * named inside a curly brace.
21
+ *
22
+ * ```dotenv
23
+ * APP-PORT=3333
24
+ * REDIS_PORT=${APP-PORT}
25
+ * ```
26
+ *
27
+ * You can escape the `$` sign with a backtick.
28
+ *
29
+ * ```dotenv
30
+ * REDIS_PASSWORD=foo\$123
31
+ * ```
32
+ *
33
+ * ## Usage
34
+ *
35
+ * ```ts
36
+ * const parser = new EnvParser(envContents)
37
+ * const output = parser.parse()
38
+ *
39
+ * // The output is a key-value pair
40
+ * ```
41
+ */
2
42
  export declare class EnvParser {
3
43
  #private;
4
44
  constructor(envContents: string, options?: {
5
45
  ignoreProcessEnv: boolean;
6
46
  });
47
+ /**
48
+ * Parse the env string to an object of environment variables.
49
+ */
7
50
  parse(): DotenvParseOutput;
8
51
  }
9
- //# sourceMappingURL=parser.d.ts.map