env-creator 1.0.0 → 1.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.
Files changed (3) hide show
  1. package/README.md +125 -29
  2. package/dist/index.js +11 -7
  3. package/package.json +14 -10
package/README.md CHANGED
@@ -1,36 +1,70 @@
1
1
  # env-creator
2
2
 
3
- A fast, lightweight CLI tool for managing and generating environment (`.env`) files.
3
+ A fast, lightweight CLI tool for managing and generating custom environment (`.env`) files, designed to simplify development by enabling multiple .env configurations for different environments, as well as automatically generating JavaScript constants for direct use within the project.
4
4
 
5
5
  ## Installation
6
6
 
7
- You can install `env-creator` globally using npm:
7
+ You can install `env-creator` locally in your project (recommended) or globally.
8
+
9
+ ### Local Installation
10
+
11
+ Install as a development dependency:
8
12
 
9
13
  ```bash
10
- npm install -g env-creator
14
+ npm install env-creator --save-dev
15
+ # or
16
+ pnpm add -D env-creator
17
+ # or
18
+ yarn add -D env-creator
19
+ ```
20
+
21
+ Then run it using your package manager's runner:
22
+
23
+ ```bash
24
+ npx env-creator create
25
+ # or
26
+ pnpx env-creator create
27
+ # or (Yarn Berry)
28
+ yarn dlx env-creator create
29
+ # or (Yarn Classic)
30
+ yarn env-creator create
11
31
  ```
12
32
 
13
- Alternatively, you can run it directly using `npx` without installing globally:
33
+ ### Global Installation
34
+
35
+ If you prefer to use it across all projects:
14
36
 
15
37
  ```bash
16
- npx create-env <command> [options]
38
+ npm install -g env-creator
17
39
  # or
18
- npx env-creator <command> [options]
40
+ pnpm add -g env-creator
41
+ # or
42
+ yarn global add env-creator
19
43
  ```
20
44
 
21
- `env-creator` (also available as `create-env`) provides several commands to help you quickly set up or split your environment files.
45
+ Then run it directly:
46
+
47
+ ```bash
48
+ env-creator create
49
+ ```
22
50
 
23
- ### 1. Create an empty or pre-filled `.env` file
51
+ ## Usage (examples for `pnpm`)
52
+
53
+ `env-creator` (also available as `env`) provides several commands (along with their short aliases, e.g. `c` for `create`) to help you quickly set up or split your environment files.
54
+
55
+ ### 1. Create an empty or pre-filled `.env` file (alias: `c`)
24
56
 
25
57
  Generates a `.env` file in the current working directory. You can optionally pass `KEY=VALUE` pairs to pre-fill it. If a file already exists, it will not overwrite it.
26
58
 
27
59
  ```bash
28
- npx create-env create
60
+ pnpx env-creator create
29
61
  ```
30
62
 
31
63
  **With initial fields:**
32
64
  ```bash
33
- npx create-env create PORT=3000 NODE_ENV=development
65
+ pnpx env-creator create PORT=3000 NODE_ENV=development
66
+ # or short version
67
+ pnpx env c PORT=3000 NODE_ENV=development
34
68
  ```
35
69
 
36
70
  **Resulting `.env`:**
@@ -39,27 +73,27 @@ PORT=3000
39
73
  NODE_ENV=development
40
74
  ```
41
75
 
42
- ### 2. Create from JSON
76
+ ### 2. Create from JSON (alias: `cfj`)
43
77
 
44
78
  Generates a `.env` target file from a provided JSON file. The keys and values in the JSON file will be converted into `KEY=VALUE` format.
45
79
  You can optionally provide an `--env <name>` flag to create a specific `.env.<name>` file (e.g., `.env.production`).
46
80
 
47
81
  ```bash
48
- npx create-env create-from-json <path-to-file.json> [--env <name>]
82
+ pnpx env-creator create-from-json <path-to-file.json> [--env <name>]
49
83
  ```
50
84
 
51
85
  **Example `config.json`:**
52
86
  ```json
53
87
  {
54
- "PORT": 3000,
55
- "DB_HOST": "localhost",
56
- "NODE_ENV": "development"
88
+ "PORT": 3000,
89
+ "DB_HOST": "localhost",
90
+ "NODE_ENV": "development"
57
91
  }
58
92
  ```
59
93
 
60
94
  **Command:**
61
95
  ```bash
