@dinanathdash/envault 1.1.0 → 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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.2.0](https://github.com/DinanathDash/Envault/compare/v1.1.0...v1.2.0) (2026-02-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * Improve CLI login with clipboard support and user email display, enhance `.env` file detection for deploy, and add a `/api/cli/me` endpoint. ([f66aa4a](https://github.com/DinanathDash/Envault/commit/f66aa4a028242d4939fdedcd4165b2bba2a5e290))
7
+
1
8
  # [1.1.0](https://github.com/DinanathDash/Envault/compare/v1.0.2...v1.1.0) (2026-02-01)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dinanathdash/envault",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Envault CLI - Securely manage your environment variables",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,6 +25,7 @@
25
25
  "axios": "^1.6.0",
26
26
  "boxen": "^7.1.1",
27
27
  "chalk": "^5.3.0",
28
+ "clipboardy": "^5.1.0",
28
29
  "commander": "^11.1.0",
29
30
  "conf": "^12.0.0",
30
31
  "dotenv": "^16.3.1",
@@ -23,10 +23,32 @@ export async function deploy(options) {
23
23
  return;
24
24
  }
25
25
 
26
- const envPath = '.env';
27
- if (!fs.existsSync(envPath)) {
28
- console.error(chalk.red('Error: .env file not found.'));
26
+ // 1. Scan for env files
27
+ const allFiles = fs.readdirSync(process.cwd());
28
+ const envFiles = allFiles.filter(file => file.startsWith('.env') && !['.env.example', '.env.template', '.env.sample'].includes(file));
29
+
30
+ let envPath = '.env';
31
+
32
+ if (envFiles.length === 0) {
33
+ console.error(chalk.red('Error: No .env files found (looked for files starting with .env, excluding .example/.template/.sample).'));
29
34
  return;
35
+ } else if (envFiles.length === 1) {
36
+ envPath = envFiles[0];
37
+ console.log(chalk.blue(`Using environment file: ${envPath}`));
38
+ } else {
39
+ // prioritize .env.local if users want, but for now let's ask
40
+ // OR we can default to .env.local if present, else asking.
41
+ // The plan said "Multiple files found: Use inquirer to show a list"
42
+
43
+ console.log(chalk.yellow(`Multiple environment files found: ${envFiles.join(', ')}`));
44
+ const { selectedEnv } = await inquirer.prompt([{
45
+ type: 'list',
46
+ name: 'selectedEnv',
47
+ message: 'Which environment file do you want to deploy?',
48
+ choices: envFiles
49
+ }]);
50
+ envPath = selectedEnv;
51
+ console.log(chalk.blue(`Selected: ${envPath}`));
30
52
  }
31
53
 
32
54
  const envConfig = dotenv.parse(fs.readFileSync(envPath));
@@ -71,7 +93,7 @@ export async function deploy(options) {
71
93
  '\n\n' +
72
94
  chalk.dim('We recommend checking the dashboard for differences:') +
73
95
  '\n' +
74
- chalk.cyan(`${appUrl}/projects/${projectId}`),
96
+ chalk.cyan(`${appUrl}/project/${projectId}`),
75
97
  {
76
98
  padding: 1,
77
99
  margin: 1,
@@ -98,7 +120,7 @@ export async function deploy(options) {
98
120
 
99
121
  try {
100
122
  const { data } = await api.post(`/projects/${projectId}/secrets`, { secrets });
101
- spinner.succeed(chalk.green(`✔ Successfully deployed ${secrets.length} secrets!`));
123
+ spinner.succeed(chalk.green(`Successfully deployed ${secrets.length} secrets!`));
102
124
  } catch (error) {
103
125
  spinner.fail('Deploy failed.');
104
126
  console.error(chalk.red(handleApiError(error)));
@@ -3,6 +3,7 @@ import chalk from 'chalk';
3
3
  import boxen from 'boxen';
4
4
  import ora from 'ora';
5
5
  import open from 'open';
6
+ import clipboard from 'clipboardy';
6
7
  import { api, handleApiError } from '../lib/api.js';
7
8
  import { setToken } from '../lib/config.js';
8
9
  import os from 'os';
@@ -41,12 +42,20 @@ export async function login() {
41
42
  console.log(boxen(chalk.green.bold(userCode), {
42
43
  title: 'Authentication Code',
43
44
  titleAlignment: 'center',
45
+ textAlignment: 'center',
44
46
  padding: 1,
45
47
  margin: 1,
46
48
  borderStyle: 'round',
47
49
  borderColor: 'green'
48
50
  }));
49
51
 
52
+ try {
53
+ clipboard.writeSync(userCode);
54
+ console.log(chalk.dim('(Code copied to clipboard)'));
55
+ } catch (e) {
56
+ // Ignore errors if clipboard fails (headless etc)
57
+ }
58
+
50
59
  // Open browser automatically
51
60
  try {
52
61
  await open(verificationUri);
@@ -87,7 +96,22 @@ export async function login() {
87
96
  try {
88
97
  const token = await poll();
89
98
  setToken(token);
99
+
100
+ // Fetch user info
101
+ let email = '';
102
+ try {
103
+ const { data: userData } = await api.get('/me');
104
+ if (userData && userData.email) {
105
+ email = userData.email;
106
+ }
107
+ } catch (e) {
108
+ // Ignore error if fetching user info fails, just show generic success
109
+ }
110
+
90
111
  spinner.succeed(chalk.green('Successfully authenticated! Token saved.'));
112
+ if (email) {
113
+ console.log(chalk.green(`Logged in as: ${chalk.bold(email)}`));
114
+ }
91
115
  } catch (error) {
92
116
  spinner.fail('Authentication failed.');
93
117
  console.error(chalk.red(error.message));
@@ -47,7 +47,7 @@ export async function pull(options) {
47
47
  '\n\n' +
48
48
  chalk.dim('We recommend checking the dashboard for differences:') +
49
49
  '\n' +
50
- chalk.cyan(`${appUrl}/projects/${projectId}`),
50
+ chalk.cyan(`${appUrl}/project/${projectId}`),
51
51
  {
52
52
  padding: 1,
53
53
  margin: 1,
@@ -86,7 +86,7 @@ export async function pull(options) {
86
86
  .join('\n');
87
87
 
88
88
  fs.writeFileSync('.env', envContent);
89
- spinner.succeed(chalk.green(`✔ Pulled ${data.secrets.length} secrets to .env`));
89
+ spinner.succeed(chalk.green(`Pulled ${data.secrets.length} secrets to .env`));
90
90
 
91
91
  } catch (error) {
92
92
  spinner.fail('Pull failed.');
package/.env DELETED
@@ -1,20 +0,0 @@
1
- # Environment Variables Example
2
-
3
- Copy this file to `.env.local` and fill in your values.
4
-
5
- ## Supabase Configuration
6
- NEXT_PUBLIC_SUPABASE_URL=your_supabase_url_here
7
- NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key_here
8
-
9
- ## Encryption Key (Required)
10
- # Generate a new key with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
11
- # IMPORTANT: Keep this secret and never commit it to version control
12
- # If you lose this key, all encrypted data becomes unrecoverable
13
- ENCRYPTION_KEY=your_64_character_hex_encryption_key_here
14
-
15
- ## Supabase Service Role Key (Required)
16
- SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here
17
-
18
- # Redis (Upstash)
19
- UPSTASH_REDIS_REST_URL=your_upstash_redis_rest_url_here
20
- UPSTASH_REDIS_REST_TOKEN=your_upstash_redis_rest_token_here