@adonisjs/env 7.0.0-next.1 → 7.0.0-next.3

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/build/index.js CHANGED
@@ -1,471 +1,234 @@
1
- import {
2
- EnvLoader,
3
- __export,
4
- debug_default
5
- } from "./chunk-KE5AFOK2.js";
6
-
7
- // src/env.ts
8
- import { schema as envSchema } from "@poppinss/validator-lite";
9
-
10
- // src/parser.ts
11
- import dotenv from "dotenv";
12
-
13
- // src/errors.ts
14
- var errors_exports = {};
15
- __export(errors_exports, {
16
- E_IDENTIFIER_ALREADY_DEFINED: () => E_IDENTIFIER_ALREADY_DEFINED,
17
- E_INVALID_ENV_VARIABLES: () => E_INVALID_ENV_VARIABLES
1
+ import { n as debug_default, t as EnvLoader } from "./loader-KsjAiZ3e.js";
2
+ import "node:module";
3
+ import { parseEnv } from "node:util";
4
+ import { readFile } from "node:fs/promises";
5
+ import { Exception, RuntimeException, createError } from "@poppinss/utils/exception";
6
+ import { Secret } from "@poppinss/utils";
7
+ import { schema } from "@poppinss/validator-lite";
8
+ var __defProp = Object.defineProperty;
9
+ var __export = (all, symbols) => {
10
+ let target = {};
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ if (symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return target;
17
+ };
18
+ var errors_exports = /* @__PURE__ */ __export({
19
+ E_IDENTIFIER_ALREADY_DEFINED: () => E_IDENTIFIER_ALREADY_DEFINED,
20
+ E_INVALID_ENV_VARIABLES: () => E_INVALID_ENV_VARIABLES
18
21
  });
19
- import { createError, Exception } from "@poppinss/utils/exception";
20
- var E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
21
- static message = "Validation failed for one or more environment variables";
22
- static code = "E_INVALID_ENV_VARIABLES";
23
- help = "";
22
+ const E_INVALID_ENV_VARIABLES = class EnvValidationException extends Exception {
23
+ static message = "Validation failed for one or more environment variables";
24
+ static code = "E_INVALID_ENV_VARIABLES";
25
+ help = "";
24
26
  };
25
- var E_IDENTIFIER_ALREADY_DEFINED = createError(
26
- 'The identifier "%s" is already defined',
27
- "E_IDENTIFIER_ALREADY_DEFINED",
28
- 500
29
- );
30
-
31
- // src/parser.ts
32
- import { readFile } from "fs/promises";
33
- import { RuntimeException } from "@poppinss/utils/exception";
34
- var EnvParser = class _EnvParser {
35
- /**
36
- * Raw environment file contents
37
- */
38
- #envContents;
39
- /**
40
- * Application root directory URL
41
- */
42
- #appRoot;
43
- /**
44
- * Whether to prefer process.env values over parsed values
45
- */
46
- #preferProcessEnv = true;
47
- /**
48
- * Static collection of registered identifiers with their callbacks
49
- */
50
- static #identifiers = {
51
- async file(value, key, appRoot) {
52
- const filePath = new URL(value, appRoot);
53
- try {
54
- const contents = await readFile(filePath, "utf-8");
55
- return contents;
56
- } catch (error) {
57
- if (error.code === "ENOENT") {
58
- throw new RuntimeException(
59
- `Cannot process "${key}" env variable. Unable to locate file "${filePath}"`,
60
- {
61
- cause: error
62
- }
63
- );
64
- }
65
- throw error;
66
- }
67
- }
68
- };
69
- /**
70
- * Creates a new EnvParser instance
71
- *
72
- * @param envContents - Raw environment file contents
73
- * @param appRoot - Application root directory URL
74
- * @param options - Parser options
75
- */
76
- constructor(envContents, appRoot, options) {
77
- if (options?.ignoreProcessEnv) {
78
- this.#preferProcessEnv = false;
79
- }
80
- this.#envContents = envContents;
81
- this.#appRoot = appRoot;
82
- }
83
- /**
84
- * Define an identifier for any environment value. The callback is invoked
85
- * when the value match the identifier to modify its interpolation.
86
- *
87
- * @deprecated use `EnvParser.defineIdentifier` instead
88
- */
89
- /**
90
- * Define an identifier for any environment value. The callback is invoked
91
- * when the value match the identifier to modify its interpolation.
92
- *
93
- * @deprecated use `EnvParser.defineIdentifier` instead
94
- * @param name - The identifier name
95
- * @param callback - Callback function to process the identifier value
96
- */
97
- static identifier(name, callback) {
98
- _EnvParser.defineIdentifier(name, callback);
99
- }
100
- /**
101
- * Define an identifier for any environment value. The callback is invoked
102
- * when the value match the identifier to modify its interpolation.
103
- *
104
- * @param name - The identifier name
105
- * @param callback - Callback function to process the identifier value
106
- */
107
- static defineIdentifier(name, callback) {
108
- if (this.#identifiers[name]) {
109
- throw new E_IDENTIFIER_ALREADY_DEFINED([name]);
110
- }
111
- this.#identifiers[name] = callback;
112
- }
113
- /**
114
- * Define an identifier for any environment value, if it's not already defined.
115
- * The callback is invoked when the value match the identifier to modify its
116
- * interpolation.
117
- *
118
- * @param name - The identifier name
119
- * @param callback - Callback function to process the identifier value
120
- */
121
- static defineIdentifierIfMissing(name, callback) {
122
- if (typeof this.#identifiers[name] === "undefined") {
123
- this.#identifiers[name] = callback;
124
- }
125
- }
126
- /**
127
- * Remove an identifier
128
- *
129
- * @param name - The identifier name to remove
130
- */
131
- static removeIdentifier(name) {
132
- delete this.#identifiers[name];
133
- }
134
- /**
135
- * Returns the value from the parsed object
136
- *
137
- * @param key - The environment variable key
138
- * @param parsed - Parsed environment variables object
139
- * @returns The resolved environment variable value
140
- */
141
- #getValue(key, parsed) {
142
- if (this.#preferProcessEnv && process.env[key]) {
143
- return process.env[key];
144
- }
145
- if (parsed[key]) {
146
- return this.#interpolate(parsed[key], parsed);
147
- }
148
- return process.env[key] || "";
149
- }
150
- /**
151
- * Interpolating the token wrapped inside the mustache braces.
152
- *
153
- * @param token - The token to interpolate
154
- * @param parsed - Parsed environment variables object
155
- * @returns Interpolated value
156
- */
157
- #interpolateMustache(token, parsed) {
158
- const closingBrace = token.indexOf("}");
159
- if (closingBrace === -1) {
160
- return token;
161
- }
162
- const varReference = token.slice(1, closingBrace).trim();
163
- return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`;
164
- }
165
- /**
166
- * Interpolating the variable reference starting with a
167
- * `$`. We only capture numbers,letter and underscore.
168
- * For other characters, one can use the mustache
169
- * braces.
170
- *
171
- * @param token - The token to interpolate
172
- * @param parsed - Parsed environment variables object
173
- * @returns Interpolated value
174
- */
175
- #interpolateVariable(token, parsed) {
176
- return token.replace(/[a-zA-Z0-9_]+/, (key) => {
177
- return this.#getValue(key, parsed);
178
- });
179
- }
180
- /**
181
- * Interpolates the referenced values
182
- *
183
- * @param value - The value to interpolate
184
- * @param parsed - Parsed environment variables object
185
- * @returns Interpolated value
186
- */
187
- #interpolate(value, parsed) {
188
- const tokens = value.split("$");
189
- let newValue = "";
190
- let skipNextToken = true;
191
- tokens.forEach((token) => {
192
- if (token === "\\") {
193
- newValue += "$";
194
- skipNextToken = true;
195
- return;
196
- }
197
- if (skipNextToken) {
198
- newValue += token.replace(/\\$/, "$");
199
- if (token.endsWith("\\")) {
200
- return;
201
- }
202
- } else {
203
- if (token.startsWith("{")) {
204
- newValue += this.#interpolateMustache(token, parsed);
205
- return;
206
- }
207
- newValue += this.#interpolateVariable(token, parsed);
208
- }
209
- skipNextToken = false;
210
- });
211
- return newValue;
212
- }
213
- /**
214
- * Parse the env string to an object of environment variables.
215
- *
216
- * @returns Promise resolving to parsed environment variables
217
- */
218
- async parse() {
219
- const envCollection = dotenv.parse(this.#envContents.trim());
220
- const identifiers = Object.keys(_EnvParser.#identifiers);
221
- let result = {};
222
- $keyLoop: for (const key in envCollection) {
223
- const value = this.#getValue(key, envCollection);
224
- if (value.includes(":")) {
225
- for (const identifier of identifiers) {
226
- if (value.startsWith(`${identifier}:`)) {
227
- result[key] = await _EnvParser.#identifiers[identifier](
228
- value.substring(identifier.length + 1),
229
- key,
230
- this.#appRoot
231
- );
232
- continue $keyLoop;
233
- }
234
- if (value.startsWith(`${identifier}\\:`)) {
235
- result[key] = identifier + value.substring(identifier.length + 1);
236
- continue $keyLoop;
237
- }
238
- }
239
- result[key] = value;
240
- } else {
241
- result[key] = value;
242
- }
243
- }
244
- return result;
245
- }
27
+ const E_IDENTIFIER_ALREADY_DEFINED = createError("The identifier \"%s\" is already defined", "E_IDENTIFIER_ALREADY_DEFINED", 500);
28
+ var EnvParser = class EnvParser {
29
+ #envContents;
30
+ #appRoot;
31
+ #preferProcessEnv = true;
32
+ static #identifiers = { async file(value, key, appRoot) {
33
+ const filePath = new URL(value, appRoot);
34
+ try {
35
+ return await readFile(filePath, "utf-8");
36
+ } catch (error) {
37
+ if (error.code === "ENOENT") throw new RuntimeException(`Cannot process "${key}" env variable. Unable to locate file "${filePath}"`, { cause: error });
38
+ throw error;
39
+ }
40
+ } };
41
+ constructor(envContents, appRoot, options) {
42
+ if (options?.ignoreProcessEnv) this.#preferProcessEnv = false;
43
+ this.#envContents = envContents;
44
+ this.#appRoot = appRoot;
45
+ }
46
+ static identifier(name, callback) {
47
+ EnvParser.defineIdentifier(name, callback);
48
+ }
49
+ static defineIdentifier(name, callback) {
50
+ if (this.#identifiers[name]) throw new E_IDENTIFIER_ALREADY_DEFINED([name]);
51
+ this.#identifiers[name] = callback;
52
+ }
53
+ static defineIdentifierIfMissing(name, callback) {
54
+ if (typeof this.#identifiers[name] === "undefined") this.#identifiers[name] = callback;
55
+ }
56
+ static removeIdentifier(name) {
57
+ delete this.#identifiers[name];
58
+ }
59
+ #getValue(key, parsed) {
60
+ if (this.#preferProcessEnv && process.env[key]) return process.env[key];
61
+ if (parsed[key]) return this.#interpolate(parsed[key], parsed);
62
+ return process.env[key] || "";
63
+ }
64
+ #interpolateMustache(token, parsed) {
65
+ const closingBrace = token.indexOf("}");
66
+ if (closingBrace === -1) return token;
67
+ const varReference = token.slice(1, closingBrace).trim();
68
+ return `${this.#getValue(varReference, parsed)}${token.slice(closingBrace + 1)}`;
69
+ }
70
+ #interpolateVariable(token, parsed) {
71
+ return token.replace(/[a-zA-Z0-9_]+/, (key) => {
72
+ return this.#getValue(key, parsed);
73
+ });
74
+ }
75
+ #interpolate(value, parsed) {
76
+ const tokens = value.split("$");
77
+ let newValue = "";
78
+ let skipNextToken = true;
79
+ tokens.forEach((token) => {
80
+ if (token === "\\") {
81
+ newValue += "$";
82
+ skipNextToken = true;
83
+ return;
84
+ }
85
+ if (skipNextToken) {
86
+ newValue += token.replace(/\\$/, "$");
87
+ if (token.endsWith("\\")) return;
88
+ } else {
89
+ if (token.startsWith("{")) {
90
+ newValue += this.#interpolateMustache(token, parsed);
91
+ return;
92
+ }
93
+ newValue += this.#interpolateVariable(token, parsed);
94
+ }
95
+ skipNextToken = false;
96
+ });
97
+ return newValue;
98
+ }
99
+ async parse() {
100
+ const envCollection = parseEnv(this.#envContents.trim());
101
+ const identifiers = Object.keys(EnvParser.#identifiers);
102
+ let result = {};
103
+ $keyLoop: for (const key in envCollection) {
104
+ const value = this.#getValue(key, envCollection);
105
+ if (value.includes(":")) {
106
+ for (const identifier of identifiers) {
107
+ if (value.startsWith(`${identifier}:`)) {
108
+ result[key] = await EnvParser.#identifiers[identifier](value.substring(identifier.length + 1), key, this.#appRoot);
109
+ continue $keyLoop;
110
+ }
111
+ if (value.startsWith(`${identifier}\\:`)) {
112
+ result[key] = identifier + value.substring(identifier.length + 1);
113
+ continue $keyLoop;
114
+ }
115
+ }
116
+ result[key] = value;
117
+ } else result[key] = value;
118
+ }
119
+ return result;
120
+ }
246
121
  };
247
-
248
- // src/validator.ts
249
122
  var EnvValidator = class {
250
- /**
251
- * The validation schema for environment variables
252
- */
253
- #schema;
254
- /**
255
- * The error instance for validation failures
256
- */
257
- #error;
258
- /**
259
- * Creates a new EnvValidator instance
260
- *
261
- * @param schema - The validation schema object
262
- */
263
- constructor(schema) {
264
- this.#schema = schema;
265
- this.#error = new E_INVALID_ENV_VARIABLES();
266
- }
267
- /**
268
- * Accepts an object of values to validate against the pre-defined
269
- * schema.
270
- *
271
- * The return value is a merged copy of the original object and the
272
- * values mutated by the schema validator.
273
- *
274
- * @param values - Object of environment variable values to validate
275
- * @returns Validated and transformed environment variables
276
- */
277
- validate(values) {
278
- const help = [];
279
- const validated = Object.keys(this.#schema).reduce(
280
- (result, key) => {
281
- const value = process.env[key] || values[key];
282
- try {
283
- result[key] = this.#schema[key](key, value);
284
- } catch (error) {
285
- help.push(`- ${error.message}`);
286
- }
287
- return result;
288
- },
289
- { ...values }
290
- );
291
- if (help.length) {
292
- this.#error.help = help.join("\n");
293
- throw this.#error;
294
- }
295
- return validated;
296
- }
123
+ #schema;
124
+ #error;
125
+ constructor(schema$2) {
126
+ this.#schema = schema$2;
127
+ this.#error = new E_INVALID_ENV_VARIABLES();
128
+ }
129
+ validate(values) {
130
+ const help = [];
131
+ const validated = Object.keys(this.#schema).reduce((result, key) => {
132
+ const value = process.env[key] || values[key];
133
+ try {
134
+ result[key] = this.#schema[key](key, value);
135
+ } catch (error) {
136
+ help.push(`- ${error.message}`);
137
+ }
138
+ return result;
139
+ }, { ...values });
140
+ if (help.length) {
141
+ this.#error.help = help.join("\n");
142
+ throw this.#error;
143
+ }
144
+ return validated;
145
+ }
297
146
  };