62
- npx create-env create-from-json config.json --env production
96
+ pnpx env-creator create-from-json config.json --env production
63
97
  ```
64
98
 
65
99
  **Resulting `.env.production`:**
@@ -69,12 +103,12 @@ DB_HOST=localhost
69
103
  NODE_ENV=development
70
104
  ```
71
105
 
72
- ### 3. Split `.env` for specific environments
106
+ ### 3. Split `.env` for specific environments (alias: `s`)
73
107
 
74
108
  Reads your existing `.env` file, removes all comments and values, and creates a new target file containing **only the keys** (e.g., for creating a `.env.example` or `.env.production` template).
75
109
 
76
110
  ```bash
77
- npx create-env split --env <env-name>
111
+ pnpx env-creator split --env <env-name>
78
112
  ```
79
113
 
80
114
  **Example:**
@@ -87,7 +121,7 @@ DB_PASS=secret
87
121
 
88
122
  Running the split command for production:
89
123
  ```bash
90
- npx create-env split --env production
124
+ pnpx env-creator split --env production
91
125
  ```
92
126
 
93
127
  Will generate a new file named `.env.production` with empty values:
@@ -96,32 +130,32 @@ DB_USER=
96
130
  DB_PASS=
97
131
  ```
98
132
 
99
- ### 4. Delete an `.env` file
133
+ ### 4. Delete an `.env` file (alias: `d`)
100
134
 
101
135
  Deletes a specific environment file. If no filename is provided, it defaults to deleting `.env`.
102
136
 
103
137
  ```bash
104
- npx create-env delete [file]
138
+ pnpx env-creator delete [file]
105
139
  ```
106
140
 
107
141
  **Examples:**
108
142
  ```bash
109
- npx create-env delete # Deletes .env
110
- npx create-env delete .env.production # Deletes .env.production
143
+ pnpx env-creator delete # Deletes .env
144
+ pnpx env-creator delete .env.production # Deletes .env.production
111
145
  ```
112
146
 
113
- ### 5. Sort `.env` keys alphabetically
147
+ ### 5. Sort `.env` keys alphabetically (alias: `srt`)
114
148
 
115
149
  Reads an environment file and reorders all `KEY=VALUE` lines alphabetically. Comments and empty lines are preserved at the top of the file. Defaults to `.env` if no file is specified.
116
150
 
117
151
  ```bash
118
- npx create-env sort [file]
152
+ pnpx env-creator sort [file]
119
153
  ```
120
154
 
121
155
  **Examples:**
122
156
  ```bash
123
- npx create-env sort # Sorts .env
124
- npx create-env sort .env.production # Sorts .env.production
157
+ pnpx env-creator sort # Sorts .env
158
+ pnpx env-creator sort .env.production # Sorts .env.production
125
159
  ```
126
160
 
127
161
  **Before:**
@@ -140,6 +174,68 @@ DB_HOST=localhost
140
174
  PORT=3000
141
175
  ```
142
176
 
