@flowkode/cli 1.0.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 +299 -0
- package/dist/api-client.d.ts +11 -0
- package/dist/api-client.js +65 -0
- package/dist/commands/blog.d.ts +3 -0
- package/dist/commands/blog.js +96 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +37 -0
- package/dist/commands/deployments.d.ts +3 -0
- package/dist/commands/deployments.js +51 -0
- package/dist/commands/domains.d.ts +3 -0
- package/dist/commands/domains.js +189 -0
- package/dist/commands/folders.d.ts +3 -0
- package/dist/commands/folders.js +103 -0
- package/dist/commands/jobs.d.ts +3 -0
- package/dist/commands/jobs.js +45 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.js +133 -0
- package/dist/commands/projects.d.ts +3 -0
- package/dist/commands/projects.js +146 -0
- package/dist/commands/utilities.d.ts +3 -0
- package/dist/commands/utilities.js +129 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +37 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +76 -0
- package/dist/output.d.ts +13 -0
- package/dist/output.js +68 -0
- package/package.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# @flowkode/cli
|
|
2
|
+
|
|
3
|
+
CLI officiel pour l'API Flowkode. Creez, deployez et gerez vos sites web depuis le terminal.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @flowkode/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Connexion
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
flowkode login
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Le navigateur s'ouvre, vous autorisez le CLI en un clic, c'est tout.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
$ flowkode login
|
|
21
|
+
|
|
22
|
+
Flowkode Login
|
|
23
|
+
|
|
24
|
+
Ouverture du navigateur...
|
|
25
|
+
|
|
26
|
+
En attente d'autorisation...
|
|
27
|
+
|
|
28
|
+
✓ Connecte en tant que jeremy@example.com
|
|
29
|
+
Cle sauvegardee dans ~/.flowkode/config.json
|
|
30
|
+
|
|
31
|
+
Essayez : flowkode projects list
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Pour se deconnecter :
|
|
35
|
+
```bash
|
|
36
|
+
flowkode logout
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Configuration avancee
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Configurer manuellement une cle API
|
|
43
|
+
flowkode config --api-key ws_live_xxxxx
|
|
44
|
+
|
|
45
|
+
# URL personnalisee (defaut: https://app.flowkode.com)
|
|
46
|
+
flowkode config --base-url https://app.flowkode.com
|
|
47
|
+
|
|
48
|
+
# Voir la config actuelle
|
|
49
|
+
flowkode config --show
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
La configuration est stockee dans `~/.flowkode/config.json`.
|
|
53
|
+
|
|
54
|
+
Variables d'environnement (prioritaires) :
|
|
55
|
+
```bash
|
|
56
|
+
export FLOWKODE_API_KEY=ws_live_xxxxx
|
|
57
|
+
export FLOWKODE_BASE_URL=https://app.flowkode.com
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Commandes
|
|
61
|
+
|
|
62
|
+
### Projets
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Lister les projets
|
|
66
|
+
flowkode projects list
|
|
67
|
+
flowkode projects list --folder <folder-id>
|
|
68
|
+
|
|
69
|
+
# Detail d'un projet
|
|
70
|
+
flowkode projects get <id>
|
|
71
|
+
|
|
72
|
+
# Creer un projet (mode rapide, 1 page)
|
|
73
|
+
flowkode projects create \
|
|
74
|
+
--name "Mon site" \
|
|
75
|
+
--type vitrine \
|
|
76
|
+
--keywords "seo, web, freelance" \
|
|
77
|
+
--language fr \
|
|
78
|
+
--description "Portfolio developpeur"
|
|
79
|
+
|
|
80
|
+
# Modifier un projet
|
|
81
|
+
flowkode projects update <id> --name "Nouveau nom"
|
|
82
|
+
flowkode projects update <id> --folder <folder-id>
|
|
83
|
+
|
|
84
|
+
# Deployer
|
|
85
|
+
flowkode projects deploy <id> --provider vercel
|
|
86
|
+
flowkode projects deploy <id> --provider cloudflare --domain <domain-id> --configure-ns
|
|
87
|
+
|
|
88
|
+
# Re-deployer sur le dernier provider
|
|
89
|
+
flowkode projects redeploy <id>
|
|
90
|
+
|
|
91
|
+
# Statut d'indexation Google
|
|
92
|
+
flowkode projects indexing <id>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Jobs de generation
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Lister les jobs
|
|
99
|
+
flowkode jobs list
|
|
100
|
+
flowkode jobs list --status running
|
|
101
|
+
|
|
102
|
+
# Suivre un job
|
|
103
|
+
flowkode jobs get <id>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Deploiements
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Lister les deploiements
|
|
110
|
+
flowkode deployments list
|
|
111
|
+
flowkode deployments list --project <id> --provider vercel --status ready
|
|
112
|
+
|
|
113
|
+
# Detail d'un deploiement
|
|
114
|
+
flowkode deployments get <id>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Domaines
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Lister les domaines
|
|
121
|
+
flowkode domains list
|
|
122
|
+
flowkode domains list --registrar ovh --project <id>
|
|
123
|
+
|
|
124
|
+
# Detail d'un domaine
|
|
125
|
+
flowkode domains get <id>
|
|
126
|
+
|
|
127
|
+
# Verifier la disponibilite
|
|
128
|
+
flowkode domains check monsite.com
|
|
129
|
+
|
|
130
|
+
# Acheter un domaine
|
|
131
|
+
flowkode domains purchase monsite.com --registrar internetbs --years 2
|
|
132
|
+
|
|
133
|
+
# Synchroniser depuis les registrars
|
|
134
|
+
flowkode domains sync
|
|
135
|
+
|
|
136
|
+
# Associer un domaine a un projet
|
|
137
|
+
flowkode domains associate <domain-id> --project <project-id>
|
|
138
|
+
|
|
139
|
+
# Dissocier
|
|
140
|
+
flowkode domains dissociate <domain-id>
|
|
141
|
+
|
|
142
|
+
# Configurer les DNS
|
|
143
|
+
flowkode domains dns <domain-id>
|
|
144
|
+
|
|
145
|
+
# Verifier la propagation DNS
|
|
146
|
+
flowkode domains propagation <domain-id>
|
|
147
|
+
|
|
148
|
+
# Modifier (dossier)
|
|
149
|
+
flowkode domains update <id> --folder <folder-id>
|
|
150
|
+
|
|
151
|
+
# Supprimer
|
|
152
|
+
flowkode domains delete <id>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Dossiers
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Lister les dossiers
|
|
159
|
+
flowkode folders list
|
|
160
|
+
|
|
161
|
+
# Creer un dossier
|
|
162
|
+
flowkode folders create --name "Clients 2026" --color blue
|
|
163
|
+
|
|
164
|
+
# Modifier
|
|
165
|
+
flowkode folders update <id> --name "Nouveau nom" --color green --position 0
|
|
166
|
+
|
|
167
|
+
# Supprimer
|
|
168
|
+
flowkode folders delete <id>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Blog
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Lister les articles
|
|
175
|
+
flowkode blog list
|
|
176
|
+
flowkode blog list --project <id> --status published
|
|
177
|
+
|
|
178
|
+
# Detail d'un article
|
|
179
|
+
flowkode blog get <article-id>
|
|
180
|
+
|
|
181
|
+
# Generer des articles par mots-cles
|
|
182
|
+
flowkode blog generate <project-id> --keywords "react" "nextjs" "typescript"
|
|
183
|
+
flowkode blog generate <project-id> --keywords "seo" --auto-publish
|
|
184
|
+
|
|
185
|
+
# Indexation Google
|
|
186
|
+
flowkode blog indexing <article-id>
|
|
187
|
+
flowkode blog indexing-check <article-id>
|
|
188
|
+
flowkode blog indexing-submit <article-id>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Formulaires de contact
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
flowkode contact-forms
|
|
195
|
+
flowkode contact-forms --category devis
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Modeles IA
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
flowkode ai-models
|
|
202
|
+
flowkode ai-models --category generation
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Mentions legales
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
flowkode legal-notices
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Affiliation
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
flowkode affiliation list
|
|
215
|
+
flowkode affiliation get <id>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Google Search Console
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Comptes connectes
|
|
222
|
+
flowkode search-console accounts
|
|
223
|
+
|
|
224
|
+
# Enregistrer un site
|
|
225
|
+
flowkode search-console add-site <project-id>
|
|
226
|
+
|
|
227
|
+
# Statut
|
|
228
|
+
flowkode search-console status <project-id>
|
|
229
|
+
|
|
230
|
+
# Soumettre le sitemap
|
|
231
|
+
flowkode search-console submit-sitemap <project-id>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Options globales
|
|
235
|
+
|
|
236
|
+
| Option | Description |
|
|
237
|
+
|--------|-------------|
|
|
238
|
+
| `--json` | Sortie en JSON brut (utile pour scripts et CI/CD) |
|
|
239
|
+
| `--version` | Afficher la version |
|
|
240
|
+
| `--help` | Afficher l'aide |
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Sortie JSON pour integration dans un script
|
|
244
|
+
flowkode --json projects list
|
|
245
|
+
|
|
246
|
+
# Pipe avec jq
|
|
247
|
+
flowkode --json projects list | jq '.data[].name'
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Utilisation dans un CI/CD
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
# GitHub Actions
|
|
254
|
+
- name: Deploy site
|
|
255
|
+
env:
|
|
256
|
+
FLOWKODE_API_KEY: ${{ secrets.FLOWKODE_API_KEY }}
|
|
257
|
+
run: |
|
|
258
|
+
npx @flowkode/cli projects deploy $PROJECT_ID --provider vercel
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Workflow type
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# 1. Creer un projet
|
|
265
|
+
flowkode projects create -n "Mon site" -t vitrine -k "web,dev" -l fr
|
|
266
|
+
# => { "jobId": "abc-123", "status": "pending" }
|
|
267
|
+
|
|
268
|
+
# 2. Suivre la generation
|
|
269
|
+
flowkode jobs get abc-123
|
|
270
|
+
# => status: "completed", project_id: "def-456"
|
|
271
|
+
|
|
272
|
+
# 3. Deployer
|
|
273
|
+
flowkode projects deploy def-456 --provider vercel
|
|
274
|
+
|
|
275
|
+
# 4. Acheter et associer un domaine
|
|
276
|
+
flowkode domains check monsite.com
|
|
277
|
+
flowkode domains purchase monsite.com --registrar ovh
|
|
278
|
+
flowkode domains sync
|
|
279
|
+
flowkode domains associate <domain-id> --project def-456
|
|
280
|
+
flowkode domains dns <domain-id>
|
|
281
|
+
|
|
282
|
+
# 5. Generer du contenu blog
|
|
283
|
+
flowkode blog generate def-456 --keywords "react" "nextjs" --auto-publish
|
|
284
|
+
|
|
285
|
+
# 6. Soumettre a Google
|
|
286
|
+
flowkode search-console add-site def-456
|
|
287
|
+
flowkode search-console submit-sitemap def-456
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Developpement
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
cd flowkode-cli
|
|
294
|
+
npm install
|
|
295
|
+
npm run build
|
|
296
|
+
|
|
297
|
+
# Mode dev
|
|
298
|
+
FLOWKODE_API_KEY=ws_live_... npm run dev -- projects list
|
|
299
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class FlowkodeApiClient {
|
|
2
|
+
private baseUrl;
|
|
3
|
+
private apiKey;
|
|
4
|
+
constructor(baseUrl: string, apiKey: string);
|
|
5
|
+
private headers;
|
|
6
|
+
get(path: string, params?: Record<string, string | undefined>): Promise<unknown>;
|
|
7
|
+
post(path: string, body?: unknown): Promise<unknown>;
|
|
8
|
+
patch(path: string, body: unknown): Promise<unknown>;
|
|
9
|
+
delete(path: string): Promise<unknown>;
|
|
10
|
+
private handleResponse;
|
|
11
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export class FlowkodeApiClient {
|
|
2
|
+
baseUrl;
|
|
3
|
+
apiKey;
|
|
4
|
+
constructor(baseUrl, apiKey) {
|
|
5
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
}
|
|
8
|
+
headers() {
|
|
9
|
+
return {
|
|
10
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async get(path, params) {
|
|
15
|
+
const url = new URL(`${this.baseUrl}/api/v1${path}`);
|
|
16
|
+
if (params) {
|
|
17
|
+
for (const [key, value] of Object.entries(params)) {
|
|
18
|
+
if (value !== undefined)
|
|
19
|
+
url.searchParams.set(key, value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const res = await fetch(url.toString(), { headers: this.headers() });
|
|
23
|
+
return this.handleResponse(res);
|
|
24
|
+
}
|
|
25
|
+
async post(path, body) {
|
|
26
|
+
const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: this.headers(),
|
|
29
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
30
|
+
});
|
|
31
|
+
return this.handleResponse(res);
|
|
32
|
+
}
|
|
33
|
+
async patch(path, body) {
|
|
34
|
+
const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
|
|
35
|
+
method: "PATCH",
|
|
36
|
+
headers: this.headers(),
|
|
37
|
+
body: JSON.stringify(body),
|
|
38
|
+
});
|
|
39
|
+
return this.handleResponse(res);
|
|
40
|
+
}
|
|
41
|
+
async delete(path) {
|
|
42
|
+
const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
|
|
43
|
+
method: "DELETE",
|
|
44
|
+
headers: this.headers(),
|
|
45
|
+
});
|
|
46
|
+
return this.handleResponse(res);
|
|
47
|
+
}
|
|
48
|
+
async handleResponse(res) {
|
|
49
|
+
const text = await res.text();
|
|
50
|
+
let data;
|
|
51
|
+
try {
|
|
52
|
+
data = JSON.parse(text);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
data = { raw: text };
|
|
56
|
+
}
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
const errorMsg = typeof data === "object" && data !== null && "error" in data
|
|
59
|
+
? data.error
|
|
60
|
+
: `HTTP ${res.status}`;
|
|
61
|
+
throw new Error(errorMsg);
|
|
62
|
+
}
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { printTable, printSuccess, printError, printJson, } from "../output.js";
|
|
3
|
+
export function blogCommand(api) {
|
|
4
|
+
const cmd = new Command("blog").description("Gerer les articles de blog");
|
|
5
|
+
cmd
|
|
6
|
+
.command("list")
|
|
7
|
+
.description("Lister les articles")
|
|
8
|
+
.option("--project <id>", "Filtrer par projet")
|
|
9
|
+
.option("-s, --status <status>", "Filtrer (pending, queued, running, generated, scheduled, published, error)")
|
|
10
|
+
.action(async (opts) => {
|
|
11
|
+
try {
|
|
12
|
+
const res = (await api.get("/blog/articles", {
|
|
13
|
+
projectId: opts.project,
|
|
14
|
+
status: opts.status,
|
|
15
|
+
}));
|
|
16
|
+
printTable(res.data, [
|
|
17
|
+
{ key: "id", label: "ID", width: 36 },
|
|
18
|
+
{ key: "title", label: "Titre", width: 35 },
|
|
19
|
+
{ key: "keyword", label: "Mot-cle", width: 20 },
|
|
20
|
+
{ key: "status", label: "Statut", width: 12 },
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
printError(e);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
cmd
|
|
28
|
+
.command("get <articleId>")
|
|
29
|
+
.description("Detail d'un article")
|
|
30
|
+
.action(async (articleId) => {
|
|
31
|
+
try {
|
|
32
|
+
const res = await api.get(`/blog/articles/${articleId}`);
|
|
33
|
+
printJson(res);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
printError(e);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
cmd
|
|
40
|
+
.command("generate <projectId>")
|
|
41
|
+
.description("Generer des articles par mots-cles")
|
|
42
|
+
.requiredOption("-k, --keywords <keywords...>", "Mots-cles (un ou plusieurs)")
|
|
43
|
+
.option("--auto-publish", "Publier automatiquement")
|
|
44
|
+
.action(async (projectId, opts) => {
|
|
45
|
+
try {
|
|
46
|
+
const res = await api.post(`/projects/${projectId}/blog/articles`, {
|
|
47
|
+
keywords: opts.keywords,
|
|
48
|
+
auto_publish: opts.autoPublish ?? false,
|
|
49
|
+
});
|
|
50
|
+
printJson(res);
|
|
51
|
+
printSuccess("Generation d'articles lancee.");
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
printError(e);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
cmd
|
|
58
|
+
.command("indexing <articleId>")
|
|
59
|
+
.description("Statut d'indexation Google d'un article")
|
|
60
|
+
.action(async (articleId) => {
|
|
61
|
+
try {
|
|
62
|
+
const res = await api.get(`/blog/articles/${articleId}/indexing`);
|
|
63
|
+
printJson(res);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
printError(e);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
cmd
|
|
70
|
+
.command("indexing-check <articleId>")
|
|
71
|
+
.description("Verifier l'indexation d'un article")
|
|
72
|
+
.action(async (articleId) => {
|
|
73
|
+
try {
|
|
74
|
+
const res = await api.post(`/blog/articles/${articleId}/indexing/check`);
|
|
75
|
+
printJson(res);
|
|
76
|
+
printSuccess("Verification lancee.");
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
printError(e);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
cmd
|
|
83
|
+
.command("indexing-submit <articleId>")
|
|
84
|
+
.description("Soumettre un article pour indexation Google")
|
|
85
|
+
.action(async (articleId) => {
|
|
86
|
+
try {
|
|
87
|
+
const res = await api.post(`/blog/articles/${articleId}/indexing/submit`);
|
|
88
|
+
printJson(res);
|
|
89
|
+
printSuccess("Article soumis pour indexation.");
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
printError(e);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return cmd;
|
|
96
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { loadConfig, saveConfig } from "../config.js";
|
|
3
|
+
import { printSuccess, printDetail } from "../output.js";
|
|
4
|
+
export function configCommand() {
|
|
5
|
+
const cmd = new Command("config").description("Configurer la cle API et l'URL de base");
|
|
6
|
+
cmd
|
|
7
|
+
.option("-k, --api-key <key>", "Cle API Flowkode (ws_live_...)")
|
|
8
|
+
.option("-u, --base-url <url>", "URL de base de l'API")
|
|
9
|
+
.option("--show", "Afficher la configuration actuelle")
|
|
10
|
+
.action((opts) => {
|
|
11
|
+
if (opts.show) {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
printDetail({
|
|
14
|
+
api_key: config.api_key
|
|
15
|
+
? `${config.api_key.slice(0, 12)}...`
|
|
16
|
+
: undefined,
|
|
17
|
+
base_url: config.base_url,
|
|
18
|
+
}, [
|
|
19
|
+
{ key: "api_key", label: "API Key" },
|
|
20
|
+
{ key: "base_url", label: "Base URL" },
|
|
21
|
+
]);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const config = loadConfig();
|
|
25
|
+
if (opts.apiKey)
|
|
26
|
+
config.api_key = opts.apiKey;
|
|
27
|
+
if (opts.baseUrl)
|
|
28
|
+
config.base_url = opts.baseUrl;
|
|
29
|
+
if (!opts.apiKey && !opts.baseUrl) {
|
|
30
|
+
cmd.help();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
saveConfig(config);
|
|
34
|
+
printSuccess("Configuration saved to ~/.flowkode/config.json");
|
|
35
|
+
});
|
|
36
|
+
return cmd;
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { printTable, printDetail, printError } from "../output.js";
|
|
3
|
+
export function deploymentsCommand(api) {
|
|
4
|
+
const cmd = new Command("deployments").description("Gerer les deploiements");
|
|
5
|
+
cmd
|
|
6
|
+
.command("list")
|
|
7
|
+
.description("Lister les deploiements")
|
|
8
|
+
.option("--project <id>", "Filtrer par projet")
|
|
9
|
+
.option("--provider <provider>", "Filtrer (vercel, cloudflare)")
|
|
10
|
+
.option("-s, --status <status>", "Filtrer (pending, building, ready, error, canceled)")
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
try {
|
|
13
|
+
const res = (await api.get("/deployments", {
|
|
14
|
+
project_id: opts.project,
|
|
15
|
+
provider: opts.provider,
|
|
16
|
+
status: opts.status,
|
|
17
|
+
}));
|
|
18
|
+
printTable(res.data, [
|
|
19
|
+
{ key: "id", label: "ID", width: 36 },
|
|
20
|
+
{ key: "project_name", label: "Projet", width: 25 },
|
|
21
|
+
{ key: "provider", label: "Provider", width: 12 },
|
|
22
|
+
{ key: "status", label: "Statut", width: 10 },
|
|
23
|
+
{ key: "url", label: "URL", width: 40 },
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
printError(e);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
cmd
|
|
31
|
+
.command("get <id>")
|
|
32
|
+
.description("Detail d'un deploiement")
|
|
33
|
+
.action(async (id) => {
|
|
34
|
+
try {
|
|
35
|
+
const res = (await api.get(`/deployments/${id}`));
|
|
36
|
+
printDetail(res.data, [
|
|
37
|
+
{ key: "id", label: "ID" },
|
|
38
|
+
{ key: "project_name", label: "Projet" },
|
|
39
|
+
{ key: "provider", label: "Provider" },
|
|
40
|
+
{ key: "status", label: "Statut" },
|
|
41
|
+
{ key: "url", label: "URL" },
|
|
42
|
+
{ key: "error_message", label: "Erreur" },
|
|
43
|
+
{ key: "created_at", label: "Cree le" },
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
printError(e);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return cmd;
|
|
51
|
+
}
|