298
-
299
- // src/processor.ts
300
147
  var EnvProcessor = class {
301
- /**
302
- * App root is needed to load files
303
- */
304
- #appRoot;
305
- /**
306
- * Creates a new EnvProcessor instance
307
- *
308
- * @param appRoot - The application root directory URL
309
- */
310
- constructor(appRoot) {
311
- this.#appRoot = appRoot;
312
- }
313
- /**
314
- * Parse env variables from raw contents
315
- *
316
- * @param envContents - Raw environment file contents
317
- * @param store - Store object to collect parsed variables
318
- * @returns Updated store with parsed variables
319
- */
320
- async #processContents(envContents, store) {
321
- if (!envContents.trim()) {
322
- return store;
323
- }
324
- const parser = new EnvParser(envContents, this.#appRoot);
325
- const values = await parser.parse();
326
- Object.keys(values).forEach((key) => {
327
- let value = process.env[key];
328
- if (!value) {
329
- value = values[key];
330
- process.env[key] = values[key];
331
- }
332
- if (!store[key]) {
333
- store[key] = value;
334
- }
335
- });
336
- return store;
337
- }
338
- /**
339
- * Parse env variables by loading dot files.
340
- *
341
- * @returns Promise resolving to collected environment variables
342
- */
343
- async #loadAndProcessDotFiles() {
344
- const loader = new EnvLoader(this.#appRoot);
345
- const envFiles = await loader.load();
346
- if (debug_default.enabled) {
347
- debug_default(
348
- "processing .env files (priority from top to bottom) %O",
349
- envFiles.map((file) => file.path)
350
- );
351
- }
352
- const envValues = {};
353
- await Promise.all(envFiles.map(({ contents }) => this.#processContents(contents, envValues)));
354
- return envValues;
355
- }
356
- /**
357
- * Process env variables
358
- *
359
- * @returns Promise resolving to processed environment variables
360
- */
361
- async process() {
362
- return this.#loadAndProcessDotFiles();
363
- }
148
+ #appRoot;
149
+ constructor(appRoot) {
150
+ this.#appRoot = appRoot;
151
+ }
152
+ async #processContents(envContents, store) {
153
+ if (!envContents.trim()) return store;
154
+ const values = await new EnvParser(envContents, this.#appRoot).parse();
155
+ Object.keys(values).forEach((key) => {
156
+ let value = process.env[key];
157
+ if (value === void 0) {
158
+ value = values[key];
159
+ process.env[key] = values[key];
160
+ }
161
+ if (key in store === false) store[key] = value;
162
+ });
163
+ return store;
164
+ }
165
+ async #loadAndProcessDotFiles() {
166
+ const envFiles = await new EnvLoader(this.#appRoot).load();
167
+ if (debug_default.enabled) debug_default("processing .env files (priority from top to bottom) %O", envFiles.map((file) => file.path));
168
+ const envValues = {};
169
+ await Promise.all(envFiles.map(({ contents }) => this.#processContents(contents, envValues)));
170
+ return envValues;
171
+ }
172
+ async process() {
173
+ return this.#loadAndProcessDotFiles();
174
+ }
175
+ };
176
+ function secret(options) {
177
+ return function validate(key, value) {
178
+ if (!value) throw new Error(options?.message ?? `Missing environment variable "${key}"`);
179
+ return new Secret(value);
180
+ };
181
+ }
182
+ secret.optional = function optionalString() {
183
+ return function validate(_, value) {
184
+ if (!value) return;
185
+ return new Secret(value);
186
+ };
187
+ };
188
+ secret.optionalWhen = function optionalWhenString(condition, options) {
189
+ return function validate(key, value) {
190
+ if (typeof condition === "function" ? condition(key, value) : condition) return secret.optional()(key, value);
191
+ return secret(options)(key, value);
192
+ };
364
193
  };
365
-
366
- // src/env.ts
367
- var Env = class _Env {
368
- /**
369
- * A cache of env values
370
- */
371
- #values;
372
- /**
373
- * Creates a new Env instance
374
- *
375
- * @param values - Validated environment values
376
- */
377
- constructor(values) {
378
- this.#values = values;
379
- }
380
- /**
381
- * Create an instance of the env class by validating the
382
- * environment variables. Also, the `.env` files are
383
- * loaded from the appRoot
384
- *
385
- * @param appRoot - The application root directory URL
386
- * @param schema - Validation schema for environment variables
387
- * @returns Promise resolving to an Env instance with validated values
388
- */
389
- static async create(appRoot, schema) {
390
- const values = await new EnvProcessor(appRoot).process();
391
- const validator = this.rules(schema);
392
- return new _Env(validator.validate(values));
393
- }
394
- /**
395
- * Define an identifier for any environment value. The callback is invoked
396
- * when the value match the identifier to modify its interpolation.
397
- *
398
- * @deprecated use `Env.defineIdentifier` instead
399
- * @param name - The identifier name
400
- * @param callback - Callback function to process the identifier value
401
- */
402
- static identifier(name, callback) {
403
- return EnvParser.defineIdentifier(name, callback);
404
- }
405
- /**
406
- * Define an identifier for any environment value. The callback is invoked
407
- * when the value match the identifier to modify its interpolation.
408
- *
409
- * @param name - The identifier name
410
- * @param callback - Callback function to process the identifier value
411
- */
412
- static defineIdentifier(name, callback) {
413
- EnvParser.defineIdentifier(name, callback);
414
- }
415
- /**
416
- * Define an identifier for any environment value, if it's not already defined.
417
- * The callback is invoked when the value match the identifier to modify its
418
- * interpolation.
419
- *
420
- * @param name - The identifier name
421
- * @param callback - Callback function to process the identifier value
422
- */
423
- static defineIdentifierIfMissing(name, callback) {
424
- EnvParser.defineIdentifierIfMissing(name, callback);
425
- }
426
- /**
427
- * Remove an identifier
428
- *
429
- * @param name - The identifier name to remove
430
- */
431
- static removeIdentifier(name) {
432
- EnvParser.removeIdentifier(name);
433
- }
434
- /**
435
- * The schema builder for defining validation rules
436
- */
437
- static schema = envSchema;
438
- /**
439
- * Define the validation rules for validating environment
440
- * variables. The return value is an instance of the
441
- * env validator
442
- *
443
- * @param schema - Validation schema object
444
- * @returns EnvValidator instance
445
- */
446
- static rules(schema) {
447
- const validator = new EnvValidator(schema);
448
- return validator;
449
- }
450
- get(key, defaultValue) {
451
- if (this.#values[key] !== void 0) {
452
- return this.#values[key];
453
- }
454
- const envValue = process.env[key];
455
- if (envValue) {
456
- return envValue;
457
- }
458
- return defaultValue;
459
- }
460
- set(key, value) {
461
- this.#values[key] = value;
462
- process.env[key] = value;
463
- }
194
+ const schema$1 = {
195
+ ...schema,
196
+ secret
464
197
  };
465
- export {
466
- Env,
467
- EnvLoader,
468
- EnvParser,
469
- EnvProcessor,
470
- errors_exports as errors
198
+ var Env = class Env {
199
+ #values;
200
+ constructor(values) {
201
+ this.#values = values;
202
+ }
203
+ static async create(appRoot, schema$2) {
204
+ const values = await new EnvProcessor(appRoot).process();
205
+ return new Env(this.rules(schema$2).validate(values));
206
+ }
207
+ static identifier(name, callback) {
208
+ return EnvParser.defineIdentifier(name, callback);
209
+ }
210
+ static defineIdentifier(name, callback) {
211
+ EnvParser.defineIdentifier(name, callback);
212
+ }
213
+ static defineIdentifierIfMissing(name, callback) {
214
+ EnvParser.defineIdentifierIfMissing(name, callback);
215
+ }
216
+ static removeIdentifier(name) {
217
+ EnvParser.removeIdentifier(name);
218
+ }
219
+ static schema = schema$1;
220
+ static rules(schema$2) {
221
+ return new EnvValidator(schema$2);
222
+ }
223
+ get(key, defaultValue) {
224
+ if (this.#values[key] !== void 0) return this.#values[key];
225
+ const envValue = process.env[key];
226
+ if (envValue) return envValue;
227
+ return defaultValue;
228
+ }
229
+ set(key, value) {
230
+ this.#values[key] = value;
231
+ process.env[key] = value;
232
+ }
471
233
  };
234
+ export { Env, EnvLoader, EnvParser, EnvProcessor, errors_exports as errors };
@@ -0,0 +1,74 @@
1
+ import { debuglog } from "node:util";
2
+ import { readFile } from "node:fs/promises";
3
+ import { fileURLToPath } from "node:url";
4
+ import { isAbsolute, join } from "node:path";
5
+ var debug_default = debuglog("adonisjs:env");
6
+ var EnvLoader = class {
7
+ #appRoot;
8
+ #loadExampleFile;
9
+ constructor(appRoot, loadExampleFile = false) {
10
+ this.#appRoot = typeof appRoot === "string" ? appRoot : fileURLToPath(appRoot);
11
+ this.#loadExampleFile = loadExampleFile;
12
+ }
13
+ async #loadFile(filePath) {
14
+ try {
15
+ return {
16
+ contents: await readFile(filePath, "utf-8"),
17
+ fileExists: true
18
+ };
19
+ } catch (error) {
20
+ /* c8 ignore next 3 */
21
+ if (error.code !== "ENOENT") throw error;
22
+ return {
23
+ contents: "",
24
+ fileExists: false
25
+ };
26
+ }
27
+ }
28
+ async load() {
29
+ const ENV_PATH = process.env.ENV_PATH;
30
+ const NODE_ENV = process.env.NODE_ENV;
31
+ const envFiles = [];
32
+ if (debug_default.enabled) {
33
+ debug_default("ENV_PATH variable is %s", ENV_PATH ? "set" : "not set");
34
+ debug_default("NODE_ENV variable is %s", NODE_ENV ? "set" : "not set");
35
+ }
36
+ const baseEnvPath = ENV_PATH ? isAbsolute(ENV_PATH) ? ENV_PATH : join(this.#appRoot, ENV_PATH) : this.#appRoot;
37
+ if (debug_default.enabled) debug_default("dot-env files base path \"%s\"", baseEnvPath);
38
+ if (NODE_ENV) {
39
+ const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
40
+ envFiles.push({
41
+ path: nodeEnvLocalFile,
42
+ ...await this.#loadFile(nodeEnvLocalFile)
43
+ });
44
+ }
45
+ if (!NODE_ENV || !["test", "testing"].includes(NODE_ENV)) {
46
+ const envLocalFile = join(baseEnvPath, ".env.local");
47
+ envFiles.push({
48
+ path: envLocalFile,
49
+ ...await this.#loadFile(envLocalFile)
50
+ });
51
+ }
52
+ if (NODE_ENV) {
53
+ const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
54
+ envFiles.push({
55
+ path: nodeEnvFile,
56
+ ...await this.#loadFile(nodeEnvFile)
57
+ });
58
+ }
59
+ const envFile = join(baseEnvPath, ".env");
60
+ envFiles.push({
61
+ path: envFile,
62
+ ...await this.#loadFile(envFile)
63
+ });
64
+ if (this.#loadExampleFile) {
65
+ const envExampleFile = join(baseEnvPath, ".env.example");
66
+ envFiles.push({
67
+ path: envExampleFile,
68
+ ...await this.#loadFile(envExampleFile)
69
+ });
70
+ }
71
+ return envFiles;
72
+ }
73
+ };
74
+ export { debug_default as n, EnvLoader as t };
@@ -1,2 +1,2 @@
1
- declare const _default: import("util").DebugLogger;
1
+ declare const _default: import("node:util").DebugLogger;
2
2
  export default _default;
@@ -1,103 +1,43 @@
1
- import {
2
- EnvLoader
3
- } from "../chunk-KE5AFOK2.js";
4
-
5
- // src/editor.ts
1
+ import { t as EnvLoader } from "../loader-KsjAiZ3e.js";
2
+ import { writeFile } from "node:fs/promises";
6
3
  import splitLines from "split-lines";
7
4
  import lodash from "@poppinss/utils/lodash";
8
- import { writeFile } from "fs/promises";
9
- var EnvEditor = class _EnvEditor {
10
- /**
11
- * The application root directory URL
12
- */
13
- #appRoot;
14
- /**
15
- * Environment file loader instance
16
- */
17
- #loader;
18
- /**
19
- * Array of loaded environment files with their contents and paths
20
- */
21
- #files = [];
22
- /**
23
- * Creates an instance of env editor and loads .env files
24
- * contents.
25
- *
26
- * @param appRoot - The application root directory URL
27
- * @returns Promise resolving to an EnvEditor instance
28
- */
29
- static async create(appRoot) {
30
- const editor = new _EnvEditor(appRoot);
31
- await editor.load();
32
- return editor;
33
- }
34
- /**
35
- * Constructs a new EnvEditor instance
36
- *
37
- * @param appRoot - The application root directory URL
38
- */
39
- constructor(appRoot) {
40
- this.#appRoot = appRoot;
41
- this.#loader = new EnvLoader(this.#appRoot, true);
42
- }
43
- /**
44
- * Loads .env files for editing. Only ".env" and ".env.example"
45
- * files are picked for editing.
46
- *
47
- * @returns Promise that resolves when files are loaded
48
- */
49
- async load() {
50
- const envFiles = await this.#loader.load();
51
- this.#files = envFiles.filter(
52
- (envFile) => envFile.fileExists && (envFile.path.endsWith(".env") || envFile.path.endsWith(".env.example"))
53
- ).map((envFile) => {
54
- return {
55
- contents: splitLines(envFile.contents.trim()),
56
- path: envFile.path
57
- };
58
- });
59
- }
60
- /**
61
- * Add key-value pair to the dot-env files.
62
- * If `withEmptyExampleValue` is true then the key will be added with an empty value
63
- * to the `.env.example` file.
64
- *
65
- * @param key - The environment variable key
66
- * @param value - The environment variable value
67
- * @param withEmptyExampleValue - Whether to add empty value to .env.example file
68
- */
69
- add(key, value, withEmptyExampleValue = false) {
70
- this.#files.forEach((file) => {
71
- let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
72
- entryIndex = entryIndex === -1 ? file.contents.length : entryIndex;
73
- if (withEmptyExampleValue && file.path.endsWith(".env.example")) {
74
- lodash.set(file.contents, entryIndex, `${key}=`);
75
- } else {
76
- lodash.set(file.contents, entryIndex, `${key}=${value}`);
77
- }
78
- });
79
- }
80
- /**
81
- * Returns the loaded files as JSON
82
- *
83
- * @returns Array of file objects with contents and paths
84
- */
85
- toJSON() {
86
- return this.#files;
87
- }
88
- /**
89
- * Save changes to the disk
90
- *
91
- * @returns Promise that resolves when files are saved
92
- */
93
- async save() {
94
- await Promise.all(
95
- this.#files.map((file) => {
96
- return writeFile(file.path, file.contents.join("\n"));
97
- })
98
- );
99
- }
100
- };
101
- export {
102
- EnvEditor
5
+ var EnvEditor = class EnvEditor {
6
+ #appRoot;
7
+ #loader;
8
+ #files = [];
9
+ static async create(appRoot) {
10
+ const editor = new EnvEditor(appRoot);
11
+ await editor.load();
12
+ return editor;
13
+ }
14
+ constructor(appRoot) {
15
+ this.#appRoot = appRoot;
16
+ this.#loader = new EnvLoader(this.#appRoot, true);
17
+ }
18
+ async load() {
19
+ this.#files = (await this.#loader.load()).filter((envFile) => envFile.fileExists && (envFile.path.endsWith(".env") || envFile.path.endsWith(".env.example"))).map((envFile) => {
20
+ return {
21
+ contents: splitLines(envFile.contents.trim()),
22
+ path: envFile.path
23
+ };
24
+ });
25
+ }
26
+ add(key, value, withEmptyExampleValue = false) {
27
+ this.#files.forEach((file) => {
28
+ let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
29
+ entryIndex = entryIndex === -1 ? file.contents.length : entryIndex;
30
+ if (withEmptyExampleValue && file.path.endsWith(".env.example")) lodash.set(file.contents, entryIndex, `${key}=`);
31
+ else lodash.set(file.contents, entryIndex, `${key}=${value}`);
32
+ });
33
+ }
34
+ toJSON() {
35
+ return this.#files;
36
+ }
37
+ async save() {
38
+ await Promise.all(this.#files.map((file) => {
39
+ return writeFile(file.path, file.contents.join("\n"));
40
+ }));
41
+ }
103
42
  };