177
+ ### 6. Generate environment constants (alias: `gc`)
178
+
179
+ Reads an environment file (defaults to `.env`), extracts the keys, and creates a JavaScript file exporting each key inside a constant object (defaults to `envConstants.js`). You can specify a custom output file using the `--out` flag.
180
+
181
+ ```bash
182
+ pnpx env-creator generate-constants [file] [--out <filename>]
183
+ ```
184
+
185
+ **Examples:**
186
+ ```bash
187
+ pnpx env gc # Generates envConstants.js from .env by default
188
+ pnpx env gc .env.production # Generates envConstants.js from .env.production
189
+ pnpx env gc --out myConfig.js # Generates myConfig.js from .env
190
+ pnpx env gc .env.production --out config/env.js # Generates config/env.js from .env.production
191
+ ```
192
+
193
+ **Resulting `envConstants.js`:**
194
+ ```javascript
195
+ export const ENV = {
196
+ API_URL: process.env.API_URL,
197
+ JWT_SECRET: process.env.JWT_SECRET,
198
+ };
199
+ ```
200
+
201
+ > [!IMPORTANT]
202
+ > There is no `process` object in the browser. To use these constants on the client-side, you must inject the environment variables using your bundler.
203
+ >
204
+ > **Example for Webpack** (other bundlers like Vite or Rollup will require their own specific configuration):
205
+ >
206
+ > ```javascript
207
+ > import webpack from "webpack";
208
+ > import dotenv from "dotenv";
209
+ > import path from "path"; // if needed
210
+ >
211
+ > // load environment variables from .env
212
+ > const env = dotenv.config().parsed;
213
+ > // load environment variables from a specific .env file (for example, .env.production)
214
+ > // const env = dotenv.config({ path: path.resolve(__dirname, `../.env.${envName}`) }).parsed;
215
+ >
216
+ > // convert to an object for DefinePlugin
217
+ > const envKeys = Object.keys(env).reduce((acc, key) => {
218
+ > acc[`process.env.${key}`] = JSON.stringify(env[key]);
219
+ > return acc;
220
+ > }, {});
221
+ >
222
+ > // inject variables passing them into DefinePlugin
223
+ > export default {
224
+ > // ...
225
+ > plugins: [
226
+ > new webpack.DefinePlugin({ ...envKeys }),
227
+ > ],
228
+ > };
229
+ > ```
230
+
231
+ Now you can easily import these constants anywhere in your project:
232
+
233
+ ```javascript
234
+ import { ENV } from "[pathToFile]/envConstants";
235
+
236
+ console.log(`API URL: ${ENV.API_URL}`); // delete after checking
237
+ ```
238
+
143
239
  ## Development
144
240
 
145
241
  If you want to contribute or modify the tool, you can clone the repository and use the built-in npm scripts:
@@ -147,13 +243,13 @@ If you want to contribute or modify the tool, you can clone the repository and u
147
243
  ### Linting
148
244
  To check the code for syntax and style errors using ESLint:
149
245
  ```bash
150
- npm run lint
246
+ pnpx run lint
151
247
  ```
152
248
 
153
249
  ### Building
154
250
  The project uses `esbuild` to bundle and minify the code into a single executable file in the `dist/` directory:
155
251
  ```bash
156
- npm run build
252
+ pnpx run build
157
253
  ```
158
254
 
