@adonisjs/env 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -3
- package/build/src/editor.d.ts +3 -1
- package/build/src/editor.js +8 -2
- package/build/src/editor.js.map +1 -1
- package/package.json +36 -25
package/README.md
CHANGED
|
@@ -12,8 +12,6 @@ Install the package from the npm packages registry as follows.
|
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
14
|
npm i @adonisjs/env
|
|
15
|
-
|
|
16
|
-
yarn add @adonisjs/env
|
|
17
15
|
```
|
|
18
16
|
|
|
19
17
|
## EnvLoader
|
|
@@ -52,7 +50,7 @@ const envParser = new EnvParser(`
|
|
|
52
50
|
HOST=localhost
|
|
53
51
|
`)
|
|
54
52
|
|
|
55
|
-
console.log(envParser.parse()) // { PORT: '3000', HOST: 'localhost' }
|
|
53
|
+
console.log(await envParser.parse()) // { PORT: '3000', HOST: 'localhost' }
|
|
56
54
|
```
|
|
57
55
|
|
|
58
56
|
The return value of `parser.parse` is an object with key-value pair. The parser also has support for interpolation.
|
|
@@ -63,6 +61,27 @@ By default, the parser prefers existing `process.env` values when they exist. Ho
|
|
|
63
61
|
new EnvParser(envContents, { ignoreProcessEnv: true })
|
|
64
62
|
```
|
|
65
63
|
|
|
64
|
+
### Identifier
|
|
65
|
+
|
|
66
|
+
You can define an "identifier" to be used for interpolation. The identifier is a string that prefix the environment variable value and let you customize the value resolution.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { readFile } from 'node:fs/promises'
|
|
70
|
+
import { EnvParser } from '@adonisjs/env'
|
|
71
|
+
|
|
72
|
+
EnvParser.identifier('file', (value) => {
|
|
73
|
+
return readFile(value, 'utf-8')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const envParser = new EnvParser(`
|
|
77
|
+
DB_PASSWORD=file:/run/secret/db_password
|
|
78
|
+
`)
|
|
79
|
+
|
|
80
|
+
console.log(await envParser.parse()) // { DB_PASSWORD: 'Value from file /run/secret/db_password' }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This can be useful when you are using secrets manager like `Docker Secret`, `HashiCorp Vault`, `Google Secrets Manager` and others to manage your secrets.
|
|
84
|
+
|
|
66
85
|
## Validating environment variables
|
|
67
86
|
Once you have the parsed objects, you can optionally validate them against a pre-defined schema. We recommend validation for the following reasons.
|
|
68
87
|
|
|
@@ -120,6 +139,18 @@ editor.add('HOST', 'localhost')
|
|
|
120
139
|
await editor.save()
|
|
121
140
|
```
|
|
122
141
|
|
|
142
|
+
You can also insert an empty value for the `.env.example` file by setting the last argument to `true`.
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
editor.add('SECRET_VARIABLE', 'secret-value', true)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This will add the following line to the `.env.example` file.
|
|
149
|
+
|
|
150
|
+
```env
|
|
151
|
+
SECRET_VARIABLE=
|
|
152
|
+
```
|
|
153
|
+
|
|
123
154
|
## Known Exceptions
|
|
124
155
|
|
|
125
156
|
### E_INVALID_ENV_VARIABLES
|
package/build/src/editor.d.ts
CHANGED
|
@@ -14,8 +14,10 @@ export declare class EnvEditor {
|
|
|
14
14
|
load(): Promise<void>;
|
|
15
15
|
/**
|
|
16
16
|
* Add key-value pair to the dot-env files.
|
|
17
|
+
* If `withEmptyExampleValue` is true then the key will be added with an empty value
|
|
18
|
+
* to the `.env.example` file.
|
|
17
19
|
*/
|
|
18
|
-
add(key: string, value: string | number | boolean): void;
|
|
20
|
+
add(key: string, value: string | number | boolean, withEmptyExampleValue?: boolean): void;
|
|
19
21
|
toJSON(): {
|
|
20
22
|
contents: string[];
|
|
21
23
|
path: string;
|
package/build/src/editor.js
CHANGED
|
@@ -40,12 +40,18 @@ var EnvEditor = class _EnvEditor {
|
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Add key-value pair to the dot-env files.
|
|
43
|
+
* If `withEmptyExampleValue` is true then the key will be added with an empty value
|
|
44
|
+
* to the `.env.example` file.
|
|
43
45
|
*/
|
|
44
|
-
add(key, value) {
|
|
46
|
+
add(key, value, withEmptyExampleValue = false) {
|
|
45
47
|
this.#files.forEach((file) => {
|
|
46
48
|
let entryIndex = file.contents.findIndex((line) => line.startsWith(`${key}=`));
|
|
47
49
|
entryIndex = entryIndex === -1 ? file.contents.length : entryIndex;
|
|
48
|
-
|
|
50
|
+
if (withEmptyExampleValue && file.path.endsWith(".env.example")) {
|
|
51
|
+
lodash.set(file.contents, entryIndex, `${key}=`);
|
|
52
|
+
} else {
|
|
53
|
+
lodash.set(file.contents, entryIndex, `${key}=${value}`);
|
|
54
|
+
}
|
|
49
55
|
});
|
|
50
56
|
}
|
|
51
57
|
toJSON() {
|
package/build/src/editor.js.map
CHANGED
|
@@ -1 +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}=${
|
|
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 * If `withEmptyExampleValue` is true then the key will be added with an empty value\n * to the `.env.example` file.\n */\n add(key: string, value: string | number | boolean, withEmptyExampleValue = false) {\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\n if (withEmptyExampleValue && file.path.endsWith('.env.example')) {\n lodash.set(file.contents, entryIndex, `${key}=`)\n } else {\n lodash.set(file.contents, entryIndex, `${key}=${value}`)\n }\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;AAAA;AAAA,EAOA,IAAI,KAAa,OAAkC,wBAAwB,OAAO;AAChF,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;AAExD,UAAI,yBAAyB,KAAK,KAAK,SAAS,cAAc,GAAG;AAC/D,eAAO,IAAI,KAAK,UAAU,YAAY,GAAG,GAAG,GAAG;AAAA,MACjD,OAAO;AACL,eAAO,IAAI,KAAK,UAAU,YAAY,GAAG,GAAG,IAAI,KAAK,EAAE;AAAA,MACzD;AAAA,IACF,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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/env",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Environment variable manager for Node.js",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"precompile": "npm run lint && npm run clean",
|
|
26
26
|
"compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
|
|
27
27
|
"build": "npm run compile",
|
|
28
|
-
"release": "
|
|
28
|
+
"release": "release-it",
|
|
29
29
|
"version": "npm run build",
|
|
30
30
|
"prepublishOnly": "npm run build",
|
|
31
31
|
"lint": "eslint . --ext=.ts",
|
|
@@ -40,33 +40,33 @@
|
|
|
40
40
|
"author": "virk,adonisjs",
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@adonisjs/eslint-config": "^1.
|
|
44
|
-
"@adonisjs/prettier-config": "^1.
|
|
45
|
-
"@adonisjs/tsconfig": "^1.
|
|
46
|
-
"@commitlint/cli": "^
|
|
47
|
-
"@commitlint/config-conventional": "^
|
|
48
|
-
"@japa/assert": "^
|
|
49
|
-
"@japa/expect-type": "^2.0.
|
|
50
|
-
"@japa/file-system": "^2.
|
|
51
|
-
"@japa/runner": "^3.1.
|
|
52
|
-
"@swc/core": "^1.
|
|
53
|
-
"@types/node": "^20.
|
|
43
|
+
"@adonisjs/eslint-config": "^1.3.0",
|
|
44
|
+
"@adonisjs/prettier-config": "^1.3.0",
|
|
45
|
+
"@adonisjs/tsconfig": "^1.3.0",
|
|
46
|
+
"@commitlint/cli": "^19.2.2",
|
|
47
|
+
"@commitlint/config-conventional": "^19.2.2",
|
|
48
|
+
"@japa/assert": "^3.0.0",
|
|
49
|
+
"@japa/expect-type": "^2.0.2",
|
|
50
|
+
"@japa/file-system": "^2.3.0",
|
|
51
|
+
"@japa/runner": "^3.1.4",
|
|
52
|
+
"@swc/core": "^1.4.16",
|
|
53
|
+
"@types/node": "^20.12.7",
|
|
54
54
|
"c8": "^9.1.0",
|
|
55
55
|
"cross-env": "^7.0.3",
|
|
56
56
|
"del-cli": "^5.1.0",
|
|
57
57
|
"eslint": "^8.56.0",
|
|
58
58
|
"github-label-sync": "^2.3.1",
|
|
59
|
-
"husky": "^
|
|
60
|
-
"
|
|
61
|
-
"
|
|
59
|
+
"husky": "^9.0.11",
|
|
60
|
+
"prettier": "^3.2.5",
|
|
61
|
+
"release-it": "^17.2.0",
|
|
62
62
|
"ts-node": "^10.9.2",
|
|
63
|
-
"tsup": "^8.0.
|
|
64
|
-
"typescript": "^5.
|
|
63
|
+
"tsup": "^8.0.2",
|
|
64
|
+
"typescript": "^5.4.5"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@poppinss/utils": "^6.7.
|
|
67
|
+
"@poppinss/utils": "^6.7.3",
|
|
68
68
|
"@poppinss/validator-lite": "^1.0.3",
|
|
69
|
-
"dotenv": "^16.
|
|
69
|
+
"dotenv": "^16.4.5",
|
|
70
70
|
"split-lines": "^3.0.0"
|
|
71
71
|
},
|
|
72
72
|
"repository": {
|
|
@@ -86,11 +86,22 @@
|
|
|
86
86
|
"access": "public",
|
|
87
87
|
"tag": "latest"
|
|
88
88
|
},
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
"release-it": {
|
|
90
|
+
"git": {
|
|
91
|
+
"commitMessage": "chore(release): ${version}",
|
|
92
|
+
"tagAnnotation": "v${version}",
|
|
93
|
+
"tagName": "v${version}"
|
|
94
|
+
},
|
|
95
|
+
"hooks": {
|
|
96
|
+
"before:init": [
|
|
97
|
+
"npm test"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"github": {
|
|
101
|
+
"release": true,
|
|
102
|
+
"releaseName": "v${version}",
|
|
103
|
+
"web": true
|
|
104
|
+
}
|
|
94
105
|
},
|
|
95
106
|
"c8": {
|
|
96
107
|
"reporter": [
|