43
+ export { EnvEditor };
@@ -1,6 +1,6 @@
1
- import { schema as envSchema } from '@poppinss/validator-lite';
2
1
  import type { ValidateFn } from '@poppinss/validator-lite/types';
3
2
  import { EnvValidator } from './validator.ts';
3
+ import { schema as envSchema } from './schema.ts';
4
4
  /**
5
5
  * A wrapper over "process.env" with types information.
6
6
  *
@@ -1,9 +1,8 @@
1
- import { type DotenvParseOutput } from 'dotenv';
2
1
  /**
3
2
  * Env parser parses the environment variables from a string formatted
4
3
  * as a key-value pair seperated using an `=`. For example:
5
4
  *
6
- * ```dotenv
5
+ * ```
7
6
  * PORT=3333
8
7
  * HOST=127.0.0.1
9
8
  * ```
@@ -11,7 +10,7 @@ import { type DotenvParseOutput } from 'dotenv';
11
10
  * The variables can reference other environment variables as well using `$`.
12
11
  * For example:
13
12
  *
14
- * ```dotenv
13
+ * ```
15
14
  * PORT=3333
16
15
  * REDIS_PORT=$PORT
17
16
  * ```
@@ -19,14 +18,14 @@ import { type DotenvParseOutput } from 'dotenv';
19
18
  * The variables using characters other than letters can wrap variable
20
19
  * named inside a curly brace.
21
20
  *
22
- * ```dotenv
21
+ * ```
23
22
  * APP-PORT=3333
24
23
  * REDIS_PORT=${APP-PORT}
25
24
  * ```
26
25
  *
27
26
  * You can escape the `$` sign with a backtick.
28
27
  *
29
- * ```dotenv
28
+ * ```
30
29
  * REDIS_PASSWORD=foo\$123
31
30
  * ```
32
31
  *
@@ -94,5 +93,5 @@ export declare class EnvParser {
94
93
  *
95
94
  * @returns Promise resolving to parsed environment variables
96
95
  */