159
255
  ## License
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
- import n from"fs";import f from"path";var t=process.argv.slice(2);t.length===0&&(p(),process.exit(0));function p(){console.log("Usage: env-creator <command> [options]"),console.log("Commands:"),console.log(" create [KEY=value...] Create a .env file (optionally with values)"),console.log(" create-from-json <json> [--env <name>] Create .env or .env.<name> from JSON"),console.log(" split --env <dev|prod> Create environment-specific file from .env"),console.log(" delete [file] Delete an environment file (default: .env)"),console.log(" sort [file] Sort keys alphabetically in an env file (default: .env)"),console.log("Options:"),console.log(" -h, --help Show this help message")}var d=t[0];(d==="--help"||d==="-h"||d==="help")&&(p(),process.exit(0));switch(d){case"create":{let e=f.join(process.cwd(),".env");if(n.existsSync(e))console.log(".env already exists");else{let o=t.slice(1),s="";if(o.length>0){let i=o.filter(c=>c.includes("="));s=i.join(`
2
- `)+(i.length>0?`
3
- `:"")}n.writeFileSync(e,s),console.log(s?"Created .env with specified fields":"Created empty .env")}break}case"create-from-json":{let e=t[1];e||(console.error("Please provide a JSON file"),process.exit(1)),n.existsSync(e)||(console.error("JSON file not found"),process.exit(1));let o=t.indexOf("--env"),i=`.env${o!==-1&&t[o+1]?`.${t[o+1]}`:""}`;if(n.existsSync(i)){console.log(`${i} already exists`);break}let c=JSON.parse(n.readFileSync(e,"utf-8")),a="";for(let r in c)a+=`${r}=${c[r]}
4
- `;n.writeFileSync(i,a),console.log(`Created ${i} from JSON`);break}case"split":{let e=t.indexOf("--env");(e===-1||!t[e+1])&&(console.error("Please specify environment with --env <dev|prod>"),process.exit(1));let o=t[e+1],s=f.join(process.cwd(),".env");n.existsSync(s)||(console.error(".env file not found"),process.exit(1));let c=n.readFileSync(s,"utf-8").split(/\r?\n/).filter(r=>r.trim()!==""&&!r.startsWith("#")).map(r=>r.split("=")[0]+"=").join(`
5
- `),a=f.join(process.cwd(),`.env.${o}`);if(n.existsSync(a)){console.log(`.env.${o} already exists`);break}n.writeFileSync(a,c),console.log(`Created .env.${o} with keys only`);break}case"delete":{let e=t[1]||".env",o=f.join(process.cwd(),e);n.existsSync(o)?(n.unlinkSync(o),console.log(`Deleted ${e}`)):console.log(`File ${e} does not exist`);break}case"sort":{let e=t[1]||".env",o=f.join(process.cwd(),e);n.existsSync(o)||(console.error(`File ${e} does not exist`),process.exit(1));let s=n.readFileSync(o,"utf-8").split(/\r?\n/),i=s[s.length-1]===""?s.slice(0,-1):s,c=i.filter(l=>!l.startsWith("#")&&l.trim()!==""&&l.includes("=")).sort((l,v)=>l.localeCompare(v)),a=0,r=i.map(l=>!l.startsWith("#")&&l.trim()!==""&&l.includes("=")?c[a++]:l);n.writeFileSync(o,r.join(`
1
+ import n from"fs";import d from"path";import u from"readline";var t=process.argv.slice(2);t.length===0&&(h(),process.exit(0));function h(){console.log("Usage: env-creator <command> [options]"),console.log(" or: env <command> [options]"),console.log("Commands:"),console.log(" c, create [KEY=value...] Create a .env file (optionally with values)"),console.log(" cfj, create-from-json <json> [--env <name>] Create .env or .env.<name> from JSON"),console.log(" s, split --env <dev|prod> Create environment-specific file from .env"),console.log(" d, delete [file] Delete an environment file (default: .env)"),console.log(" srt, sort [file] Sort keys alphabetically in an env file (default: .env)"),console.log(" gc, generate-constants [file] [--out <file>] Generate a JS file with env variable constants"),console.log("Options:"),console.log(" -h, --help Show this help message")}var g=t[0];(g==="--help"||g==="-h"||g==="help")&&(h(),process.exit(0));switch(g){case"c":case"create":{let e=d.join(process.cwd(),".env");if(n.existsSync(e))console.log(".env already exists");else{let s=t.slice(1),i="";if(s.length>0){let o=s.filter(c=>c.includes("="));i=o.join(`
2
+ `)+(o.length>0?`
3
+ `:"")}n.writeFileSync(e,i),console.log(i?"Created .env with specified fields":"Created empty .env")}break}case"cfj":case"create-from-json":{let e=t[1];e||(console.error("Please provide a JSON file"),process.exit(1)),n.existsSync(e)||(console.error("JSON file not found"),process.exit(1));let s=t.indexOf("--env"),o=`.env${s!==-1&&t[s+1]?`.${t[s+1]}`:""}`;if(n.existsSync(o)){console.log(`${o} already exists`);break}let c=JSON.parse(n.readFileSync(e,"utf-8")),f="";for(let l in c)f+=`${l}=${c[l]}
4
+ `;n.writeFileSync(o,f),console.log(`Created ${o} from JSON`);break}case"s":case"split":{let e=t.indexOf("--env");(e===-1||!t[e+1])&&(console.error("Please specify environment with --env <dev|prod>"),process.exit(1));let s=t[e+1],i=d.join(process.cwd(),".env");n.existsSync(i)||(console.error(".env file not found"),process.exit(1));let c=n.readFileSync(i,"utf-8").split(/\r?\n/).filter(l=>l.trim()!==""&&!l.startsWith("#")).map(l=>l.split("=")[0]+"=").join(`
5
+ `),f=d.join(process.cwd(),`.env.${s}`);if(n.existsSync(f)){console.log(`.env.${s} already exists`);break}n.writeFileSync(f,c),console.log(`Created .env.${s} with keys only`);break}case"d":case"delete":{let e=t[1]||".env",s=d.join(process.cwd(),e);n.existsSync(s)?(n.unlinkSync(s),console.log(`Deleted ${e}`)):console.log(`File ${e} does not exist`);break}case"srt":case"sort":{let e=t[1]||".env",s=d.join(process.cwd(),e);n.existsSync(s)||(console.error(`File ${e} does not exist`),process.exit(1));let i=n.readFileSync(s,"utf-8").split(/\r?\n/),o=i[i.length-1]===""?i.slice(0,-1):i,c=o.filter(a=>!a.startsWith("#")&&a.trim()!==""&&a.includes("=")).sort((a,m)=>a.localeCompare(m)),f=0,l=o.map(a=>!a.startsWith("#")&&a.trim()!==""&&a.includes("=")?c[f++]:a);n.writeFileSync(s,l.join(`
6
6
  `)+`
7
- `),console.log(`Sorted keys in ${e}`);break}default:console.error(`Unknown command: "${d}"
8
- `),p(),process.exit(1)}
7
+ `),console.log(`Sorted keys in ${e}`);break}case"gc":case"generate-constants":{let e=t.indexOf("--out"),s=e!==-1&&t[e+1]?t[e+1]:"envConstants.js",o=(e!==-1?t.filter((r,p)=>p!==e&&p!==e+1):t)[1]||".env",c=d.join(process.cwd(),o);if(!n.existsSync(c)){let p=n.readdirSync(process.cwd()).filter(v=>v.startsWith(".env")&&!v.endsWith(".example"));p.length>0?(o=p[0],c=d.join(process.cwd(),o),console.log(`File ${t[1]||".env"} not found. Using ${o} instead.`)):(console.error(`File ${o} does not exist and no fallback .env* files were found`),process.exit(1))}let l=n.readFileSync(c,"utf-8").split(/\r?\n/).filter(r=>!r.startsWith("#")&&r.trim()!==""&&r.includes("=")).map(r=>r.split("=")[0].trim());if(l.length===0){console.log(`No variables found in ${o}`);break}let m=`export const ENV = {
8
+ ${l.map(r=>` ${r}: process.env.${r},`).join(`
9
+ `)}
10
+ };
11
+ `,y=d.join(process.cwd(),s);if(n.existsSync(y)){let r=u.createInterface({input:process.stdin,output:process.stdout});r.question(`File ${s} already exists. Overwrite? (y/n) `,p=>{let v=p.trim().toLowerCase();v==="y"||v==="yes"?(n.writeFileSync(y,m),console.log(`Overwrote ${s} from ${o}`)):console.log("Action cancelled. File was not overwritten."),r.close()})}else n.writeFileSync(y,m),console.log(`Generated ${s} from ${o}`);break}default:console.error(`Unknown command: "${g}"
12
+ `),h(),process.exit(1)}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "env-creator",
3
- "version": "1.0.0",
4
- "description": "Environment variable generator CLI",
3
+ "version": "1.1.0",
4
+ "description": "A fast, lightweight CLI tool for managing and generating custom environment (`.env`) files",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "env-creator": "./dist/cli.js",
8
- "create-env": "./dist/cli.js"
8
+ "env": "./dist/cli.js"
9
9
  },
