@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 +7 -0
- package/package.json +2 -1
- package/src/commands/deploy.js +27 -5
- package/src/commands/login.js +24 -0
- package/src/commands/pull.js +2 -2
- package/.env +0 -20
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.
|
|
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",
|
package/src/commands/deploy.js
CHANGED
|
@@ -23,10 +23,32 @@ export async function deploy(options) {
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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}/
|
|
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(
|
|
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)));
|
package/src/commands/login.js
CHANGED
|
@@ -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));
|
package/src/commands/pull.js
CHANGED
|
@@ -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}/
|
|
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(
|
|
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
|