97
- parse(): Promise<DotenvParseOutput>;
96
+ parse(): Promise<NodeJS.Dict<string>>;
98
97
  }
@@ -0,0 +1,13 @@
1
+ import { Secret } from '@poppinss/utils';
2
+ import { type Prettify } from '@poppinss/utils/types';
3
+ import { schema as envSchema } from '@poppinss/validator-lite';
4
+ import { type SchemaFnOptions } from '@poppinss/validator-lite/types';
5
+ declare function secret(options?: SchemaFnOptions): (key: string, value?: string) => Secret<string>;
6
+ declare namespace secret {
7
+ var optional: () => (_: string, value?: string) => Secret<string> | undefined;
8
+ var optionalWhen: (condition: boolean | ((key: string, value?: string) => boolean), options?: SchemaFnOptions) => (key: string, value?: string) => Secret<string> | undefined;
9
+ }
10
+ export declare const schema: Prettify<typeof envSchema & {
11
+ secret: typeof secret;
12
+ }>;
13
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonisjs/env",
3
- "version": "7.0.0-next.1",
3
+ "version": "7.0.0-next.3",
4
4
  "description": "Environment variable manager for Node.js",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "typecheck": "tsc --noEmit",
27
27
  "precompile": "npm run lint && npm run clean",
28
28
  "clean": "del-cli build",
