@relesio/cli 0.2.6
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 +224 -0
- package/bin/relesio.js +4 -0
- package/dist/commands/auth/index.d.ts +2 -0
- package/dist/commands/auth/index.js +9 -0
- package/dist/commands/auth/login.d.ts +2 -0
- package/dist/commands/auth/login.js +82 -0
- package/dist/commands/auth/logout.d.ts +2 -0
- package/dist/commands/auth/logout.js +25 -0
- package/dist/commands/auth/status.d.ts +2 -0
- package/dist/commands/auth/status.js +35 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.js +293 -0
- package/dist/commands/organizations/index.d.ts +2 -0
- package/dist/commands/organizations/index.js +8 -0
- package/dist/commands/organizations/list.d.ts +2 -0
- package/dist/commands/organizations/list.js +54 -0
- package/dist/commands/organizations/set.d.ts +2 -0
- package/dist/commands/organizations/set.js +34 -0
- package/dist/commands/projects/index.d.ts +2 -0
- package/dist/commands/projects/index.js +6 -0
- package/dist/commands/projects/list.d.ts +2 -0
- package/dist/commands/projects/list.js +49 -0
- package/dist/commands/rollback.d.ts +2 -0
- package/dist/commands/rollback.js +119 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +59 -0
- package/dist/commands/team/get.d.ts +2 -0
- package/dist/commands/team/get.js +34 -0
- package/dist/commands/team/index.d.ts +2 -0
- package/dist/commands/team/index.js +7 -0
- package/dist/commands/team/list.d.ts +2 -0
- package/dist/commands/team/list.js +46 -0
- package/dist/commands/upload.d.ts +2 -0
- package/dist/commands/upload.js +365 -0
- package/dist/commands/versions/index.d.ts +2 -0
- package/dist/commands/versions/index.js +6 -0
- package/dist/commands/versions/list.d.ts +2 -0
- package/dist/commands/versions/list.js +51 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +52 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +90 -0
- package/dist/lib/api/client.d.ts +32 -0
- package/dist/lib/api/client.js +187 -0
- package/dist/lib/api/deployments.d.ts +122 -0
- package/dist/lib/api/deployments.js +55 -0
- package/dist/lib/api/organizations.d.ts +27 -0
- package/dist/lib/api/organizations.js +37 -0
- package/dist/lib/api/projects.d.ts +38 -0
- package/dist/lib/api/projects.js +34 -0
- package/dist/lib/api/teams.d.ts +15 -0
- package/dist/lib/api/teams.js +44 -0
- package/dist/lib/api/types.d.ts +89 -0
- package/dist/lib/api/types.js +2 -0
- package/dist/lib/api/versions.d.ts +140 -0
- package/dist/lib/api/versions.js +53 -0
- package/dist/lib/config/manager.d.ts +35 -0
- package/dist/lib/config/manager.js +78 -0
- package/dist/lib/config/types.d.ts +15 -0
- package/dist/lib/config/types.js +15 -0
- package/dist/lib/errors/handler.d.ts +1 -0
- package/dist/lib/errors/handler.js +75 -0
- package/dist/lib/errors/types.d.ts +19 -0
- package/dist/lib/errors/types.js +34 -0
- package/dist/lib/files/scanner.d.ts +23 -0
- package/dist/lib/files/scanner.js +81 -0
- package/dist/lib/git/metadata.d.ts +31 -0
- package/dist/lib/git/metadata.js +90 -0
- package/dist/lib/output/colors.d.ts +14 -0
- package/dist/lib/output/colors.js +23 -0
- package/dist/lib/output/formatter.d.ts +2 -0
- package/dist/lib/output/formatter.js +7 -0
- package/dist/lib/output/table.d.ts +7 -0
- package/dist/lib/output/table.js +64 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Relesio CLI
|
|
2
|
+
|
|
3
|
+
Command-line tool for [Relesio](https://relesio.com) — modern micro-frontend hosting. Upload versions, deploy to environments, and manage projects from the terminal.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **Node.js** >= 18
|
|
8
|
+
- **Bun** (recommended) or **npm** / **pnpm**
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
### From npm
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @relesio/cli
|
|
16
|
+
# or
|
|
17
|
+
bun add -g @relesio/cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### From source (monorepo)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd api
|
|
24
|
+
bun install
|
|
25
|
+
bun run build --filter=@relesio/cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Link locally:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd apps/cli
|
|
32
|
+
bun link
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
1. **Authenticate** with your API token:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
relesio auth login --token rls_your_token_here
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or use the `RELESIO_API_TOKEN` environment variable.
|
|
44
|
+
|
|
45
|
+
2. **Upload** a built frontend:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
relesio upload ./dist --project my-app --version 1.0.0
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
3. **Deploy** to an environment:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
relesio deploy my-app 1.0.0 --env production --yes
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Commands
|
|
58
|
+
|
|
59
|
+
### Authentication
|
|
60
|
+
|
|
61
|
+
| Command | Description |
|
|
62
|
+
| --------------------- | ------------------------ |
|
|
63
|
+
| `relesio auth login` | Authenticate with token |
|
|
64
|
+
| `relesio auth status` | Show current auth state |
|
|
65
|
+
| `relesio auth logout` | Clear stored credentials |
|
|
66
|
+
| `relesio whoami` | Show current user info |
|
|
67
|
+
|
|
68
|
+
### Organizations & Projects
|
|
69
|
+
|
|
70
|
+
| Command | Description |
|
|
71
|
+
| ------------------------------------ | ------------------------------------ |
|
|
72
|
+
| `relesio organizations list` | List organizations |
|
|
73
|
+
| `relesio organizations set <org-id>` | Set active organization |
|
|
74
|
+
| `relesio projects list` | List projects in active organization |
|
|
75
|
+
| `relesio team list` | List teams |
|
|
76
|
+
| `relesio team get <teamId>` | Get team details |
|
|
77
|
+
|
|
78
|
+
### Versions & Deployment
|
|
79
|
+
|
|
80
|
+
| Command | Description |
|
|
81
|
+
| -------------------------------- | -------------------------------------------- |
|
|
82
|
+
| `relesio versions list <project>`| List versions for a project |
|
|
83
|
+
| `relesio status <project>` | Show deployment status across environments |
|
|
84
|
+
| `relesio upload [dir]` | Upload a new version |
|
|
85
|
+
| `relesio deploy [project] [ver]` | Deploy a version to an environment |
|
|
86
|
+
| `relesio rollback <project>` | Rollback to the previous version |
|
|
87
|
+
|
|
88
|
+
## Usage Examples
|
|
89
|
+
|
|
90
|
+
### Authentication
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Interactive login (prompts for token)
|
|
94
|
+
relesio auth login
|
|
95
|
+
|
|
96
|
+
# With token flag
|
|
97
|
+
relesio auth login --token rls_...
|
|
98
|
+
|
|
99
|
+
# Via environment variable
|
|
100
|
+
export RELESIO_API_TOKEN=rls_...
|
|
101
|
+
relesio auth status
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Upload
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Basic upload (default dir: dist, uses package.json for project/version)
|
|
108
|
+
relesio upload
|
|
109
|
+
|
|
110
|
+
# Specify directory, project, and version
|
|
111
|
+
relesio upload ./build --project my-app --version 1.2.0
|
|
112
|
+
|
|
113
|
+
# Require clean git working directory
|
|
114
|
+
relesio upload ./dist -p my-app -v 1.0.1 --require-clean
|
|
115
|
+
|
|
116
|
+
# Non-interactive (skip prompts)
|
|
117
|
+
relesio upload ./dist -p my-app -v 1.0.0 -y
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Deploy
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Deploy specific version to production
|
|
124
|
+
relesio deploy my-app 1.0.0 --env production --yes
|
|
125
|
+
|
|
126
|
+
# Deploy latest version
|
|
127
|
+
relesio deploy my-app --latest --env staging
|
|
128
|
+
|
|
129
|
+
# Use project from package.json
|
|
130
|
+
relesio deploy --env production
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Rollback
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
relesio rollback my-app --env production --yes
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Configuration
|
|
140
|
+
|
|
141
|
+
### Environment Variables
|
|
142
|
+
|
|
143
|
+
| Variable | Description | Default |
|
|
144
|
+
| ------------------ | --------------------------------------- | -------------------------- |
|
|
145
|
+
| `RELESIO_API_TOKEN`| API token (starts with `rls_`) | — |
|
|
146
|
+
| `RELESIO_API_URL` | API base URL | `https://api.relesio.com` |
|
|
147
|
+
| `RELESIO_ORG_ID` | Override active organization | — |
|
|
148
|
+
| `DEBUG` | Enable debug output | — |
|
|
149
|
+
|
|
150
|
+
### Organization Context
|
|
151
|
+
|
|
152
|
+
Order of precedence:
|
|
153
|
+
|
|
154
|
+
1. `--org <org-id>` flag
|
|
155
|
+
2. `RELESIO_ORG_ID` environment variable
|
|
156
|
+
3. Active organization from session
|
|
157
|
+
|
|
158
|
+
### Output Options
|
|
159
|
+
|
|
160
|
+
- `--json` — Output as JSON (machine-readable)
|
|
161
|
+
- `--no-color` — Disable colored output
|
|
162
|
+
|
|
163
|
+
## Project & Version Inference
|
|
164
|
+
|
|
165
|
+
The CLI infers values from `package.json` when possible:
|
|
166
|
+
|
|
167
|
+
- **Project slug** — from `name` (slugified: lowercase, hyphens)
|
|
168
|
+
- **Version** — from `version` (semver)
|
|
169
|
+
|
|
170
|
+
Example: `package.json` with `"name": "@myorg/my-app"` and `"version": "1.0.0"` allows:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
relesio upload ./dist
|
|
174
|
+
relesio deploy --env staging
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## File Structure
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
api/apps/cli/
|
|
181
|
+
├── bin/relesio.js # Entry shim
|
|
182
|
+
├── src/
|
|
183
|
+
│ ├── index.ts # CLI root
|
|
184
|
+
│ ├── commands/ # Command implementations
|
|
185
|
+
│ └── lib/ # API client, config, utilities
|
|
186
|
+
└── dist/ # Compiled output
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Install dependencies
|
|
193
|
+
bun install
|
|
194
|
+
|
|
195
|
+
# Run in development mode
|
|
196
|
+
bun run dev
|
|
197
|
+
|
|
198
|
+
# Build
|
|
199
|
+
bun run build
|
|
200
|
+
|
|
201
|
+
# Type check
|
|
202
|
+
bun run type-check
|
|
203
|
+
|
|
204
|
+
# Lint & format
|
|
205
|
+
bun run lint
|
|
206
|
+
bun run format
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Exit Codes
|
|
210
|
+
|
|
211
|
+
| Code | Meaning |
|
|
212
|
+
| ---- | ----------------- |
|
|
213
|
+
| 0 | Success |
|
|
214
|
+
| 1 | General error |
|
|
215
|
+
|
|
216
|
+
## Links
|
|
217
|
+
|
|
218
|
+
- [Relesio](https://relesio.io)
|
|
219
|
+
- [GitHub](https://github.com/relesio/relesio)
|
|
220
|
+
- [Issues](https://github.com/relesio/relesio/issues)
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
package/bin/relesio.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { loginCommand } from "./login.js";
|
|
3
|
+
import { logoutCommand } from "./logout.js";
|
|
4
|
+
import { statusCommand } from "./status.js";
|
|
5
|
+
export const authCommand = new Command("auth")
|
|
6
|
+
.description("Authentication commands")
|
|
7
|
+
.addCommand(loginCommand)
|
|
8
|
+
.addCommand(logoutCommand)
|
|
9
|
+
.addCommand(statusCommand);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { ConfigManager } from "../../lib/config/manager.js";
|
|
6
|
+
import { RelesioAPIClient } from "../../lib/api/client.js";
|
|
7
|
+
export const loginCommand = new Command("login")
|
|
8
|
+
.description("Authenticate with API token")
|
|
9
|
+
.option("-t, --token <token>", "API token (or use RELESIO_API_TOKEN env var)")
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
let token = options.token || process.env.RELESIO_API_TOKEN;
|
|
12
|
+
// If no token provided, prompt it
|
|
13
|
+
if (!token) {
|
|
14
|
+
const answers = await inquirer.prompt([
|
|
15
|
+
{
|
|
16
|
+
type: "password",
|
|
17
|
+
name: "token",
|
|
18
|
+
message: "Enter your API token:",
|
|
19
|
+
mask: "*",
|
|
20
|
+
validate: (input) => {
|
|
21
|
+
if (!input || input.length === 0) {
|
|
22
|
+
return "Token is required";
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
]);
|
|
28
|
+
token = answers.token;
|
|
29
|
+
}
|
|
30
|
+
// Test token by making API call
|
|
31
|
+
const spinner = ora("Validating token...").start();
|
|
32
|
+
try {
|
|
33
|
+
const config = ConfigManager.load();
|
|
34
|
+
if (process.env.DEBUG) {
|
|
35
|
+
console.error(`\n[DEBUG] Login attempt:`);
|
|
36
|
+
console.error(` API Base URL: ${config.apiBaseUrl}`);
|
|
37
|
+
console.error(` Token (first 20 chars): ${token.substring(0, 20)}...`);
|
|
38
|
+
}
|
|
39
|
+
// Create a temporary client without auth to call /v1/api-token/me
|
|
40
|
+
const tempClient = new RelesioAPIClient(config.apiBaseUrl);
|
|
41
|
+
if (process.env.DEBUG) {
|
|
42
|
+
console.error(`\n[DEBUG] Calling /v1/api-token/me API...`);
|
|
43
|
+
}
|
|
44
|
+
// Validate API key and get full user context
|
|
45
|
+
const response = await tempClient.get("/v1/api-token/me", {
|
|
46
|
+
headers: { "x-api-key": token },
|
|
47
|
+
raw: true
|
|
48
|
+
});
|
|
49
|
+
if (process.env.DEBUG) {
|
|
50
|
+
console.error(`\n[DEBUG] /v1/api-token/me response:`, JSON.stringify(response, null, 2));
|
|
51
|
+
}
|
|
52
|
+
// Save token and user info
|
|
53
|
+
ConfigManager.save({
|
|
54
|
+
apiToken: token,
|
|
55
|
+
userId: response.data.userId,
|
|
56
|
+
userEmail: response.data.email,
|
|
57
|
+
userName: response.data.name,
|
|
58
|
+
activeOrganizationId: response.data.activeOrganizationId,
|
|
59
|
+
activeOrganizationName: response.data.activeOrganizationName,
|
|
60
|
+
activeOrganizationSlug: response.data.activeOrganizationSlug,
|
|
61
|
+
// Legacy fields for backward compatibility
|
|
62
|
+
currentOrgId: response.data.activeOrganizationId,
|
|
63
|
+
currentOrgName: response.data.activeOrganizationName
|
|
64
|
+
});
|
|
65
|
+
spinner.succeed("Authentication successful!");
|
|
66
|
+
console.log(chalk.green("✓"), `Authenticated as ${response.data.email}`);
|
|
67
|
+
if (response.data.activeOrganizationId) {
|
|
68
|
+
console.log(chalk.green("✓"), `Active organization: ${response.data.activeOrganizationName} (${response.data.activeOrganizationSlug})`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log(chalk.yellow("⚠"), "No active organization set. Use 'relesio organizations set <org-id>' to set one.");
|
|
72
|
+
}
|
|
73
|
+
if (response.data.organizations.length > 1) {
|
|
74
|
+
console.log(chalk.blue("ℹ"), `You belong to ${response.data.organizations.length} organizations. Use --org flag to override context.`);
|
|
75
|
+
}
|
|
76
|
+
console.log(chalk.dim("\nTip: Use 'relesio auth status' to view your authentication details"));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
spinner.fail("Authentication failed");
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
import { ConfigManager } from "../../lib/config/manager.js";
|
|
4
|
+
import { formatSuccess } from "../../lib/output/colors.js";
|
|
5
|
+
export const logoutCommand = new Command("logout")
|
|
6
|
+
.description("Clear authentication credentials")
|
|
7
|
+
.option("-f, --force", "Skip confirmation")
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
if (!options.force) {
|
|
10
|
+
const { confirm } = await inquirer.prompt([
|
|
11
|
+
{
|
|
12
|
+
type: "confirm",
|
|
13
|
+
name: "confirm",
|
|
14
|
+
message: "Are you sure you want to logout?",
|
|
15
|
+
default: false
|
|
16
|
+
}
|
|
17
|
+
]);
|
|
18
|
+
if (!confirm) {
|
|
19
|
+
console.log("Logout cancelled");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
ConfigManager.clear();
|
|
24
|
+
console.log(formatSuccess("Logged out successfully"));
|
|
25
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { ConfigManager } from "../../lib/config/manager.js";
|
|
4
|
+
import { handleError } from "../../lib/errors/handler.js";
|
|
5
|
+
export const statusCommand = new Command("status")
|
|
6
|
+
.description("Show current authentication status")
|
|
7
|
+
.action(async () => {
|
|
8
|
+
try {
|
|
9
|
+
const config = ConfigManager.load();
|
|
10
|
+
if (!config.apiToken) {
|
|
11
|
+
console.log(chalk.red("✗"), "Not authenticated");
|
|
12
|
+
console.log(chalk.dim("Run 'relesio auth login' to authenticate"));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
console.log(chalk.green("✓"), "Authenticated");
|
|
16
|
+
console.log(chalk.dim("User:"), config.userEmail || config.userId);
|
|
17
|
+
if (config.userName) {
|
|
18
|
+
console.log(chalk.dim("Name:"), config.userName);
|
|
19
|
+
}
|
|
20
|
+
if (config.activeOrganizationId) {
|
|
21
|
+
console.log(chalk.dim("Active Organization:"), `${config.activeOrganizationName} (${config.activeOrganizationSlug})`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(chalk.yellow("⚠"), "No active organization set");
|
|
25
|
+
}
|
|
26
|
+
console.log(chalk.dim("API URL:"), config.apiBaseUrl);
|
|
27
|
+
// Check env var overrides
|
|
28
|
+
if (process.env.RELESIO_ORG_ID) {
|
|
29
|
+
console.log(chalk.blue("ℹ"), `Organization override: ${process.env.RELESIO_ORG_ID} (from RELESIO_ORG_ID env var)`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
handleError(error);
|
|
34
|
+
}
|
|
35
|
+
});
|