10
10
  "exports": {
11
11
  ".": "./dist/index.js"
@@ -16,17 +16,15 @@
16
16
  "engines": {
17
17
  "node": ">=20"
18
18
  },
19
- "scripts": {
20
- "lint": "eslint .",
21
- "build": "esbuild src/index.js --bundle --platform=node --format=esm --target=node20 --minify --outfile=dist/index.js && printf '#!/usr/bin/env node\nimport(\"./index.js\");\n' > dist/cli.js && chmod +x dist/cli.js",
22
- "prepublishOnly": "npm run lint && npm run build",
23
- "release": "npm version patch && npm publish"
24
- },
25
19
  "keywords": [
26
20
  "env",
21
+ ".env",
27
22
  "dotenv",
28
- "cli",
29
23
  "environment",
24
+ "variables",
25
+ "node",
26
+ "custom",
27
+ "cli",
30
28
  "generator"
31
29
  ],
32
30
  "author": "Kyrylo Voronoi",
@@ -41,5 +39,11 @@
41
39
  "esbuild": "^0.27.3",
42
40
  "eslint": "^10.0.3",
43
41
  "globals": "^17.4.0"
42
+ },
43
+ "scripts": {
44
+ "lint": "eslint .",
45
+ "build": "esbuild src/index.js --bundle --platform=node --format=esm --target=node20 --minify --outfile=dist/index.js && printf '#!/usr/bin/env node\nimport(\"./index.js\");\n' > dist/cli.js && chmod +x dist/cli.js",
46
+ "build:pack": "pnpm run build && pnpm pack",
47
+ "release": "pnpm version patch && pnpm publish"
44
48
  }
45
49
  }