29
- "compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
29
+ "compile": "tsdown && tsc --emitDeclarationOnly --declaration",
30
30
  "build": "npm run compile",
31
31
  "release": "release-it",
32
32
  "version": "npm run build",
@@ -34,29 +34,29 @@
34
34
  "quick:test": "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts"
35
35
  },
36
36
  "devDependencies": {
37
- "@adonisjs/eslint-config": "^3.0.0-next.1",
37
+ "@adonisjs/eslint-config": "^3.0.0-next.5",
38
38
  "@adonisjs/prettier-config": "^1.4.5",
39
- "@adonisjs/tsconfig": "^2.0.0-next.0",
40
- "@japa/assert": "^4.1.1",
41
- "@japa/expect-type": "^2.0.3",
42
- "@japa/file-system": "^2.3.2",
43
- "@japa/runner": "^4.4.0",
39
+ "@adonisjs/tsconfig": "^2.0.0-next.3",
40
+ "@japa/assert": "^4.2.0",
41
+ "@japa/expect-type": "^2.0.4",
42
+ "@japa/file-system": "^3.0.0",
43
+ "@japa/runner": "^5.0.0",
44
44
  "@poppinss/ts-exec": "^1.4.1",
45
- "@release-it/conventional-changelog": "^10.0.1",
46
- "@types/node": "^24.3.0",
45
+ "@release-it/conventional-changelog": "^10.0.3",
46
+ "@types/node": "^25.0.2",
47
47
  "c8": "^10.1.3",
48
- "cross-env": "^10.0.0",
49
- "del-cli": "^6.0.0",
50
- "eslint": "^9.34.0",
51
- "prettier": "^3.6.2",
52
- "release-it": "^19.0.4",
53
- "tsup": "^8.5.0",
54
- "typescript": "^5.9.2"
48
+ "cross-env": "^10.1.0",
49
+ "del-cli": "^7.0.0",
50
+ "eslint": "^9.39.2",
51
+ "prettier": "^3.7.4",
52
+ "release-it": "^19.1.0",
53
+ "tsdown": "^0.17.4",
54
+ "typedoc": "^0.28.15",
55
+ "typescript": "^5.9.3"
55
56
  },
