env-creator 1.1.1 → 1.2.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 CHANGED
@@ -146,31 +146,59 @@ pnpx env-creator delete .env.production # Deletes .env.production
146
146
 
147
147
  ### 5. Sort `.env` keys alphabetically (alias: `srt`)
148
148
 
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.
149
+ Reads an environment file and reorders all `KEY=VALUE` lines alphabetically. By default, it operates in a **flat sort mode**, meaning it binds each comment or empty line to the closest variable immediately below it, and sorts these blocks of keys.
150
+
151
+ If you prefer to strictly preserve the exact file layout and structure, use the `--groups` (or `-g`) flag, which performs **intra-group sorting** that alphabetizes variables tightly inside their original continuous groups. Defaults to `.env` if no file is specified.
150
152
 
151
153
  ```bash
152
- pnpx env-creator sort [file]
154
+ pnpx env-creator sort [--groups] [file]
153
155
  ```
154
156
 
155
157
  **Examples:**
156
158
  ```bash
157
- pnpx env-creator sort # Sorts .env
158
- pnpx env-creator sort .env.production # Sorts .env.production
159
+ pnpx env-creator sort # Flat sorts .env
160
+ pnpx env-creator sort -g .env.production # Group-sorts .env.production
159
161
  ```
160
162
 
163
+ **Example 1: Flat Sort (Default)**
164
+
161
165
  **Before:**
162
166
  ```env
163
- # App config
167
+ DB_USER=admin
168
+ DB_PASS=secret
164
169
  PORT=3000
165
170
  APP_NAME=my-app
166
- DB_HOST=localhost
167
171
  ```
168
172
 
169
- **After:**
173
+ **After (`env-creator sort`):**
170
174
  ```env
171
- # App config
172
175
  APP_NAME=my-app
173
- DB_HOST=localhost
176
+ DB_PASS=secret
177
+ DB_USER=admin
178
+ PORT=3000
179
+ ```
180
+
181
+ **Example 2: Intra-Group Sort (`--groups`)**
182
+
183
+ **Before:**
184
+ ```env
185
+ # DB Config
186
+ DB_USER=admin
187
+ DB_PASS=secret
188
+
189
+ # App
190
+ PORT=3000
191
+ APP_NAME=my-app
192
+ ```
193
+
194
+ **After (`env-creator sort -g`):**
195
+ ```env
196
+ # DB Config
197
+ DB_PASS=secret
198
+ DB_USER=admin
199
+
200
+ # App
201
+ APP_NAME=my-app
174
202
  PORT=3000
175
203
  ```
