@adonisjs/env 4.2.0-5 → 4.2.0-7

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
@@ -110,7 +110,7 @@ env.get('NODE_ENV') // is unknown, hence a string or undefined
110
110
  The Env editor can be used to edit dot-env files and persist changes on disk. Only the `.env` and `.env.example` files are updated (if exists).
111
111
 
112
112
  ```ts
113
- import { EnvEditor } from '@adonisjs/env'
113
+ import { EnvEditor } from '@adonisjs/env/editor'
114
114
 
115
115
  const editor = await EnvEditor.create(new URL('./', import.meta.url))
116
116
  editor.add('PORT', 3000)
@@ -0,0 +1,96 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/loader.ts
8
+ import { fileURLToPath } from "node:url";
9
+ import { readFile } from "node:fs/promises";
10
+ import { isAbsolute, join } from "node:path";
11
+
12
+ // src/debug.ts
13
+ import { debuglog } from "node:util";
14
+ var debug_default = debuglog("adonisjs:env");
15
+
16
+ // src/loader.ts
17
+ var EnvLoader = class {
18
+ #appRoot;
19
+ #loadExampleFile;
20
+ constructor(appRoot, loadExampleFile = false) {
21
+ this.#appRoot = typeof appRoot === "string" ? appRoot : fileURLToPath(appRoot);
22
+ this.#loadExampleFile = loadExampleFile;
23
+ }
24
+ /**
25
+ * Optionally read a file from the disk
26
+ */
27
+ async #loadFile(filePath) {
28
+ try {
29
+ const contents = await readFile(filePath, "utf-8");
30
+ return { contents, fileExists: true };
31
+ } catch (error) {
32
+ if (error.code !== "ENOENT") {
33
+ throw error;
34
+ }
35
+ return { contents: "", fileExists: false };
36
+ }
37
+ }
38
+ /**
39
+ * Load contents of the main dot-env file and the current
40
+ * environment dot-env file
41
+ */
42
+ async load() {
43
+ const ENV_PATH = process.env.ENV_PATH;
44
+ const NODE_ENV = process.env.NODE_ENV;
45
+ const envFiles = [];
46
+ if (debug_default.enabled) {
47
+ debug_default("ENV_PATH variable is %s", ENV_PATH ? "set" : "not set");
48
+ debug_default("NODE_ENV variable is %s", NODE_ENV ? "set" : "not set");
49
+ }
50
+ const baseEnvPath = ENV_PATH ? isAbsolute(ENV_PATH) ? ENV_PATH : join(this.#appRoot, ENV_PATH) : this.#appRoot;
51
+ if (debug_default.enabled) {
52
+ debug_default('dot-env files base path "%s"', baseEnvPath);
53
+ }
54
+ if (NODE_ENV) {
55
+ const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
56
+ envFiles.push({
57
+ path: nodeEnvLocalFile,
58
+ ...await this.#loadFile(nodeEnvLocalFile)
59
+ });
60
+ }
61
+ if (!NODE_ENV || !["test", "testing"].includes(NODE_ENV)) {
62
+ const envLocalFile = join(baseEnvPath, ".env.local");
63
+ envFiles.push({
64
+ path: envLocalFile,
65
+ ...await this.#loadFile(envLocalFile)
66
+ });
67
+ }
68
+ if (NODE_ENV) {
69
+ const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
70
+ envFiles.push({
71
+ path: nodeEnvFile,
72
+ ...await this.#loadFile(nodeEnvFile)
73
+ });
74
+ }
75
+ const envFile = join(baseEnvPath, ".env");
76
+ envFiles.push({
77
+ path: envFile,
78
+ ...await this.#loadFile(envFile)
79
+ });
80
+ if (this.#loadExampleFile) {
81
+ const envExampleFile = join(baseEnvPath, ".env.example");
82
+ envFiles.push({
83
+ path: envExampleFile,
84
+ ...await this.#loadFile(envExampleFile)
85
+ });
86
+ }
87
+ return envFiles;
88
+ }
89
+ };
90
+
91
+ export {
92
+ __export,
93
+ debug_default,
94
+ EnvLoader
95
+ };
96
+ //# sourceMappingURL=chunk-H6UKLEIO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/loader.ts","../src/debug.ts"],"sourcesContent":["/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { fileURLToPath } from 'node:url'\nimport { readFile } from 'node:fs/promises'\nimport { isAbsolute, join } from 'node:path'\n\nimport debug from './debug.js'\n\n/**\n * Read the contents of one or more dot-env files. Following is how the files\n * are read.\n *\n * - Load file from the \"ENV_PATH\" environment file.\n * (Raise error if file is missing)\n *\n * - If \"ENV_PATH\" is not defined, then find \".env\" file in the app root.\n * (Ignore if file is missing)\n *\n * - Find \".env.[NODE_ENV]\" file in the app root.\n * (Ignore if file is missing)\n *\n * ```ts\n * const loader = new EnvLoader(new URL('./', import.meta.url))\n *\n * const { envContents, currentEnvContents } = await loader.load()\n *\n * // envContents: Contents of .env or file specified via ENV_PATH\n * // currentEnvContents: Contents of .env.[NODE_ENV] file\n * ```\n */\nexport class EnvLoader {\n #appRoot: string\n #loadExampleFile: boolean\n\n constructor(appRoot: string | URL, loadExampleFile: boolean = false) {\n this.#appRoot = typeof appRoot === 'string' ? appRoot : fileURLToPath(appRoot)\n this.#loadExampleFile = loadExampleFile\n }\n\n /**\n * Optionally read a file from the disk\n */\n async #loadFile(filePath: string | URL): Promise<{ fileExists: boolean; contents: string }> {\n try {\n const contents = await readFile(filePath, 'utf-8')\n return { contents, fileExists: true }\n } catch (error) {\n /* c8 ignore next 3 */\n if (error.code !== 'ENOENT') {\n throw error\n }\n\n return { contents: '', fileExists: false }\n }\n }\n\n /**\n * Load contents of the main dot-env file and the current\n * environment dot-env file\n */\n async load(): Promise<{ contents: string; path: string; fileExists: boolean }[]> {\n const ENV_PATH = process.env.ENV_PATH\n const NODE_ENV = process.env.NODE_ENV\n const envFiles: { path: string; contents: string; fileExists: boolean }[] = []\n\n if (debug.enabled) {\n debug('ENV_PATH variable is %s', ENV_PATH ? 'set' : 'not set')\n debug('NODE_ENV variable is %s', NODE_ENV ? 'set' : 'not set')\n }\n\n /**\n * Base path to load .env files from\n */\n const baseEnvPath = ENV_PATH\n ? isAbsolute(ENV_PATH)\n ? ENV_PATH\n : join(this.#appRoot, ENV_PATH)\n : this.#appRoot\n\n if (debug.enabled) {\n debug('dot-env files base path \"%s\"', baseEnvPath)\n }\n\n /**\n * 1st\n * The top most priority is given to the \".env.[NODE_ENV].local\" file\n */\n if (NODE_ENV) {\n const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`)\n envFiles.push({\n path: nodeEnvLocalFile,\n ...(await this.#loadFile(nodeEnvLocalFile)),\n })\n }\n\n /**\n * 2nd\n * Next, we give priority to the \".env.local\" file\n */\n if (!NODE_ENV || !['test', 'testing'].includes(NODE_ENV)) {\n const envLocalFile = join(baseEnvPath, '.env.local')\n envFiles.push({\n path: envLocalFile,\n ...(await this.#loadFile(envLocalFile)),\n })\n }\n\n /**\n * 3rd\n * Next, we give priority to the \".env.[NODE_ENV]\" file\n */\n if (NODE_ENV) {\n const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`)\n envFiles.push({\n path: nodeEnvFile,\n ...(await this.#loadFile(nodeEnvFile)),\n })\n }\n\n /**\n * Finally, we push the contents of the \".env\" file.\n */\n const envFile = join(baseEnvPath, '.env')\n envFiles.push({\n path: envFile,\n ...(await this.#loadFile(envFile)),\n })\n\n /**\n * Load example file\n */\n if (this.#loadExampleFile) {\n const envExampleFile = join(baseEnvPath, '.env.example')\n envFiles.push({\n path: envExampleFile,\n ...(await this.#loadFile(envExampleFile)),\n })\n }\n\n return envFiles\n }\n}\n","/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { debuglog } from 'node:util'\nexport default debuglog('adonisjs:env')\n"],"mappings":";;;;;;;AASA,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,YAAY,YAAY;;;ACFjC,SAAS,gBAAgB;AACzB,IAAO,gBAAQ,SAAS,cAAc;;;AD2B/B,IAAM,YAAN,MAAgB;AAAA,EACrB;AAAA,EACA;AAAA,EAEA,YAAY,SAAuB,kBAA2B,OAAO;AACnE,SAAK,WAAW,OAAO,YAAY,WAAW,UAAU,cAAc,OAAO;AAC7E,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,UAA4E;AAC1F,QAAI;AACF,YAAM,WAAW,MAAM,SAAS,UAAU,OAAO;AACjD,aAAO,EAAE,UAAU,YAAY,KAAK;AAAA,IACtC,SAAS,OAAO;AAEd,UAAI,MAAM,SAAS,UAAU;AAC3B,cAAM;AAAA,MACR;AAEA,aAAO,EAAE,UAAU,IAAI,YAAY,MAAM;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAA2E;AAC/E,UAAM,WAAW,QAAQ,IAAI;AAC7B,UAAM,WAAW,QAAQ,IAAI;AAC7B,UAAM,WAAsE,CAAC;AAE7E,QAAI,cAAM,SAAS;AACjB,oBAAM,2BAA2B,WAAW,QAAQ,SAAS;AAC7D,oBAAM,2BAA2B,WAAW,QAAQ,SAAS;AAAA,IAC/D;AAKA,UAAM,cAAc,WAChB,WAAW,QAAQ,IACjB,WACA,KAAK,KAAK,UAAU,QAAQ,IAC9B,KAAK;AAET,QAAI,cAAM,SAAS;AACjB,oBAAM,gCAAgC,WAAW;AAAA,IACnD;AAMA,QAAI,UAAU;AACZ,YAAM,mBAAmB,KAAK,aAAa,QAAQ,QAAQ,QAAQ;AACnE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,GAAI,MAAM,KAAK,UAAU,gBAAgB;AAAA,MAC3C,CAAC;AAAA,IACH;AAMA,QAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,SAAS,EAAE,SAAS,QAAQ,GAAG;AACxD,YAAM,eAAe,KAAK,aAAa,YAAY;AACnD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,GAAI,MAAM,KAAK,UAAU,YAAY;AAAA,MACvC,CAAC;AAAA,IACH;AAMA,QAAI,UAAU;AACZ,YAAM,cAAc,KAAK,aAAa,QAAQ,QAAQ,EAAE;AACxD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,GAAI,MAAM,KAAK,UAAU,WAAW;AAAA,MACtC,CAAC;AAAA,IACH;AAKA,UAAM,UAAU,KAAK,aAAa,MAAM;AACxC,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,GAAI,MAAM,KAAK,UAAU,OAAO;AAAA,IAClC,CAAC;AAKD,QAAI,KAAK,kBAAkB;AACzB,YAAM,iBAAiB,KAAK,aAAa,cAAc;AACvD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,GAAI,MAAM,KAAK,UAAU,cAAc;AAAA,MACzC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
package/build/index.d.ts CHANGED
@@ -1,5 +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 * as errors from './src/exceptions.js';
4
+ export * as errors from './src/errors.js';
5
5
  export { EnvProcessor } from './src/processor.js';