56
57
  "dependencies": {
57
- "@poppinss/utils": "^7.0.0-next.3",
58
+ "@poppinss/utils": "^7.0.0-next.4",
58
59
  "@poppinss/validator-lite": "^2.1.2",
59
- "dotenv": "^17.2.1",
60
60
  "split-lines": "^3.0.0"
61
61
  },
62
62
  "homepage": "https://github.com/adonisjs/env#readme",
@@ -81,7 +81,7 @@
81
81
  "access": "public",
82
82
  "provenance": true
83
83
  },
84
- "tsup": {
84
+ "tsdown": {
85
85
  "entry": [
86
86
  "./index.ts",
87
87
  "./src/types.ts",
@@ -90,8 +90,11 @@
90
90
  "outDir": "./build",
91
91
  "clean": true,
92
92
  "format": "esm",
93
+ "minify": "dce-only",
94
+ "fixedExtension": false,
93
95
  "dts": false,
94
- "sourcemap": false,
96
+ "treeshake": false,
97
+ "sourcemaps": false,
95
98
  "target": "esnext"
96
99
  },
97
100
  "release-it": {
@@ -1,112 +0,0 @@
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 "url";
9
- import { readFile } from "fs/promises";
10
- import { isAbsolute, join } from "path";
11
-
12
- // src/debug.ts
13
- import { debuglog } from "util";
14
- var debug_default = debuglog("adonisjs:env");
15
-
16
- // src/loader.ts
17
- var EnvLoader = class {
18
- /**
19
- * The application root directory path
20
- */
21
- #appRoot;
22
- /**
23
- * Whether to load the .env.example file
24
- */
25
- #loadExampleFile;
26
- /**
27
- * Creates a new EnvLoader instance
28
- *
29
- * @param appRoot - The application root directory as string or URL
30
- * @param loadExampleFile - Whether to load .env.example file
31
- */
32
- constructor(appRoot, loadExampleFile = false) {
33
- this.#appRoot = typeof appRoot === "string" ? appRoot : fileURLToPath(appRoot);
34
- this.#loadExampleFile = loadExampleFile;
35
- }
36
- /**
37
- * Optionally read a file from the disk
38
- *
39
- * @param filePath - Path to the file to read
40
- * @returns Promise resolving to file existence status and contents
41
- */
42
- async #loadFile(filePath) {
43
- try {
44
- const contents = await readFile(filePath, "utf-8");
45
- return { contents, fileExists: true };
46
- } catch (error) {
47
- if (error.code !== "ENOENT") {
48
- throw error;
49
- }
50
- return { contents: "", fileExists: false };
51
- }
52
- }
53
- /**
54
- * Load contents of the main dot-env file and the current
55
- * environment dot-env file
56
- *
57
- * @returns Promise resolving to array of loaded environment files
58
- */
59
- async load() {
60
- const ENV_PATH = process.env.ENV_PATH;
61
- const NODE_ENV = process.env.NODE_ENV;
62
- const envFiles = [];
63
- if (debug_default.enabled) {
64
- debug_default("ENV_PATH variable is %s", ENV_PATH ? "set" : "not set");
65
- debug_default("NODE_ENV variable is %s", NODE_ENV ? "set" : "not set");
66
- }
67
- const baseEnvPath = ENV_PATH ? isAbsolute(ENV_PATH) ? ENV_PATH : join(this.#appRoot, ENV_PATH) : this.#appRoot;
68
- if (debug_default.enabled) {
69
- debug_default('dot-env files base path "%s"', baseEnvPath);
70
- }
71
- if (NODE_ENV) {
72
- const nodeEnvLocalFile = join(baseEnvPath, `.env.${NODE_ENV}.local`);
73
- envFiles.push({
74
- path: nodeEnvLocalFile,
75
- ...await this.#loadFile(nodeEnvLocalFile)
76
- });
77
- }
78
- if (!NODE_ENV || !["test", "testing"].includes(NODE_ENV)) {
79
- const envLocalFile = join(baseEnvPath, ".env.local");
80
- envFiles.push({
81
- path: envLocalFile,
82
- ...await this.#loadFile(envLocalFile)
83
- });
84
- }
85
- if (NODE_ENV) {
86
- const nodeEnvFile = join(baseEnvPath, `.env.${NODE_ENV}`);
87
- envFiles.push({
88
- path: nodeEnvFile,
89
- ...await this.#loadFile(nodeEnvFile)
90
- });
91
- }
92
- const envFile = join(baseEnvPath, ".env");
93
- envFiles.push({
94
- path: envFile,
95
- ...await this.#loadFile(envFile)
96
- });
97
- if (this.#loadExampleFile) {
98
- const envExampleFile = join(baseEnvPath, ".env.example");
99
- envFiles.push({
100
- path: envExampleFile,
101
- ...await this.#loadFile(envExampleFile)
102
- });
103
- }
104
- return envFiles;
105
- }
106
- };
107
-
108
- export {
109
- __export,
110
- debug_default,
111
- EnvLoader
112
- };