176
204
 
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
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(`
1
+ import n from"fs";import v from"path";import y from"readline";var t=process.argv.slice(2);t.length===0&&(u(),process.exit(0));function u(){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 [-g/--groups] [file] Sort keys alphabetically (default: .env). Use -g to sort inside existing groups."),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 m=t[0];(m==="--help"||m==="-h"||m==="help")&&(u(),process.exit(0));switch(m){case"c":case"create":{let s=v.join(process.cwd(),".env");if(n.existsSync(s))console.log(".env already exists");else{let i=t.slice(1),p="";if(i.length>0){let o=i.filter(f=>f.includes("="));p=o.join(`
2
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(`
3
+ `:"")}n.writeFileSync(s,p),console.log(p?"Created .env with specified fields":"Created empty .env")}break}case"cfj":case"create-from-json":{let s=t[1];s||(console.error("Please provide a JSON file"),process.exit(1)),n.existsSync(s)||(console.error("JSON file not found"),process.exit(1));let i=t.indexOf("--env"),o=`.env${i!==-1&&t[i+1]?`.${t[i+1]}`:""}`;if(n.existsSync(o)){console.log(`${o} already exists`);break}let f=JSON.parse(n.readFileSync(s,"utf-8")),d="";for(let e in f)d+=`${e}=${f[e]}
4
+ `;n.writeFileSync(o,d),console.log(`Created ${o} from JSON`);break}case"s":case"split":{let s=t.indexOf("--env");(s===-1||!t[s+1])&&(console.error("Please specify environment with --env <dev|prod>"),process.exit(1));let i=t[s+1],p=v.join(process.cwd(),".env");n.existsSync(p)||(console.error(".env file not found"),process.exit(1));let f=n.readFileSync(p,"utf-8").split(/\r?\n/).filter(e=>e.trim()!==""&&!e.startsWith("#")).map(e=>e.split("=")[0]+"=").join(`
5
+ `),d=v.join(process.cwd(),`.env.${i}`);if(n.existsSync(d)){console.log(`.env.${i} already exists`);break}n.writeFileSync(d,f),console.log(`Created .env.${i} with keys only`);break}case"d":case"delete":{let s=t[1]||".env",i=v.join(process.cwd(),s);n.existsSync(i)?(n.unlinkSync(i),console.log(`Deleted ${s}`)):console.log(`File ${s} does not exist`);break}case"srt":case"sort":{let s=t.includes("--groups")||t.includes("-g"),p=t.slice(1).find(a=>a!=="--groups"&&a!=="-g")||".env",o=v.join(process.cwd(),p);n.existsSync(o)||(console.error(`File ${p} does not exist`),process.exit(1));let f=n.readFileSync(o,"utf-8").split(/\r?\n/),d=f[f.length-1]===""?f.slice(0,-1):f,e=[];if(s){let a=[];for(let c of d)if(!c.startsWith("#")&&c.trim()!==""&&c.includes("="))a.push(c);else{if(a.length>0&&(a.sort((l,g)=>l.split("=")[0].trim().localeCompare(g.split("=")[0].trim())),e.push(...a),a=[],c.trim()!==""&&e.push("")),c.trim()===""&&e.length>0&&e[e.length-1].trim()==="")continue;e.push(c)}for(a.length>0&&(a.sort((c,r)=>c.split("=")[0].trim().localeCompare(r.split("=")[0].trim())),e.push(...a));e.length>0&&e[e.length-1].trim()==="";)e.pop()}else{let a=[],c=[];for(let r of d)!r.startsWith("#")&&r.trim()!==""&&r.includes("=")?(a.push({header:c,entry:r,key:r.split("=")[0].trim()}),c=[]):r.trim()!==""&&c.push(r);a.sort((r,l)=>r.key.localeCompare(l.key));for(let r of a)e.push(...r.header),e.push(r.entry);e.push(...c)}n.writeFileSync(o,e.join(`
6
6
  `)+`
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(`
7
+ `),console.log(`Sorted keys in ${p}`);break}case"gc":case"generate-constants":{let s=t.indexOf("--out"),i=s!==-1&&t[s+1]?t[s+1]:"envConstants.js",o=(s!==-1?t.filter((l,g)=>g!==s&&g!==s+1):t)[1]||".env",f=v.join(process.cwd(),o);if(!n.existsSync(f)){let g=n.readdirSync(process.cwd()).filter(h=>h.startsWith(".env")&&!h.endsWith(".example"));g.length>0?(o=g[0],f=v.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 e=n.readFileSync(f,"utf-8").split(/\r?\n/).filter(l=>!l.startsWith("#")&&l.trim()!==""&&l.includes("=")).map(l=>l.split("=")[0].trim());if(e.length===0){console.log(`No variables found in ${o}`);break}let c=`export const ENV = {
8
+ ${e.map(l=>` ${l}: process.env.${l},`).join(`
9
9
  `)}
10
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)}
11
+ `,r=v.join(process.cwd(),i);if(n.existsSync(r)){let l=y.createInterface({input:process.stdin,output:process.stdout});l.question(`File ${i} already exists. Overwrite? (y/n) `,g=>{let h=g.trim().toLowerCase();h==="y"||h==="yes"?(n.writeFileSync(r,c),console.log(`Overwrote ${i} from ${o}`)):console.log("Action cancelled. File was not overwritten."),l.close()})}else n.writeFileSync(r,c),console.log(`Generated ${i} from ${o}`);break}default:console.error(`Unknown command: "${m}"
12
+ `),u(),process.exit(1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "env-creator",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "A fast, lightweight CLI tool for managing and generating custom environment (`.env`) files",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,6 +44,9 @@
44
44
  "lint": "eslint .",
45
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
46
  "build:pack": "pnpm run build && pnpm pack",
47
- "release": "pnpm version patch && pnpm publish"
47
+ "version:patch": "pnpm version patch",
48
+ "version:minor": "pnpm version minor",
49
+ "version:major": "pnpm version major",
50
+ "publish:npm": "pnpm publish"
48
51
  }
49
52
  }