package/build/index.js CHANGED
@@ -1,13 +1,252 @@
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
- */
9
- export { Env } from './src/env.js';
10
- export { EnvParser } from './src/parser.js';
11
- export { EnvLoader } from './src/loader.js';
12
- export * as errors from './src/exceptions.js';
13
- export { EnvProcessor } from './src/processor.js';
1
+ import {
2
+ EnvLoader,
3
+ __export,
4
+ debug_default
5
+ } from "./chunk-H6UKLEIO.js";
6
+
7
+ // src/env.ts
8
+ import { schema as envSchema } from "@poppinss/validator-lite";
9
+
10
+ // src/errors.ts
11
+ var errors_exports = {};
12
+ __export(errors_exports, {
13
+ E_INVALID_ENV_VARIABLES: () => E_INVALID_ENV_VARIABLES
14
+ });
15
+ import { Exception } from "@poppinss/utils";
16
+ var E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
17
+ static message = "Validation failed for one or more environment variables";
18
+ static code = "E_INVALID_ENV_VARIABLES";
19
+ help = "";
20
+ };
21
+
22
+ // src/validator.ts
23
+ var EnvValidator = class {
24
+ #schema;
25
+ #error;
26
+ constructor(schema) {
27
+ this.#schema = schema;
28
+ this.#error = new E_INVALID_ENV_VARIABLES();
29
+ }
30
+ /**
31
+ * Accepts an object of values to validate against the pre-defined
32
+ * schema.
33
+ *
34
+ * The return value is a merged copy of the original object and the
35
+ * values mutated by the schema validator.
36
+ */
37
+ validate(values) {
38
+ const help = [];
39
+ const validated = Object.keys(this.#schema).reduce(
40
+ (result, key) => {
41
+ const value = process.env[key] || values[key];
42
+ try {
43
+ result[key] = this.#schema[key](key, value);
44
+ } catch (error) {
45
+ help.push(`- ${error.message}`);
46
+ }
47
+ return result;
48
+ },
49
+ { ...values }
50
+ );
51
+ if (help.length) {
52
+ this.#error.help = help.join("\n");
53
+ throw this.#error;
54
+ }
55
+ return validated;
56
+ }
57
+ };
58
+
59
+ // src/parser.ts
60
+ import dotenv from "dotenv";
61
+ var EnvParser = class {
62
+ #envContents;
63
+ #preferProcessEnv = true;
64
+ constructor(envContents, options) {
65
+ if (options?.ignoreProcessEnv) {
66
+ this.#preferProcessEnv = false;
67
+ }
68
+ this.#envContents = envContents;
69
+ }
70
+ /**
71
+ * Returns the value from the parsed object
72
+ */
73
+ #getValue(key, parsed) {
74
+ if (this.#preferProcessEnv && process.env[key]) {
75
+ return process.env[key];
76
+ }
77
+ if (parsed[key]) {
78
+ return this.#interpolate(parsed[key], parsed);
79
+ }
80
+ return process.env[key] || "";
81
+ }
82
+ /**
83
+ * Interpolating the token wrapped inside the mustache braces.
84
+ */
85
+ #interpolateMustache(token, parsed) {
86
+ const closingBrace = token.indexOf("}");
87
+ if (closingBrace === -1) {
88
+ return token;
89
+ }
90
+ const varReference = token.slice(1, closingBrace).trim();
91
+ return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`;
92
+ }
93
+ /**
94
+ * Interpolating the variable reference starting with a
95
+ * `$`. We only capture numbers,letter and underscore.
96
+ * For other characters, one can use the mustache
97
+ * braces.
98
+ */
99
+ #interpolateVariable(token, parsed) {
100
+ return token.replace(/[a-zA-Z0-9_]+/, (key) => {
101
+ return this.#getValue(key, parsed);
102
+ });
103
+ }
104
+ /**
105
+ * Interpolates the referenced values
106
+ */
107
+ #interpolate(value, parsed) {
108
+ const tokens = value.split("$");
109
+ let newValue = "";
110
+ let skipNextToken = true;
111
+ tokens.forEach((token) => {
112
+ if (token === "\\") {
113
+ newValue += "$";
114
+ skipNextToken = true;
115
+ return;
116
+ }
117
+ if (skipNextToken) {
118
+ newValue += token.replace(/\\$/, "$");
119
+ if (token.endsWith("\\")) {
120
+ return;
121
+ }
122
+ } else {
123
+ if (token.startsWith("{")) {
124
+ newValue += this.#interpolateMustache(token, parsed);
125
+ return;
126
+ }
127
+ newValue += this.#interpolateVariable(token, parsed);
128
+ }
129
+ skipNextToken = false;
130
+ });
131
+ return newValue;
132
+ }
133
+ /**
134
+ * Parse the env string to an object of environment variables.
135
+ */
136
+ parse() {
137
+ const envCollection = dotenv.parse(this.#envContents.trim());
138
+ return Object.keys(envCollection).reduce((result, key) => {
139
+ result[key] = this.#getValue(key, envCollection);
140
+ return result;
141
+ }, {});
142
+ }
143
+ };
144
+
145
+ // src/processor.ts
146
+ var EnvProcessor = class {
147
+ /**
148
+ * App root is needed to load files
149
+ */
150
+ #appRoot;
151
+ constructor(appRoot) {
152
+ this.#appRoot = appRoot;
153
+ }
154
+ /**
155
+ * Parse env variables from raw contents
156
+ */
157
+ #processContents(envContents, store) {
158
+ if (!envContents.trim()) {
159
+ return store;
160
+ }
161
+ const values = new EnvParser(envContents).parse();
162
+ Object.keys(values).forEach((key) => {
163
+ let value = process.env[key];
164
+ if (!value) {
165
+ value = values[key];
166
+ process.env[key] = values[key];
167
+ }
168
+ if (!store[key]) {
169
+ store[key] = value;
170
+ }
171
+ });
172
+ return store;
173
+ }
174
+ /**
175
+ * Parse env variables by loading dot files.
176
+ */
177
+ async #loadAndProcessDotFiles() {
178
+ const loader = new EnvLoader(this.#appRoot);
179
+ const envFiles = await loader.load();
180
+ if (debug_default.enabled) {
181
+ debug_default(
182
+ "processing .env files (priority from top to bottom) %O",
183
+ envFiles.map((file) => file.path)
184
+ );
185
+ }
186
+ const envValues = {};
187
+ envFiles.forEach(({ contents }) => this.#processContents(contents, envValues));
188
+ return envValues;
189
+ }
190
+ /**
191
+ * Process env variables
192
+ */
193
+ async process() {
194
+ return this.#loadAndProcessDotFiles();
195
+ }
196
+ };
197
+
198
+ // src/env.ts
199
+ var Env = class _Env {
200
+ /**
201
+ * A cache of env values
202
+ */
203
+ #values;
204
+ constructor(values) {
205
+ this.#values = values;
206
+ }
207
+ /**
208
+ * Create an instance of the env class by validating the
209
+ * environment variables. Also, the `.env` files are
210
+ * loaded from the appRoot
211
+ */
212
+ static async create(appRoot, schema) {
213
+ const values = await new EnvProcessor(appRoot).process();
214
+ const validator = this.rules(schema);
215
+ return new _Env(validator.validate(values));
216
+ }
217
+ /**
218
+ * The schema builder for defining validation rules
219
+ */
220
+ static schema = envSchema;
221
+ /**
222
+ * Define the validation rules for validating environment
223
+ * variables. The return value is an instance of the
224
+ * env validator
225
+ */
226
+ static rules(schema) {
227
+ const validator = new EnvValidator(schema);
228
+ return validator;
229
+ }
230
+ get(key, defaultValue) {
231
+ if (this.#values[key] !== void 0) {
232
+ return this.#values[key];
233
+ }
234
+ const envValue = process.env[key];
235
+ if (envValue) {
236
+ return envValue;
237
+ }
238
+ return defaultValue;
239
+ }
240
+ set(key, value) {
241
+ this.#values[key] = value;
242
+ process.env[key] = value;
243
+ }
244
+ };
245
+ export {
246
+ Env,
247
+ EnvLoader,
248
+ EnvParser,
249
+ EnvProcessor,
250
+ errors_exports as errors
251
+ };
252
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/env.ts","../src/errors.ts","../src/validator.ts","../src/parser.ts","../src/processor.ts"],"sourcesContent":["/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { schema as envSchema, type ValidateFn } from '@poppinss/validator-lite'\nimport { EnvValidator } from './validator.js'\nimport { EnvProcessor } from './processor.js'\n\n/**\n * A wrapper over \"process.env\" with types information.\n *\n * ```ts\n * const validate = Env.rules({\n * PORT: Env.schema.number()\n * })\n *\n * const validatedEnvVars = validate(process.env)\n *\n * const env = new EnvValues(validatedEnvVars)\n * env.get('PORT') // type === number\n * ```\n */\nexport class Env<EnvValues extends Record<string, any>> {\n /**\n * A cache of env values\n */\n #values: EnvValues\n\n constructor(values: EnvValues) {\n this.#values = values\n }\n\n /**\n * Create an instance of the env class by validating the\n * environment variables. Also, the `.env` files are\n * loaded from the appRoot\n */\n static async create<Schema extends { [key: string]: ValidateFn<unknown> }>(\n appRoot: URL,\n schema: Schema\n ): Promise<\n Env<{\n [K in keyof Schema]: ReturnType<Schema[K]>\n }>\n > {\n const values = await new EnvProcessor(appRoot).process()\n const validator = this.rules(schema)\n return new Env(validator.validate(values))\n }\n\n /**\n * The schema builder for defining validation rules\n */\n static schema = envSchema\n\n /**\n * Define the validation rules for validating environment\n * variables. The return value is an instance of the\n * env validator\n */\n static rules<T extends { [key: string]: ValidateFn<unknown> }>(schema: T): EnvValidator<T> {\n const validator = new EnvValidator<T>(schema)\n return validator\n }\n\n /**\n * Get the value of an environment variable by key. The values are\n * lookedup inside the validated environment and \"process.env\"\n * is used as a fallback.\n *\n * The second param is the default value, which is returned when\n * the environment variable does not exist.\n *\n * ```ts\n * Env.get('PORT')\n *\n * // With default value\n * Env.get('PORT', 3000)\n * ```\n */\n get<K extends keyof EnvValues>(key: K): EnvValues[K]\n get<K extends keyof EnvValues>(\n key: K,\n defaultValue: Exclude<EnvValues[K], undefined>\n ): Exclude<EnvValues[K], undefined>\n get(key: string): string | undefined\n get(key: string, defaultValue: string): string\n get(key: string, defaultValue?: any): any {\n /**\n * Return cached value\n */\n if (this.#values[key] !== undefined) {\n return this.#values[key]\n }\n\n /**\n * Get value from \"process.env\" and update the cache\n */\n const envValue = process.env[key]\n if (envValue) {\n return envValue\n }\n\n /**\n * Return default value when unable to lookup any other value\n */\n return defaultValue\n }\n\n /**\n * Update/set value of an environment variable.\n *\n * The value is not casted/validated using the validator, so make sure\n * to set the correct data type.\n *\n * ```ts\n * Env.set('PORT', 3000)\n *\n * Env.get('PORT') === 3000 // true\n * process.env.PORT === '3000' // true\n * ```\n */\n set<K extends keyof EnvValues>(key: K, value: EnvValues[K]): void\n set(key: string, value: string): void\n set(key: string | keyof EnvValues, value: any): void {\n this.#values[key] = value\n process.env[key as string] = value\n }\n}\n","/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { Exception } from '@poppinss/utils'\n\n/**\n * Exception raised when one or more env variables\n * are invalid\n */\nexport const E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {\n static message = 'Validation failed for one or more environment variables'\n static code = 'E_INVALID_ENV_VARIABLES'\n help: string = ''\n}\n","/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport type { Exception } from '@poppinss/utils'\nimport { ValidateFn } from '@poppinss/validator-lite'\n\nimport { E_INVALID_ENV_VARIABLES } from './errors.js'\n\n/**\n * Exposes the API to validate environment variables against a\n * pre-defined schema.\n *\n * The class is not exported in the main API and used internally.\n */\nexport class EnvValidator<Schema extends { [key: string]: ValidateFn<unknown> }> {\n #schema: Schema\n #error: Exception\n\n constructor(schema: Schema) {\n this.#schema = schema\n this.#error = new E_INVALID_ENV_VARIABLES()\n }\n\n /**\n * Accepts an object of values to validate against the pre-defined\n * schema.\n *\n * The return value is a merged copy of the original object and the\n * values mutated by the schema validator.\n */\n validate(values: { [K: string]: string | undefined }): {\n [K in keyof Schema]: ReturnType<Schema[K]>\n } {\n const help: string[] = []\n\n const validated = Object.keys(this.#schema).reduce(\n (result, key) => {\n const value = process.env[key] || values[key]\n\n try {\n result[key] = this.#schema[key](key, value) as any\n } catch (error) {\n help.push(`- ${error.message}`)\n }\n return result\n },\n { ...values }\n ) as { [K in keyof Schema]: ReturnType<Schema[K]> }\n\n if (help.length) {\n this.#error.help = help.join('\\n')\n throw this.#error\n }\n\n return validated\n }\n}\n","/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport dotenv, { DotenvParseOutput } from 'dotenv'\n\n/**\n * Env parser parses the environment variables from a string formatted\n * as a key-value pair seperated using an `=`. For example:\n *\n * ```dotenv\n * PORT=3333\n * HOST=127.0.0.1\n * ```\n *\n * The variables can reference other environment variables as well using `$`.\n * For example:\n *\n * ```dotenv\n * PORT=3333\n * REDIS_PORT=$PORT\n * ```\n *\n * The variables using characters other than letters can wrap variable\n * named inside a curly brace.\n *\n * ```dotenv\n * APP-PORT=3333\n * REDIS_PORT=${APP-PORT}\n * ```\n *\n * You can escape the `$` sign with a backtick.\n *\n * ```dotenv\n * REDIS_PASSWORD=foo\\$123\n * ```\n *\n * ## Usage\n *\n * ```ts\n * const parser = new EnvParser(envContents)\n * const output = parser.parse()\n *\n * // The output is a key-value pair\n * ```\n */\nexport class EnvParser {\n #envContents: string\n #preferProcessEnv: boolean = true\n\n constructor(envContents: string, options?: { ignoreProcessEnv: boolean }) {\n if (options?.ignoreProcessEnv) {\n this.#preferProcessEnv = false\n }\n\n this.#envContents = envContents\n }\n\n /**\n * Returns the value from the parsed object\n */\n #getValue(key: string, parsed: DotenvParseOutput): string {\n if (this.#preferProcessEnv && process.env[key]) {\n return process.env[key]!\n }\n\n if (parsed[key]) {\n return this.#interpolate(parsed[key], parsed)\n }\n\n return process.env[key] || ''\n }\n\n /**\n * Interpolating the token wrapped inside the mustache braces.\n */\n #interpolateMustache(token: string, parsed: DotenvParseOutput) {\n /**\n * Finding the closing brace. If closing brace is missing, we\n * consider the block as a normal string\n */\n const closingBrace = token.indexOf('}')\n if (closingBrace === -1) {\n return token\n }\n\n /**\n * Then we pull everything until the closing brace, except\n * the opening brace and trim off all white spaces.\n */\n const varReference = token.slice(1, closingBrace).trim()\n\n /**\n * Getting the value of the reference inside the braces\n */\n return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`\n }\n\n /**\n * Interpolating the variable reference starting with a\n * `$`. We only capture numbers,letter and underscore.\n * For other characters, one can use the mustache\n * braces.\n */\n #interpolateVariable(token: string, parsed: any) {\n return token.replace(/[a-zA-Z0-9_]+/, (key) => {\n return this.#getValue(key, parsed)\n })\n }\n\n /**\n * Interpolates the referenced values\n */\n #interpolate(value: string, parsed: DotenvParseOutput): string {\n const tokens = value.split('$')\n\n let newValue = ''\n let skipNextToken = true\n\n tokens.forEach((token) => {\n /**\n * If the value is an escaped sequence, then we replace it\n * with a `$` and then skip the next token.\n */\n if (token === '\\\\') {\n newValue += '$'\n skipNextToken = true\n return\n }\n\n /**\n * Use the value as it is when \"skipNextToken\" is set to true.\n */\n if (skipNextToken) {\n /**\n * Replace the ending escape sequence with a $\n */\n newValue += token.replace(/\\\\$/, '$')\n /**\n * and then skip the next token if it ends with escape sequence\n */\n if (token.endsWith('\\\\')) {\n return\n }\n } else {\n /**\n * Handle mustache block\n */\n if (token.startsWith('{')) {\n newValue += this.#interpolateMustache(token, parsed)\n return\n }\n\n /**\n * Process all words as variable\n */\n newValue += this.#interpolateVariable(token, parsed)\n }\n\n /**\n * Process next token\n */\n skipNextToken = false\n })\n\n return newValue\n }\n\n /**\n * Parse the env string to an object of environment variables.\n */\n parse(): DotenvParseOutput {\n const envCollection = dotenv.parse(this.#envContents.trim())\n\n return Object.keys(envCollection).reduce<DotenvParseOutput>((result, key) => {\n result[key] = this.#getValue(key, envCollection)\n return result\n }, {})\n }\n}\n","/*\n * @adonisjs/application\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport debug from './debug.js'\nimport { EnvParser } from './parser.js'\nimport { EnvLoader } from './loader.js'\n\n/**\n * Env processors loads, parses and process environment variables.\n */\nexport class EnvProcessor {\n /**\n * App root is needed to load files\n */\n #appRoot: URL\n\n constructor(appRoot: URL) {\n this.#appRoot = appRoot\n }\n\n /**\n * Parse env variables from raw contents\n */\n #processContents(envContents: string, store: Record<string, any>) {\n /**\n * Collected env variables\n */\n if (!envContents.trim()) {\n return store\n }\n\n const values = new EnvParser(envContents).parse()\n Object.keys(values).forEach((key) => {\n let value = process.env[key]\n\n if (!value) {\n value = values[key]\n process.env[key] = values[key]\n }\n\n if (!store[key]) {\n store[key] = value\n }\n })\n\n return store\n }\n\n /**\n * Parse env variables by loading dot files.\n */\n async #loadAndProcessDotFiles() {\n const loader = new EnvLoader(this.#appRoot)\n const envFiles = await loader.load()\n\n if (debug.enabled) {\n debug(\n 'processing .env files (priority from top to bottom) %O',\n envFiles.map((file) => file.path)\n )\n }\n\n /**\n * Collected env variables\n */\n const envValues: Record<string, any> = {}\n envFiles.forEach(({ contents }) => this.#processContents(contents, envValues))\n return envValues\n }\n\n /**\n * Process env variables\n */\n async process() {\n return this.#loadAndProcessDotFiles()\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,67 +1,68 @@
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
- */
9
- import splitLines from 'split-lines';
10
- import lodash from '@poppinss/utils/lodash';
11
- import { writeFile } from 'node:fs/promises';
12
- import { EnvLoader } from './loader.js';
13
- export class EnvEditor {
14
- #appRoot;
15
- #loader;
16
- #files = [];
17
- /**
18
- * Creates an instance of env editor and loads .env files
19
- * contents.
20
- */
21
- static async create(appRoot) {
22
- const editor = new EnvEditor(appRoot);
23
- await editor.load();
24
- return editor;
25
- }
26
- constructor(appRoot) {
27
- this.#appRoot = appRoot;
28
- this.#loader = new EnvLoader(this.#appRoot, true);
29
- }
30
- /**
31
- * Loads .env files for editing. Only ".env" and ".env.example"
32
- * files are picked for editing.
33
- */
34
- async load() {
35
- const envFiles = await this.#loader.load();
36
- this.#files = envFiles
37
- .filter((envFile) => envFile.fileExists &&
38
- (envFile.path.endsWith('.env') || envFile.path.endsWith('.env.example')))
39
- .map((envFile) => {
40
- return {
41
- contents: splitLines(envFile.contents.trim()),
42
- path: envFile.path,
43
- };
44
- });
45
- }
46
- /**
47
- * Add key-value pair to the dot-env files.
48
- */
49
- add(key, value) {
50
- this.#files.forEach((file) => {
51
- let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
52
- entryIndex = entryIndex === -1 ? file.contents.length : entryIndex;
53
- lodash.set(file.contents, entryIndex, `${key}=${String(value)}`);
54
- });
55
- }
56
- toJSON() {
57
- return this.#files;
58
- }
59
- /**
60
- * Save changes to the disk
61
- */
62
- async save() {
63
- await Promise.all(this.#files.map((file) => {
64
- return writeFile(file.path, file.contents.join('\n'));
65
- }));
66
- }
67
- }
1
+ import {
2
+ EnvLoader
3
+ } from "../chunk-H6UKLEIO.js";
4
+
5
+ // src/editor.ts
6
+ import splitLines from "split-lines";
7
+ import lodash from "@poppinss/utils/lodash";
8
+ import { writeFile } from "node:fs/promises";
9
+ var EnvEditor = class _EnvEditor {
10
+ #appRoot;
11
+ #loader;
12
+ #files = [];
13
+ /**
14
+ * Creates an instance of env editor and loads .env files
15
+ * contents.
16
+ */
17
+ static async create(appRoot) {
18
+ const editor = new _EnvEditor(appRoot);
19
+ await editor.load();
20
+ return editor;
21
+ }
22
+ constructor(appRoot) {
23
+ this.#appRoot = appRoot;
24
+ this.#loader = new EnvLoader(this.#appRoot, true);
25
+ }
26
+ /**
27
+ * Loads .env files for editing. Only ".env" and ".env.example"
28
+ * files are picked for editing.
29
+ */
30
+ async load() {
31
+ const envFiles = await this.#loader.load();
32
+ this.#files = envFiles.filter(
33
+ (envFile) => envFile.fileExists && (envFile.path.endsWith(".env") || envFile.path.endsWith(".env.example"))
34
+ ).map((envFile) => {
35
+ return {
36
+ contents: splitLines(envFile.contents.trim()),
37
+ path: envFile.path
38
+ };
39
+ });
40
+ }
41
+ /**
42
+ * Add key-value pair to the dot-env files.
43
+ */
44
+ add(key, value) {
45
+ this.#files.forEach((file) => {
46
+ let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
47
+ entryIndex = entryIndex === -1 ? file.contents.length : entryIndex;
48
+ lodash.set(file.contents, entryIndex, `${key}=${String(value)}`);
49
+ });
50
+ }
51
+ toJSON() {
52
+ return this.#files;
53
+ }
54
+ /**
55
+ * Save changes to the disk
56
+ */
57
+ async save() {
58
+ await Promise.all(
59
+ this.#files.map((file) => {
60
+ return writeFile(file.path, file.contents.join("\n"));
61
+ })
62
+ );
63
+ }
64
+ };
65
+ export {
66
+ EnvEditor
67
+ };
68
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/editor.ts"],"sourcesContent":["/*\n * @adonisjs/env\n *\n * (c) AdonisJS\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport splitLines from 'split-lines'\nimport lodash from '@poppinss/utils/lodash'\nimport { writeFile } from 'node:fs/promises'\n\nimport { EnvLoader } from './loader.js'\n\nexport class EnvEditor {\n #appRoot: URL\n #loader: EnvLoader\n #files: { contents: string[]; path: string }[] = []\n\n /**\n * Creates an instance of env editor and loads .env files\n * contents.\n */\n static async create(appRoot: URL) {\n const editor = new EnvEditor(appRoot)\n await editor.load()\n\n return editor\n }\n\n constructor(appRoot: URL) {\n this.#appRoot = appRoot\n this.#loader = new EnvLoader(this.#appRoot, true)\n }\n\n /**\n * Loads .env files for editing. Only \".env\" and \".env.example\"\n * files are picked for editing.\n */\n async load() {\n const envFiles = await this.#loader.load()\n\n this.#files = envFiles\n .filter(\n (envFile) =>\n envFile.fileExists &&\n (envFile.path.endsWith('.env') || envFile.path.endsWith('.env.example'))\n )\n .map((envFile) => {\n return {\n contents: splitLines(envFile.contents.trim()),\n path: envFile.path,\n }\n })\n }\n\n /**\n * Add key-value pair to the dot-env files.\n */\n add(key: string, value: string | number | boolean) {\n this.#files.forEach((file) => {\n let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`))\n\n entryIndex = entryIndex === -1 ? file.contents.length : entryIndex\n lodash.set(file.contents, entryIndex, `${key}=${String(value)}`)\n })\n }\n\n toJSON() {\n return this.#files\n }\n\n /**\n * Save changes to the disk\n */\n async save() {\n await Promise.all(\n this.#files.map((file) => {\n return writeFile(file.path, file.contents.join('\\n'))\n })\n )\n }\n}\n"],"mappings":";;;;;AASA,OAAO,gBAAgB;AACvB,OAAO,YAAY;AACnB,SAAS,iBAAiB;AAInB,IAAM,YAAN,MAAM,WAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA,SAAiD,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlD,aAAa,OAAO,SAAc;AAChC,UAAM,SAAS,IAAI,WAAU,OAAO;AACpC,UAAM,OAAO,KAAK;AAElB,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,SAAc;AACxB,SAAK,WAAW;AAChB,SAAK,UAAU,IAAI,UAAU,KAAK,UAAU,IAAI;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO;AACX,UAAM,WAAW,MAAM,KAAK,QAAQ,KAAK;AAEzC,SAAK,SAAS,SACX;AAAA,MACC,CAAC,YACC,QAAQ,eACP,QAAQ,KAAK,SAAS,MAAM,KAAK,QAAQ,KAAK,SAAS,cAAc;AAAA,IAC1E,EACC,IAAI,CAAC,YAAY;AAChB,aAAO;AAAA,QACL,UAAU,WAAW,QAAQ,SAAS,KAAK,CAAC;AAAA,QAC5C,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa,OAAkC;AACjD,SAAK,OAAO,QAAQ,CAAC,SAAS;AAC5B,UAAI,aAAa,KAAK,SAAS,UAAU,CAAC,SAAS,KAAK,WAAW,GAAG,GAAG,GAAG,CAAC;AAE7E,mBAAa,eAAe,KAAK,KAAK,SAAS,SAAS;AACxD,aAAO,IAAI,KAAK,UAAU,YAAY,GAAG,GAAG,IAAI,OAAO,KAAK,CAAC,EAAE;AAAA,IACjE,CAAC;AAAA,EACH;AAAA,EAEA,SAAS;AACP,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO;AACX,UAAM,QAAQ;AAAA,MACZ,KAAK,OAAO,IAAI,CAAC,SAAS;AACxB,eAAO,UAAU,KAAK,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@adonisjs/env",
3
- "version": "4.2.0-5",
3
+ "version": "4.2.0-7",
4
4
  "description": "Environment variable manager for Node.js",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
7
7
  "files": [
8
- "build/src",
9
- "build/index.d.ts",
10
- "build/index.js"
8
+ "build",
9
+ "!build/bin",
10
+ "!build/examples",
11
+ "!build/tests"
11
12
  ],
12
13
  "exports": {
13
14
  ".": "./build/index.js",
@@ -21,7 +22,8 @@
21
22
  "test": "cross-env NODE_DEBUG=adonisjs:env c8 npm run quick:test",
22
23
  "clean": "del-cli build",
23
24
  "typecheck": "tsc --noEmit",
24
- "compile": "npm run lint && npm run clean && tsc",
25
+ "precompile": "npm run lint && npm run clean",
26
+ "compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
25
27
  "build": "npm run compile",
26
28
  "release": "np",
27
29
  "version": "npm run build",
@@ -38,30 +40,31 @@
38
40
  "author": "virk,adonisjs",
39
41
  "license": "MIT",
40
42
  "devDependencies": {
41
- "@adonisjs/eslint-config": "^1.1.8",
42
- "@adonisjs/prettier-config": "^1.1.8",
43
- "@adonisjs/tsconfig": "^1.1.8",
44
- "@commitlint/cli": "^17.7.1",
45
- "@commitlint/config-conventional": "^17.7.0",
46
- "@japa/assert": "^2.0.0-1",
47
- "@japa/expect-type": "^2.0.0-0",
48
- "@japa/file-system": "^2.0.0-1",
49
- "@japa/runner": "^3.0.0-3",
50
- "@swc/core": "^1.3.78",
51
- "@types/node": "^20.5.3",
43
+ "@adonisjs/eslint-config": "^1.1.9",
44
+ "@adonisjs/prettier-config": "^1.1.9",
45
+ "@adonisjs/tsconfig": "^1.1.9",
46
+ "@commitlint/cli": "^18.4.3",
47
+ "@commitlint/config-conventional": "^18.4.3",
48
+ "@japa/assert": "^2.0.1",
49
+ "@japa/expect-type": "^2.0.0",
50
+ "@japa/file-system": "^2.0.1",
51
+ "@japa/runner": "^3.1.0",
52
+ "@swc/core": "^1.3.99",
53
+ "@types/node": "^20.9.4",
52
54
  "c8": "^8.0.1",
53
55
  "cross-env": "^7.0.3",
54
- "del-cli": "^5.0.0",
55
- "eslint": "^8.47.0",
56
+ "del-cli": "^5.1.0",
57
+ "eslint": "^8.54.0",
56
58
  "github-label-sync": "^2.3.1",
57
59
  "husky": "^8.0.3",
58
60
  "np": "^8.0.4",
59
- "prettier": "^3.0.2",
61
+ "prettier": "^3.1.0",
60
62
  "ts-node": "^10.9.1",
61
- "typescript": "^5.1.6"
63
+ "tsup": "^8.0.1",
64
+ "typescript": "5.2.2"
62
65
  },
63
66
  "dependencies": {
64
- "@poppinss/utils": "^6.5.0-5",
67
+ "@poppinss/utils": "^6.5.1",
65
68
  "@poppinss/validator-lite": "^1.0.3",
66
69
  "dotenv": "^16.3.1",
67
70
  "split-lines": "^3.0.0"
@@ -101,5 +104,17 @@
101
104
  "eslintConfig": {
102
105
  "extends": "@adonisjs/eslint-config/package"
103
106
  },
104
- "prettier": "@adonisjs/prettier-config"
107
+ "prettier": "@adonisjs/prettier-config",
108
+ "tsup": {
109
+ "entry": [
110
+ "./index.ts",
111
+ "./src/editor.ts"
112
+ ],
113
+ "outDir": "./build",
114
+ "clean": true,
115
+ "format": "esm",
116
+ "dts": false,
117
+ "sourcemap": true,
118
+ "target": "esnext"
119
+ }
105
120
  }
@@ -1,10 +0,0 @@
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
- */
9
- import { debuglog } from 'node:util';
10
- export default debuglog('adonisjs:env');
package/build/src/env.js DELETED
@@ -1,80 +0,0 @@
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
- */
9
- import { schema as envSchema } from '@poppinss/validator-lite';
10
- import { EnvValidator } from './validator.js';
11
- import { EnvProcessor } from './processor.js';
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
- */
30
- #values;
31
- constructor(values) {
32
- this.#values = values;
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
- */
39
- static async create(appRoot, schema) {
40
- const values = await new EnvProcessor(appRoot).process();
41
- const validator = this.rules(schema);
42
- return new Env(validator.validate(values));
43
- }
44
- /**
45
- * The schema builder for defining validation rules
46
- */
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
- */
53
- static rules(schema) {
54
- const validator = new EnvValidator(schema);
55
- return validator;
56
- }
57
- get(key, defaultValue) {
58
- /**
59
- * Return cached value
60
- */
61
- if (this.#values[key] !== undefined) {
62
- return this.#values[key];
63
- }
64
- /**
65
- * Get value from "process.env" and update the cache
66
- */
67
- const envValue = process.env[key];
68
- if (envValue) {
69
- return envValue;
70
- }
71
- /**
72
- * Return default value when unable to lookup any other value
73
- */
74
- return defaultValue;
75
- }
76
- set(key, value) {
77
- this.#values[key] = value;
78
- process.env[key] = value;
79
- }
80
- }
@@ -1,18 +0,0 @@
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
- */
9
- import { Exception } from '@poppinss/utils';
10
- /**
11
- * Exception raised when one or more env variables
12
- * are invalid
13
- */
14
- export const E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
15
- static message = 'Validation failed for one or more environment variables';
16
- static code = 'E_INVALID_ENV_VARIABLES';
17
- help = '';
18
- };
@@ -1,134 +0,0 @@
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
- */
9
- import { fileURLToPath } from 'node:url';
10
- import { readFile } from 'node:fs/promises';
11
- import { isAbsolute, join } from 'node:path';
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
- */
35
- export class EnvLoader {
36
- #appRoot;
37
- #loadExampleFile;
38
- constructor(appRoot, loadExampleFile = false) {
39
- this.#appRoot = typeof appRoot === 'string' ? appRoot : fileURLToPath(appRoot);
40
- this.#loadExampleFile = loadExampleFile;
41
- }
42
- /**
43
- * Optionally read a file from the disk
44
- */
45
- async #loadFile(filePath) {
46
- try {
47
- const contents = await readFile(filePath, 'utf-8');
48
- return { contents, fileExists: true };
49
- }
50
- catch (error) {
51
- /* c8 ignore next 3 */
52
- if (error.code !== 'ENOENT') {
53
- throw error;
54
- }
55
- return { contents: '', fileExists: false };
56
- }
57
- }
58
- /**
59
- * Load contents of the main dot-env file and the current
60
- * environment dot-env file
61
- */
62
- async load() {
63
- const ENV_PATH = process.env.ENV_PATH;
64
- const NODE_ENV = process.env.NODE_ENV;
65
- const envFiles = [];
66
- if (debug.enabled) {
67
- debug('ENV_PATH variable is %s', ENV_PATH ? 'set' : 'not set');
68
- debug('NODE_ENV variable is %s', NODE_ENV ? 'set' : 'not set');
69
- }
70
- /**
71
- * Base path to load .env files from
72
- */
73
- const baseEnvPath = ENV_PATH
74
- ? isAbsolute(ENV_PATH)
75
- ? ENV_PATH
76
- : join(this.#appRoot, ENV_PATH)
77
- : this.#appRoot;
78
- if (debug.enabled) {
79
- debug('dot-env files base path "%s"', baseEnvPath);
80
- }
81
- /**
82
- * 1st
83
- * The top most priority is given to the ".env.[NODE_ENV].local" file
84
- */
85
- if (NODE_ENV) {
86
- const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
87
- envFiles.push({
88
- path: nodeEnvLocalFile,
89
- ...(await this.#loadFile(nodeEnvLocalFile)),
90
- });
91
- }
92
- /**
93
- * 2nd
94
- * Next, we give priority to the ".env.local" file
95
- */
96
- if (!NODE_ENV || !['test', 'testing'].includes(NODE_ENV)) {
97
- const envLocalFile = join(baseEnvPath, '.env.local');
98
- envFiles.push({
99
- path: envLocalFile,
100
- ...(await this.#loadFile(envLocalFile)),
101
- });
102
- }
103
- /**
104
- * 3rd
105
- * Next, we give priority to the ".env.[NODE_ENV]" file
106
- */
107
- if (NODE_ENV) {
108
- const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
109
- envFiles.push({
110
- path: nodeEnvFile,
111
- ...(await this.#loadFile(nodeEnvFile)),
112
- });
113
- }
114
- /**
115
- * Finally, we push the contents of the ".env" file.
116
- */
117
- const envFile = join(baseEnvPath, '.env');
118
- envFiles.push({
119
- path: envFile,
120
- ...(await this.#loadFile(envFile)),
121
- });
122
- /**
123
- * Load example file
124
- */
125
- if (this.#loadExampleFile) {
126
- const envExampleFile = join(baseEnvPath, '.env.example');
127
- envFiles.push({
128
- path: envExampleFile,
129
- ...(await this.#loadFile(envExampleFile)),
130
- });
131
- }
132
- return envFiles;
133
- }
134
- }
@@ -1,166 +0,0 @@
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
- */
9
- import dotenv from 'dotenv';
10
- /**
11
- * Env parser parses the environment variables from a string formatted
12
- * as a key-value pair seperated using an `=`. For example:
13
- *
14
- * ```dotenv
15
- * PORT=3333
16
- * HOST=127.0.0.1
17
- * ```
18
- *
19
- * The variables can reference other environment variables as well using `$`.
20
- * For example:
21
- *
22
- * ```dotenv
23
- * PORT=3333
24
- * REDIS_PORT=$PORT
25
- * ```
26
- *
27
- * The variables using characters other than letters can wrap variable
28
- * named inside a curly brace.
29
- *
30
- * ```dotenv
31
- * APP-PORT=3333
32
- * REDIS_PORT=${APP-PORT}
33
- * ```
34
- *
35
- * You can escape the `$` sign with a backtick.
36
- *
37
- * ```dotenv
38
- * REDIS_PASSWORD=foo\$123
39
- * ```
40
- *
41
- * ## Usage
42
- *
43
- * ```ts
44
- * const parser = new EnvParser(envContents)
45
- * const output = parser.parse()
46
- *
47
- * // The output is a key-value pair
48
- * ```
49
- */
50
- export class EnvParser {
51
- #envContents;
52
- #preferProcessEnv = true;
53
- constructor(envContents, options) {
54
- if (options?.ignoreProcessEnv) {
55
- this.#preferProcessEnv = false;
56
- }
57
- this.#envContents = envContents;
58
- }
59
- /**
60
- * Returns the value from the parsed object
61
- */
62
- #getValue(key, parsed) {
63
- if (this.#preferProcessEnv && process.env[key]) {
64
- return process.env[key];
65
- }
66
- if (parsed[key]) {
67
- return this.#interpolate(parsed[key], parsed);
68
- }
69
- return process.env[key] || '';
70
- }
71
- /**
72
- * Interpolating the token wrapped inside the mustache braces.
73
- */
74
- #interpolateMustache(token, parsed) {
75
- /**
76
- * Finding the closing brace. If closing brace is missing, we
77
- * consider the block as a normal string
78
- */
79
- const closingBrace = token.indexOf('}');
80
- if (closingBrace === -1) {
81
- return token;
82
- }
83
- /**
84
- * Then we pull everything until the closing brace, except
85
- * the opening brace and trim off all white spaces.
86
- */
87
- const varReference = token.slice(1, closingBrace).trim();
88
- /**
89
- * Getting the value of the reference inside the braces
90
- */
91
- return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`;
92
- }
93
- /**
94
- * Interpolating the variable reference starting with a
95
- * `$`. We only capture numbers,letter and underscore.
96
- * For other characters, one can use the mustache
97
- * braces.
98
- */
99
- #interpolateVariable(token, parsed) {
100
- return token.replace(/[a-zA-Z0-9_]+/, (key) => {
101
- return this.#getValue(key, parsed);
102
- });
103
- }
104
- /**
105
- * Interpolates the referenced values
106
- */
107
- #interpolate(value, parsed) {
108
- const tokens = value.split('$');
109
- let newValue = '';
110
- let skipNextToken = true;
111
- tokens.forEach((token) => {
112
- /**
113
- * If the value is an escaped sequence, then we replace it
114
- * with a `$` and then skip the next token.
115
- */
116
- if (token === '\\') {
117
- newValue += '$';
118
- skipNextToken = true;
119
- return;
120
- }
121
- /**
122
- * Use the value as it is when "skipNextToken" is set to true.
123
- */
124
- if (skipNextToken) {
125
- /**
126
- * Replace the ending escape sequence with a $
127
- */
128
- newValue += token.replace(/\\$/, '$');
129
- /**
130
- * and then skip the next token if it ends with escape sequence
131
- */
132
- if (token.endsWith('\\')) {
133
- return;
134
- }
135
- }
136
- else {
137
- /**
138
- * Handle mustache block
139
- */
140
- if (token.startsWith('{')) {
141
- newValue += this.#interpolateMustache(token, parsed);
142
- return;
143
- }
144
- /**
145
- * Process all words as variable
146
- */
147
- newValue += this.#interpolateVariable(token, parsed);
148
- }
149
- /**
150
- * Process next token
151
- */
152
- skipNextToken = false;
153
- });
154
- return newValue;
155
- }
156
- /**
157
- * Parse the env string to an object of environment variables.
158
- */
159
- parse() {
160
- const envCollection = dotenv.parse(this.#envContents.trim());
161
- return Object.keys(envCollection).reduce((result, key) => {
162
- result[key] = this.#getValue(key, envCollection);
163
- return result;
164
- }, {});
165
- }
166
- }
@@ -1,68 +0,0 @@
1
- /*
2
- * @adonisjs/application
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
- */
9
- import debug from './debug.js';
10
- import { EnvParser } from './parser.js';
11
- import { EnvLoader } from './loader.js';
12
- /**
13
- * Env processors loads, parses and process environment variables.
14
- */
15
- export class EnvProcessor {
16
- /**
17
- * App root is needed to load files
18
- */
19
- #appRoot;
20
- constructor(appRoot) {
21
- this.#appRoot = appRoot;
22
- }
23
- /**
24
- * Parse env variables from raw contents
25
- */
26
- #processContents(envContents, store) {
27
- /**
28
- * Collected env variables
29
- */
30
- if (!envContents.trim()) {
31
- return store;
32
- }
33
- const values = new EnvParser(envContents).parse();
34
- Object.keys(values).forEach((key) => {
35
- let value = process.env[key];
36
- if (!value) {
37
- value = values[key];
38
- process.env[key] = values[key];
39
- }
40
- if (!store[key]) {
41
- store[key] = value;
42
- }
43
- });
44
- return store;
45
- }
46
- /**
47
- * Parse env variables by loading dot files.
48
- */
49
- async #loadAndProcessDotFiles() {
50
- const loader = new EnvLoader(this.#appRoot);
51
- const envFiles = await loader.load();
52
- if (debug.enabled) {
53
- debug('processing .env files (priority from top to bottom) %O', envFiles.map((file) => file.path));
54
- }
55
- /**
56
- * Collected env variables
57
- */
58
- const envValues = {};
59
- envFiles.forEach(({ contents }) => this.#processContents(contents, envValues));
60
- return envValues;
61
- }
62
- /**
63
- * Process env variables
64
- */
65
- async process() {
66
- return this.#loadAndProcessDotFiles();
67
- }
68
- }
@@ -1,48 +0,0 @@
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
- */
9
- import { E_INVALID_ENV_VARIABLES } from './exceptions.js';
10
- /**
11
- * Exposes the API to validate environment variables against a
12
- * pre-defined schema.
13
- *
14
- * The class is not exported in the main API and used internally.
15
- */
16
- export class EnvValidator {
17
- #schema;
18
- #error;
19
- constructor(schema) {
20
- this.#schema = schema;
21
- this.#error = new E_INVALID_ENV_VARIABLES();
22
- }
23
- /**
24
- * Accepts an object of values to validate against the pre-defined
25
- * schema.
26
- *
27
- * The return value is a merged copy of the original object and the
28
- * values mutated by the schema validator.
29
- */
30
- validate(values) {
31
- const help = [];
32
- const validated = Object.keys(this.#schema).reduce((result, key) => {
33
- const value = process.env[key] || values[key];
34
- try {
35
- result[key] = this.#schema[key](key, value);
36
- }
37
- catch (error) {
38
- help.push(`- ${error.message}`);
39
- }
40
- return result;
41
- }, { ...values });
42
- if (help.length) {
43
- this.#error.help = help.join('\n');
44
- throw this.#error;
45
- }
46
- return validated;
47
- }
48
- }
File without changes