veylix-cli 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/LICENSE +21 -0
- package/README.md +217 -0
- package/package.json +26 -3
- package/veylix.mjs +8 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Veylix
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# veylix-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/veylix-cli)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](https://www.npmjs.com/package/veylix-cli?activeTab=dependencies)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
The official command-line tool for **[Veylix](https://veylix-omega.vercel.app)**. It pulls your environment variables into local development, shell sessions and CI/CD pipelines, so you don't have to copy `.env` files around.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g veylix-cli
|
|
12
|
+
veylix login --token vlx_…
|
|
13
|
+
veylix link
|
|
14
|
+
veylix run -- npm run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- **No `.env` files on disk.** `veylix run` puts variables straight into your process.
|
|
18
|
+
- **One token for every project.** Choose the project and environment per folder.
|
|
19
|
+
- **CI-ready.** Configure everything through environment variables, with no interactive prompts.
|
|
20
|
+
- **Zero dependencies.** A single ESM file on Node 18+, so it installs in about a second and is easy to audit.
|
|
21
|
+
- **Secure defaults.** The config file is written with `0600` permissions, and secrets go to stdout only when you ask for them.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g veylix-cli # or: pnpm add -g veylix-cli / yarn global add veylix-cli
|
|
29
|
+
veylix --version
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
To run it once without installing:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx veylix-cli pull
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Requires **Node.js 18 or newer**.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
**1. Create an API token.** Sign in at **[veylix-omega.vercel.app](https://veylix-omega.vercel.app)** and go to **Settings → API tokens**. A token can cover all your projects or only one, can be read-only or read-write, and can expire.
|
|
43
|
+
|
|
44
|
+
**2. Log in.**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
veylix login --token vlx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
✓ Logged in to https://veylix-omega.vercel.app as you@company.com: all projects (3), read-write
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**3. Link a folder to a project and environment.**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cd my-app
|
|
58
|
+
veylix link
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
Which project?
|
|
63
|
+
1 api (3 environments)
|
|
64
|
+
2 web (2 environments)
|
|
65
|
+
Choose 1-2: 1
|
|
66
|
+
Which environment of api?
|
|
67
|
+
1 development (12 variables)
|
|
68
|
+
2 staging (14 variables)
|
|
69
|
+
3 production (14 variables)
|
|
70
|
+
Choose 1-3: 1
|
|
71
|
+
✓ Linked this folder to api › development (.veylix.json)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**4. Use your variables.**
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
veylix run -- npm run dev # inject into a process
|
|
78
|
+
veylix pull > .env # or write a .env file
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Commands
|
|
82
|
+
|
|
83
|
+
| Command | Description |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `veylix login --token <vlx_…> [--url <server>]` | Save your token (and server) after checking it with the API |
|
|
86
|
+
| `veylix logout` | Remove the saved token |
|
|
87
|
+
| `veylix whoami` | Show the account, token scope, server and linked project |
|
|
88
|
+
| `veylix projects` | List projects, environments and variable counts |
|
|
89
|
+
| `veylix link [--project <name>] [--env <name>]` | Link the current folder (writes `.veylix.json`) |
|
|
90
|
+
| `veylix unlink` | Remove the folder link |
|
|
91
|
+
| `veylix envs` | List the environments of the current project |
|
|
92
|
+
| `veylix pull [--format dotenv\|json\|shell] [--output <file>]` | Print or save variables |
|
|
93
|
+
| `veylix run -- <command> [args…]` | Run a command with the variables injected |
|
|
94
|
+
| `veylix push [--file .env] [--replace]` | Upload a `.env` file (needs a read-write token) |
|
|
95
|
+
| `veylix set KEY=value [KEY2=value…]` | Create or update variables |
|
|
96
|
+
| `veylix unset KEY` | Delete a variable |
|
|
97
|
+
| `veylix help` / `veylix --version` | Show help or the version |
|
|
98
|
+
|
|
99
|
+
Every command accepts `--project <name|id>` and `--env <name>` to override the folder link.
|
|
100
|
+
|
|
101
|
+
### Examples
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Run against another environment for a single command
|
|
105
|
+
veylix run --env staging -- npm start
|
|
106
|
+
|
|
107
|
+
# Export as JSON for tooling
|
|
108
|
+
veylix pull --project api --env production --format json
|
|
109
|
+
|
|
110
|
+
# Load into the current shell session
|
|
111
|
+
eval "$(veylix pull --format shell)"
|
|
112
|
+
|
|
113
|
+
# Write a file with 0600 permissions
|
|
114
|
+
veylix pull --output .env.local
|
|
115
|
+
|
|
116
|
+
# Sync a local .env up to Veylix; --replace also deletes keys missing from the file
|
|
117
|
+
veylix push --file .env.production --env production --replace
|
|
118
|
+
|
|
119
|
+
# Quick edits
|
|
120
|
+
veylix set STRIPE_KEY=sk_live_… FEATURE_FLAG=true
|
|
121
|
+
veylix unset LEGACY_API_URL
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
Settings are resolved in this order (first match wins):
|
|
127
|
+
|
|
128
|
+
| Setting | 1. Flag | 2. Environment variable | 3. Saved |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| Token | `--token` | `VEYLIX_TOKEN` | `~/.config/veylix/config.json` |
|
|
131
|
+
| Server URL | `--url` | `VEYLIX_URL` | `~/.config/veylix/config.json`, then `https://veylix-omega.vercel.app` |
|
|
132
|
+
| Project | `--project` | `VEYLIX_PROJECT` | nearest `.veylix.json` |
|
|
133
|
+
| Environment | `--env` | `VEYLIX_ENV` | nearest `.veylix.json` |
|
|
134
|
+
|
|
135
|
+
- **`~/.config/veylix/config.json`** holds your token. It is created with mode `0600` and respects `XDG_CONFIG_HOME`.
|
|
136
|
+
- **`.veylix.json`** holds only the project and environment names, never secrets. **Commit it**, so everyone on the team pulls the same environment. The CLI looks for it in the current folder and every parent folder, so it works in monorepos.
|
|
137
|
+
- You can leave out the project or environment when it's unambiguous, for example when the token can reach only one project.
|
|
138
|
+
|
|
139
|
+
### Self-hosted Veylix
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
veylix login --url https://veylix.your-company.com --token vlx_…
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## CI/CD
|
|
146
|
+
|
|
147
|
+
The CLI needs no login step in CI. Pass everything as environment variables:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
VEYLIX_TOKEN=vlx_… VEYLIX_PROJECT=api VEYLIX_ENV=production \
|
|
151
|
+
npx veylix-cli run -- node server.js
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
<details>
|
|
155
|
+
<summary><b>GitHub Actions</b></summary>
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
- name: Deploy
|
|
159
|
+
env:
|
|
160
|
+
VEYLIX_TOKEN: ${{ secrets.VEYLIX_TOKEN }}
|
|
161
|
+
VEYLIX_PROJECT: api
|
|
162
|
+
VEYLIX_ENV: production
|
|
163
|
+
run: npx veylix-cli run -- npm run deploy
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
</details>
|
|
167
|
+
|
|
168
|
+
<details>
|
|
169
|
+
<summary><b>GitLab CI</b></summary>
|
|
170
|
+
|
|
171
|
+
```yaml
|
|
172
|
+
deploy:
|
|
173
|
+
image: node:20
|
|
174
|
+
variables:
|
|
175
|
+
VEYLIX_PROJECT: api
|
|
176
|
+
VEYLIX_ENV: production
|
|
177
|
+
script:
|
|
178
|
+
- npx veylix-cli run -- npm run deploy # VEYLIX_TOKEN set as a masked CI/CD variable
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
</details>
|
|
182
|
+
|
|
183
|
+
<details>
|
|
184
|
+
<summary><b>Docker</b></summary>
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
veylix pull --env production --output .env.production
|
|
188
|
+
docker run --env-file .env.production my-image
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
For CI, use a **read-only token scoped to one project**, and set an expiry.
|
|
194
|
+
|
|
195
|
+
## Security
|
|
196
|
+
|
|
197
|
+
- Tokens are sent only to your Veylix server, in the `Authorization` header (HTTPS on the hosted service).
|
|
198
|
+
- The server looks tokens up by SHA-256 hash and keeps them encrypted at rest. You can revoke, regenerate and expire them in **Settings → API tokens**.
|
|
199
|
+
- `veylix run` keeps secrets in the child process's memory only. Nothing is written to disk.
|
|
200
|
+
- `pull --output` creates files with mode `0600`. Add `.env*` to your `.gitignore`.
|
|
201
|
+
- Read-only tokens can't change anything, even if they leak.
|
|
202
|
+
|
|
203
|
+
## Troubleshooting
|
|
204
|
+
|
|
205
|
+
| Message | Fix |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `Not logged in` | Run `veylix login --token …` or set `VEYLIX_TOKEN` |
|
|
208
|
+
| `Can't reach Veylix at …` | Check `--url` / `VEYLIX_URL` and your network |
|
|
209
|
+
| `Which project? Pass it as a flag` | Run `veylix link`, or pass `--project` / set `VEYLIX_PROJECT` in CI |
|
|
210
|
+
| `[HTTP 401]` | The token is invalid, revoked or expired. Create a new one |
|
|
211
|
+
| `[HTTP 403]` | The token is read-only. Use a read-write token for `push`, `set` and `unset` |
|
|
212
|
+
| `[HTTP 404]` | The project or environment doesn't exist or isn't covered by the token. Run `veylix projects` |
|
|
213
|
+
| `[HTTP 429]` | Rate limited. Wait a moment and retry |
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
[MIT](./LICENSE) © Veylix
|
package/package.json
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "veylix-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Veylix CLI: pull, inject and sync environment variables from Veylix into your apps, shells and CI pipelines. Zero dependencies.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"veylix",
|
|
7
|
+
"env",
|
|
8
|
+
"dotenv",
|
|
9
|
+
"environment-variables",
|
|
10
|
+
"secrets",
|
|
11
|
+
"secrets-management",
|
|
12
|
+
"config",
|
|
13
|
+
"cli",
|
|
14
|
+
"ci",
|
|
15
|
+
"devops"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://veylix-omega.vercel.app",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/Dhamodharan-coder/veylix.git",
|
|
21
|
+
"directory": "cli"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/Dhamodharan-coder/veylix/issues"
|
|
25
|
+
},
|
|
5
26
|
"type": "module",
|
|
6
27
|
"bin": {
|
|
7
28
|
"veylix": "veylix.mjs"
|
|
8
29
|
},
|
|
9
30
|
"files": [
|
|
10
|
-
"veylix.mjs"
|
|
31
|
+
"veylix.mjs",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
11
34
|
],
|
|
12
35
|
"engines": {
|
|
13
36
|
"node": ">=18"
|
package/veylix.mjs
CHANGED
|
@@ -8,7 +8,8 @@ import { homedir } from "node:os";
|
|
|
8
8
|
import { dirname, join, relative } from "node:path";
|
|
9
9
|
import { createInterface } from "node:readline/promises";
|
|
10
10
|
|
|
11
|
-
const VERSION = "1.
|
|
11
|
+
const VERSION = "1.2.0";
|
|
12
|
+
const DEFAULT_URL = "https://veylix-omega.vercel.app";
|
|
12
13
|
const CONFIG_PATH = join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "veylix", "config.json");
|
|
13
14
|
// Per-folder project/environment choice (no secrets, safe to commit).
|
|
14
15
|
const LINK_FILE = ".veylix.json";
|
|
@@ -16,7 +17,7 @@ const LINK_FILE = ".veylix.json";
|
|
|
16
17
|
const HELP = `veylix ${VERSION}: environment variables from Veylix
|
|
17
18
|
|
|
18
19
|
Usage:
|
|
19
|
-
veylix login --token <vlx_…> [--url <
|
|
20
|
+
veylix login --token <vlx_…> [--url <server>] Server defaults to ${DEFAULT_URL}
|
|
20
21
|
veylix logout
|
|
21
22
|
veylix whoami Show your account, token access and linked project
|
|
22
23
|
veylix projects List projects and environments you can use
|
|
@@ -42,7 +43,9 @@ Examples:
|
|
|
42
43
|
veylix pull > .env
|
|
43
44
|
veylix run --env staging -- npm start
|
|
44
45
|
veylix pull --project api --env production --format json
|
|
45
|
-
VEYLIX_TOKEN=vlx_… VEYLIX_PROJECT=api VEYLIX_ENV=production veylix run -- node server.js # CI
|
|
46
|
+
VEYLIX_TOKEN=vlx_… VEYLIX_PROJECT=api VEYLIX_ENV=production veylix run -- node server.js # CI
|
|
47
|
+
|
|
48
|
+
Create a token at ${DEFAULT_URL}/settings`;
|
|
46
49
|
|
|
47
50
|
// ---------- args ----------
|
|
48
51
|
|
|
@@ -85,7 +88,7 @@ function writeConfig(config) {
|
|
|
85
88
|
|
|
86
89
|
function settings(flags) {
|
|
87
90
|
const config = readConfig();
|
|
88
|
-
const url = String(flags.url || process.env.VEYLIX_URL || config.url ||
|
|
91
|
+
const url = String(flags.url || process.env.VEYLIX_URL || config.url || DEFAULT_URL).replace(/\/$/, "");
|
|
89
92
|
const token = flags.token || process.env.VEYLIX_TOKEN || config.token;
|
|
90
93
|
if (!token) fail("Not logged in. Run `veylix login --token vlx_…` or set VEYLIX_TOKEN.");
|
|
91
94
|
return { url, token: String(token) };
|
|
@@ -215,7 +218,7 @@ function fail(msg) {
|
|
|
215
218
|
const commands = {
|
|
216
219
|
async login(_, flags) {
|
|
217
220
|
if (!flags.token || flags.token === true) fail("Usage: veylix login --token vlx_… [--url https://your-veylix]");
|
|
218
|
-
const config = { url: String(flags.url || readConfig().url ||
|
|
221
|
+
const config = { url: String(flags.url || readConfig().url || DEFAULT_URL).replace(/\/$/, ""), token: String(flags.token) };
|
|
219
222
|
const me = await fetchMe({ ...flags, ...config });
|
|
220
223
|
writeConfig(config);
|
|
221
224
|
const scope = me.scope === "all-projects" ? `all projects (${me.projects.length})` : `project ${c(1, me.projects[0]?.name)}`;
|