@laioutr/cli 0.3.2 → 0.4.1
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 +17 -0
- package/README.md +168 -25
- package/dist/api/deploy.d.ts +66 -0
- package/dist/api/deploy.js +34 -0
- package/dist/api/fetchRc.d.ts +1 -0
- package/dist/api/fetchRc.js +12 -28
- package/dist/api/http.d.ts +30 -0
- package/dist/api/http.js +93 -0
- package/dist/api/releaseAppVersion.d.ts +1 -0
- package/dist/api/releaseAppVersion.js +9 -20
- package/dist/commands/app/release.d.ts +2 -1
- package/dist/commands/app/release.js +2 -1
- package/dist/commands/deploy/list.d.ts +32 -0
- package/dist/commands/deploy/list.js +55 -0
- package/dist/commands/deploy/logs.d.ts +23 -0
- package/dist/commands/deploy/logs.js +54 -0
- package/dist/commands/deploy/status.d.ts +31 -0
- package/dist/commands/deploy/status.js +41 -0
- package/dist/commands/deploy/trigger.d.ts +24 -0
- package/dist/commands/deploy/trigger.js +130 -0
- package/dist/commands/rc/fetch.d.ts +4 -3
- package/dist/commands/rc/fetch.js +24 -3
- package/dist/commands/rc/update.d.ts +2 -1
- package/dist/commands/rc/update.js +2 -1
- package/dist/deploy/attribution.d.ts +12 -0
- package/dist/deploy/attribution.js +16 -0
- package/dist/deploy/log-renderer.d.ts +13 -0
- package/dist/deploy/log-renderer.js +21 -0
- package/dist/deploy/polling.d.ts +4 -0
- package/dist/deploy/polling.js +12 -0
- package/dist/deploy/validation.d.ts +81 -0
- package/dist/deploy/validation.js +47 -0
- package/dist/deploy-base-command.d.ts +12 -0
- package/dist/deploy-base-command.js +27 -0
- package/dist/format/color.d.ts +5 -0
- package/dist/format/color.js +10 -0
- package/dist/format/detail.d.ts +19 -0
- package/dist/format/detail.js +18 -0
- package/dist/laioutr-base-command.d.ts +9 -1
- package/dist/laioutr-base-command.js +21 -3
- package/dist/project.d.ts +14 -0
- package/dist/project.js +16 -0
- package/oclif.manifest.json +443 -22
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @laioutr/cli
|
|
2
2
|
|
|
3
|
+
## 0.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b62dff8: Follow CLI output conventions for deployment logs, add actionable timeout-aware HTTP errors and a versioned API user agent, and introduce kebab-case flags with deprecated camelCase aliases.
|
|
8
|
+
|
|
9
|
+
## 0.4.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- e5eb46a: Add a `deploy` command group for managing project deployments from the CLI. Every command targets a project as `--project org/project` and authenticates with an organization API key (`--key`, or the `LAIOUTR_API_KEY` env var).
|
|
14
|
+
|
|
15
|
+
- `laioutr deploy trigger` — trigger a production or named-preview deployment (`--preview <name>`). Waits for completion by default (`--no-wait` to return immediately) and can stream build logs with `--logs`.
|
|
16
|
+
- `laioutr deploy status` — show a deployment's status, environment, URL, and who created it.
|
|
17
|
+
- `laioutr deploy list` — list recent deployments for a project (`--limit`, default 20, max 100).
|
|
18
|
+
- `laioutr deploy logs` — fetch and follow a deployment's build logs.
|
|
19
|
+
|
|
3
20
|
## 0.3.1
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ $ npm install -g @laioutr/cli
|
|
|
20
20
|
$ laioutr COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ laioutr (--version)
|
|
23
|
-
@laioutr/cli/0.
|
|
23
|
+
@laioutr/cli/0.4.1 linux-x64 node-v24.18.0
|
|
24
24
|
$ laioutr --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ laioutr COMMAND
|
|
@@ -32,6 +32,10 @@ USAGE
|
|
|
32
32
|
|
|
33
33
|
<!-- commands -->
|
|
34
34
|
* [`laioutr app release`](#laioutr-app-release)
|
|
35
|
+
* [`laioutr deploy list`](#laioutr-deploy-list)
|
|
36
|
+
* [`laioutr deploy logs`](#laioutr-deploy-logs)
|
|
37
|
+
* [`laioutr deploy status`](#laioutr-deploy-status)
|
|
38
|
+
* [`laioutr deploy trigger`](#laioutr-deploy-trigger)
|
|
35
39
|
* [`laioutr help [COMMAND]`](#laioutr-help-command)
|
|
36
40
|
* [`laioutr plugins`](#laioutr-plugins)
|
|
37
41
|
* [`laioutr plugins add PLUGIN`](#laioutr-plugins-add-plugin)
|
|
@@ -53,14 +57,16 @@ Publish an app version to the Laioutr platform.
|
|
|
53
57
|
|
|
54
58
|
```
|
|
55
59
|
USAGE
|
|
56
|
-
$ laioutr app release --
|
|
60
|
+
$ laioutr app release --cockpit-api-host <value> --cwd <value> -k <value> [--no-color] [-c stable|testing]
|
|
57
61
|
|
|
58
62
|
FLAGS
|
|
59
|
-
-c, --channel=<option>
|
|
60
|
-
|
|
61
|
-
-k, --key=<value>
|
|
62
|
-
--
|
|
63
|
-
--cwd=<value>
|
|
63
|
+
-c, --channel=<option> Release channel (auto-detected from version if omitted)
|
|
64
|
+
<options: stable|testing>
|
|
65
|
+
-k, --key=<value> (required) API key for authentication
|
|
66
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
67
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
68
|
+
directory
|
|
69
|
+
--no-color Disable color in output
|
|
64
70
|
|
|
65
71
|
DESCRIPTION
|
|
66
72
|
Publish an app version to the Laioutr platform.
|
|
@@ -73,7 +79,137 @@ EXAMPLES
|
|
|
73
79
|
LAIOUTR_API_KEY=orgKey_xxx laioutr app release
|
|
74
80
|
```
|
|
75
81
|
|
|
76
|
-
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.
|
|
82
|
+
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/app/release.ts)_
|
|
83
|
+
|
|
84
|
+
## `laioutr deploy list`
|
|
85
|
+
|
|
86
|
+
List recent deployments for a project.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
USAGE
|
|
90
|
+
$ laioutr deploy list --cockpit-api-host <value> --cwd <value> -p <value> -k <value> [--json] [--no-color]
|
|
91
|
+
[--limit <value>]
|
|
92
|
+
|
|
93
|
+
FLAGS
|
|
94
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
95
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
96
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
97
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
98
|
+
directory
|
|
99
|
+
--limit=<value> [default: 20] Maximum number of deployments to list (1-100)
|
|
100
|
+
--no-color Disable color in output
|
|
101
|
+
|
|
102
|
+
GLOBAL FLAGS
|
|
103
|
+
--json Format output as json.
|
|
104
|
+
|
|
105
|
+
DESCRIPTION
|
|
106
|
+
List recent deployments for a project.
|
|
107
|
+
|
|
108
|
+
EXAMPLES
|
|
109
|
+
$ laioutr deploy list --project org/project --key orgKey_xxx
|
|
110
|
+
|
|
111
|
+
$ laioutr deploy list --project org/project --key orgKey_xxx --limit 50
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
_See code: [src/commands/deploy/list.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/list.ts)_
|
|
115
|
+
|
|
116
|
+
## `laioutr deploy logs`
|
|
117
|
+
|
|
118
|
+
Fetch and display build logs for a deployment.
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
USAGE
|
|
122
|
+
$ laioutr deploy logs --cockpit-api-host <value> --cwd <value> -p <value> -k <value> --deployment-id <value>
|
|
123
|
+
[--json] [--no-color]
|
|
124
|
+
|
|
125
|
+
FLAGS
|
|
126
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
127
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
128
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
129
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
130
|
+
directory
|
|
131
|
+
--deployment-id=<value> (required) Deployment ID
|
|
132
|
+
--no-color Disable color in output
|
|
133
|
+
|
|
134
|
+
GLOBAL FLAGS
|
|
135
|
+
--json Format output as json.
|
|
136
|
+
|
|
137
|
+
DESCRIPTION
|
|
138
|
+
Fetch and display build logs for a deployment.
|
|
139
|
+
|
|
140
|
+
EXAMPLES
|
|
141
|
+
$ laioutr deploy logs --project org/project --key orgKey_xxx --deployment-id dep_abc123
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
_See code: [src/commands/deploy/logs.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/logs.ts)_
|
|
145
|
+
|
|
146
|
+
## `laioutr deploy status`
|
|
147
|
+
|
|
148
|
+
Show status of a deployment.
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
USAGE
|
|
152
|
+
$ laioutr deploy status --cockpit-api-host <value> --cwd <value> -p <value> -k <value> --deployment-id <value>
|
|
153
|
+
[--json] [--no-color]
|
|
154
|
+
|
|
155
|
+
FLAGS
|
|
156
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
157
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
158
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
159
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
160
|
+
directory
|
|
161
|
+
--deployment-id=<value> (required) Deployment ID
|
|
162
|
+
--no-color Disable color in output
|
|
163
|
+
|
|
164
|
+
GLOBAL FLAGS
|
|
165
|
+
--json Format output as json.
|
|
166
|
+
|
|
167
|
+
DESCRIPTION
|
|
168
|
+
Show status of a deployment.
|
|
169
|
+
|
|
170
|
+
EXAMPLES
|
|
171
|
+
$ laioutr deploy status --project org/project --key orgKey_xxx --deployment-id dep_abc123
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
_See code: [src/commands/deploy/status.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/status.ts)_
|
|
175
|
+
|
|
176
|
+
## `laioutr deploy trigger`
|
|
177
|
+
|
|
178
|
+
Trigger a project deployment.
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
USAGE
|
|
182
|
+
$ laioutr deploy trigger --cockpit-api-host <value> --cwd <value> -p <value> -k <value> [--json] [--no-color]
|
|
183
|
+
[--wait] [--logs] [--preview <value>]
|
|
184
|
+
|
|
185
|
+
FLAGS
|
|
186
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
187
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
188
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
189
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
190
|
+
directory
|
|
191
|
+
--logs Stream build log output instead of spinner
|
|
192
|
+
--no-color Disable color in output
|
|
193
|
+
--preview=<value> Create a preview deployment with optional name
|
|
194
|
+
--[no-]wait Wait for deployment to complete
|
|
195
|
+
|
|
196
|
+
GLOBAL FLAGS
|
|
197
|
+
--json Format output as json.
|
|
198
|
+
|
|
199
|
+
DESCRIPTION
|
|
200
|
+
Trigger a project deployment.
|
|
201
|
+
|
|
202
|
+
EXAMPLES
|
|
203
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx
|
|
204
|
+
|
|
205
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --no-wait
|
|
206
|
+
|
|
207
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --logs
|
|
208
|
+
|
|
209
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --preview my-feature
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
_See code: [src/commands/deploy/trigger.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/trigger.ts)_
|
|
77
213
|
|
|
78
214
|
## `laioutr help [COMMAND]`
|
|
79
215
|
|
|
@@ -391,14 +527,17 @@ Fetches the laioutrrc.json of a project from the cockpit api.
|
|
|
391
527
|
|
|
392
528
|
```
|
|
393
529
|
USAGE
|
|
394
|
-
$ laioutr project fetch-rc [FILENAME] --
|
|
530
|
+
$ laioutr project fetch-rc [FILENAME] --cockpit-api-host <value> --cwd <value> -e <value> -s <value> -p <value>
|
|
531
|
+
[--no-color]
|
|
395
532
|
|
|
396
533
|
FLAGS
|
|
397
|
-
-e, --
|
|
398
|
-
-p, --project=<value>
|
|
399
|
-
-s, --
|
|
400
|
-
--
|
|
401
|
-
--cwd=<value>
|
|
534
|
+
-e, --environment-name=<value> (required) [default: main] Environment name
|
|
535
|
+
-p, --project=<value> (required) <organization slug>/<project slug>
|
|
536
|
+
-s, --project-secret=<value> (required) Project secret
|
|
537
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
538
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
539
|
+
directory
|
|
540
|
+
--no-color Disable color in output
|
|
402
541
|
|
|
403
542
|
DESCRIPTION
|
|
404
543
|
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
@@ -416,14 +555,17 @@ Fetches the laioutrrc.json of a project from the cockpit api.
|
|
|
416
555
|
|
|
417
556
|
```
|
|
418
557
|
USAGE
|
|
419
|
-
$ laioutr rc fetch [FILENAME] --
|
|
558
|
+
$ laioutr rc fetch [FILENAME] --cockpit-api-host <value> --cwd <value> -e <value> -s <value> -p <value>
|
|
559
|
+
[--no-color]
|
|
420
560
|
|
|
421
561
|
FLAGS
|
|
422
|
-
-e, --
|
|
423
|
-
-p, --project=<value>
|
|
424
|
-
-s, --
|
|
425
|
-
--
|
|
426
|
-
--cwd=<value>
|
|
562
|
+
-e, --environment-name=<value> (required) [default: main] Environment name
|
|
563
|
+
-p, --project=<value> (required) <organization slug>/<project slug>
|
|
564
|
+
-s, --project-secret=<value> (required) Project secret
|
|
565
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
566
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working
|
|
567
|
+
directory
|
|
568
|
+
--no-color Disable color in output
|
|
427
569
|
|
|
428
570
|
DESCRIPTION
|
|
429
571
|
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
@@ -435,7 +577,7 @@ EXAMPLES
|
|
|
435
577
|
$ laioutr rc fetch
|
|
436
578
|
```
|
|
437
579
|
|
|
438
|
-
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.
|
|
580
|
+
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/rc/fetch.ts)_
|
|
439
581
|
|
|
440
582
|
## `laioutr rc update [FILENAME]`
|
|
441
583
|
|
|
@@ -443,11 +585,12 @@ Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
|
443
585
|
|
|
444
586
|
```
|
|
445
587
|
USAGE
|
|
446
|
-
$ laioutr rc update [FILENAME] --
|
|
588
|
+
$ laioutr rc update [FILENAME] --cockpit-api-host <value> --cwd <value> [--no-color]
|
|
447
589
|
|
|
448
590
|
FLAGS
|
|
449
|
-
--
|
|
450
|
-
--cwd=<value>
|
|
591
|
+
--cockpit-api-host=<value> (required) [default: https://cockpit.laioutr.cloud] Cockpit API host
|
|
592
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] Current working directory
|
|
593
|
+
--no-color Disable color in output
|
|
451
594
|
|
|
452
595
|
DESCRIPTION
|
|
453
596
|
Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
@@ -456,5 +599,5 @@ EXAMPLES
|
|
|
456
599
|
$ laioutr rc update
|
|
457
600
|
```
|
|
458
601
|
|
|
459
|
-
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.
|
|
602
|
+
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/rc/update.ts)_
|
|
460
603
|
<!-- commandsstop -->
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface DeployApiOptions {
|
|
2
|
+
cockpitApiHost: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
organizationSlug: string;
|
|
5
|
+
projectSlug: string;
|
|
6
|
+
userAgent: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TriggerOptions extends DeployApiOptions {
|
|
9
|
+
previewName?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function triggerDeployment(options: TriggerOptions): Promise<{
|
|
12
|
+
deploymentId: string;
|
|
13
|
+
status: string;
|
|
14
|
+
environment: string;
|
|
15
|
+
previewName: string | null;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function fetchDeploymentStatus(options: DeployApiOptions & {
|
|
18
|
+
deploymentId: string;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
deploymentId: string;
|
|
21
|
+
status: string;
|
|
22
|
+
environment: string;
|
|
23
|
+
previewName: string | null;
|
|
24
|
+
url: string | null;
|
|
25
|
+
lastError: string | null;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
stoppedAt: string | null;
|
|
28
|
+
attribution: {
|
|
29
|
+
principalType: "user" | "api-key" | "system";
|
|
30
|
+
displayName: string;
|
|
31
|
+
email: string | null;
|
|
32
|
+
agentName: string | null;
|
|
33
|
+
redacted: boolean;
|
|
34
|
+
} | null;
|
|
35
|
+
}>;
|
|
36
|
+
export declare function fetchDeployments(options: DeployApiOptions & {
|
|
37
|
+
limit?: number;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
deployments: {
|
|
40
|
+
deploymentId: string;
|
|
41
|
+
status: string;
|
|
42
|
+
environment: string;
|
|
43
|
+
previewName: string | null;
|
|
44
|
+
url: string | null;
|
|
45
|
+
createdAt: string;
|
|
46
|
+
stoppedAt: string | null;
|
|
47
|
+
attribution: {
|
|
48
|
+
principalType: "user" | "api-key" | "system";
|
|
49
|
+
displayName: string;
|
|
50
|
+
email: string | null;
|
|
51
|
+
agentName: string | null;
|
|
52
|
+
redacted: boolean;
|
|
53
|
+
} | null;
|
|
54
|
+
}[];
|
|
55
|
+
}>;
|
|
56
|
+
export declare function fetchDeploymentLogs(options: DeployApiOptions & {
|
|
57
|
+
deploymentId: string;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
lines: {
|
|
60
|
+
text: string;
|
|
61
|
+
level?: "error" | "warning" | null | undefined;
|
|
62
|
+
timestamp?: number | null | undefined;
|
|
63
|
+
}[] | null;
|
|
64
|
+
supported: boolean;
|
|
65
|
+
deploymentStatus: string;
|
|
66
|
+
}>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { postJson } from './http.js';
|
|
2
|
+
import { deploymentLogsResponseSchema, deploymentsListResponseSchema, deploymentStatusResponseSchema, deployTriggerResponseSchema, } from '../deploy/validation.js';
|
|
3
|
+
export async function triggerDeployment(options) {
|
|
4
|
+
const data = await postJson(`${options.cockpitApiHost}/api/v1/project/deploy`, {
|
|
5
|
+
organizationSlug: options.organizationSlug,
|
|
6
|
+
projectSlug: options.projectSlug,
|
|
7
|
+
previewName: options.previewName,
|
|
8
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
9
|
+
return deployTriggerResponseSchema.parse(data);
|
|
10
|
+
}
|
|
11
|
+
export async function fetchDeploymentStatus(options) {
|
|
12
|
+
const data = await postJson(`${options.cockpitApiHost}/api/v1/project/deployment-status`, {
|
|
13
|
+
organizationSlug: options.organizationSlug,
|
|
14
|
+
projectSlug: options.projectSlug,
|
|
15
|
+
deploymentId: options.deploymentId,
|
|
16
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
17
|
+
return deploymentStatusResponseSchema.parse(data);
|
|
18
|
+
}
|
|
19
|
+
export async function fetchDeployments(options) {
|
|
20
|
+
const data = await postJson(`${options.cockpitApiHost}/api/v1/project/deployments`, {
|
|
21
|
+
organizationSlug: options.organizationSlug,
|
|
22
|
+
projectSlug: options.projectSlug,
|
|
23
|
+
limit: options.limit,
|
|
24
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
25
|
+
return deploymentsListResponseSchema.parse(data);
|
|
26
|
+
}
|
|
27
|
+
export async function fetchDeploymentLogs(options) {
|
|
28
|
+
const data = await postJson(`${options.cockpitApiHost}/api/v1/project/deployment-logs`, {
|
|
29
|
+
organizationSlug: options.organizationSlug,
|
|
30
|
+
projectSlug: options.projectSlug,
|
|
31
|
+
deploymentId: options.deploymentId,
|
|
32
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
33
|
+
return deploymentLogsResponseSchema.parse(data);
|
|
34
|
+
}
|
package/dist/api/fetchRc.d.ts
CHANGED
package/dist/api/fetchRc.js
CHANGED
|
@@ -1,35 +1,19 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
1
|
import { z } from 'zod/v4';
|
|
2
|
+
import { postJson } from './http.js';
|
|
3
|
+
import { parseProjectSlug } from '../project.js';
|
|
3
4
|
const apiResponseSchema = z.object({
|
|
4
5
|
content: z.string(),
|
|
5
6
|
});
|
|
6
7
|
export const fetchRc = async (flags) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
body: JSON.stringify({
|
|
11
|
-
environmentName: flags.environmentName,
|
|
12
|
-
organizationSlug,
|
|
13
|
-
projectSecret: flags.projectSecret,
|
|
14
|
-
projectSlug,
|
|
15
|
-
}),
|
|
16
|
-
headers: {
|
|
17
|
-
'Content-Type': 'application/json',
|
|
18
|
-
},
|
|
19
|
-
method: 'POST',
|
|
20
|
-
});
|
|
21
|
-
const body = await response.text();
|
|
22
|
-
let data = null;
|
|
23
|
-
if (response.status !== 200) {
|
|
24
|
-
throw new Error(`Failed to fetch RC file. Status: ${response.status} ${response.statusText}. Body: ${body}`);
|
|
8
|
+
const parsed = parseProjectSlug(flags.project);
|
|
9
|
+
if (!parsed) {
|
|
10
|
+
throw new Error(`Invalid project "${flags.project}" — expected <organization slug>/<project slug>.`);
|
|
25
11
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const parsed = apiResponseSchema.parse(data);
|
|
34
|
-
return parsed.content;
|
|
12
|
+
const data = await postJson(`${flags.cockpitApiHost}/api/v1/project/fetch-rc`, {
|
|
13
|
+
environmentName: flags.environmentName,
|
|
14
|
+
organizationSlug: parsed.organizationSlug,
|
|
15
|
+
projectSecret: flags.projectSecret,
|
|
16
|
+
projectSlug: parsed.projectSlug,
|
|
17
|
+
}, { userAgent: flags.userAgent });
|
|
18
|
+
return apiResponseSchema.parse(data).content;
|
|
35
19
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type HttpErrorCode = 'HTTP_INVALID_RESPONSE' | 'HTTP_NETWORK_ERROR' | 'HTTP_RESPONSE_ERROR' | 'HTTP_TIMEOUT';
|
|
2
|
+
interface HttpRequestErrorOptions {
|
|
3
|
+
cause?: unknown;
|
|
4
|
+
status?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class HttpRequestError extends Error {
|
|
7
|
+
readonly code: HttpErrorCode;
|
|
8
|
+
readonly status?: number;
|
|
9
|
+
constructor(code: HttpErrorCode, message: string, options?: HttpRequestErrorOptions);
|
|
10
|
+
}
|
|
11
|
+
export interface PostJsonOptions {
|
|
12
|
+
/** When set, sent as an `Authorization: Bearer <apiKey>` header. */
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
/** Extra headers, merged over the defaults (`Content-Type` + auth). */
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
/** Request timeout in milliseconds. */
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/** CLI identity sent as the HTTP User-Agent. */
|
|
19
|
+
userAgent?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
23
|
+
*
|
|
24
|
+
* Throws a safe, actionable `HttpRequestError` for connection failures,
|
|
25
|
+
* timeouts, non-success responses, and malformed JSON. Callers validate the
|
|
26
|
+
* returned shape themselves — typically with a zod schema — so this returns
|
|
27
|
+
* `unknown`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function postJson(url: string, body: unknown, options?: PostJsonOptions): Promise<unknown>;
|
|
30
|
+
export {};
|
package/dist/api/http.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
2
|
+
export class HttpRequestError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
status;
|
|
5
|
+
constructor(code, message, options = {}) {
|
|
6
|
+
super(message, { cause: options.cause });
|
|
7
|
+
this.name = 'Error';
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.status = options.status;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function apiOrigin(url) {
|
|
13
|
+
try {
|
|
14
|
+
return new URL(url).origin;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return 'the configured endpoint';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function timeoutError(url, timeoutMs, cause) {
|
|
21
|
+
return new HttpRequestError('HTTP_TIMEOUT', `Request to ${apiOrigin(url)} timed out after ${timeoutMs} ms. Check the network connection, then try again.`, { cause });
|
|
22
|
+
}
|
|
23
|
+
function responseError(response) {
|
|
24
|
+
const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ''}`;
|
|
25
|
+
let message;
|
|
26
|
+
if (response.status === 401 || response.status === 403) {
|
|
27
|
+
message = `Laioutr API authentication failed (${status}). Check the API key and required permissions, then try again.`;
|
|
28
|
+
}
|
|
29
|
+
else if (response.status === 404) {
|
|
30
|
+
message = `The requested Laioutr API resource was not found (${status}). Check the API host and command identifiers, then try again.`;
|
|
31
|
+
}
|
|
32
|
+
else if (response.status === 429) {
|
|
33
|
+
message = `The Laioutr API rate limit was exceeded (${status}). Wait briefly, then try again.`;
|
|
34
|
+
}
|
|
35
|
+
else if (response.status >= 500) {
|
|
36
|
+
message = `The Laioutr API is currently unavailable (${status}). Try again later.`;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
message = `The Laioutr API rejected the request (${status}). Check the command input, then try again.`;
|
|
40
|
+
}
|
|
41
|
+
return new HttpRequestError('HTTP_RESPONSE_ERROR', message, { status: response.status });
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
45
|
+
*
|
|
46
|
+
* Throws a safe, actionable `HttpRequestError` for connection failures,
|
|
47
|
+
* timeouts, non-success responses, and malformed JSON. Callers validate the
|
|
48
|
+
* returned shape themselves — typically with a zod schema — so this returns
|
|
49
|
+
* `unknown`.
|
|
50
|
+
*/
|
|
51
|
+
export async function postJson(url, body, options = {}) {
|
|
52
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
53
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
54
|
+
let response;
|
|
55
|
+
try {
|
|
56
|
+
response = await fetch(url, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/json',
|
|
60
|
+
...(options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {}),
|
|
61
|
+
...(options.userAgent ? { 'User-Agent': options.userAgent } : {}),
|
|
62
|
+
...options.headers,
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
signal,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (signal.aborted) {
|
|
70
|
+
throw timeoutError(url, timeoutMs, error);
|
|
71
|
+
}
|
|
72
|
+
throw new HttpRequestError('HTTP_NETWORK_ERROR', `Unable to reach the Laioutr API at ${apiOrigin(url)}. Check the network connection and API host, then try again.`, { cause: error });
|
|
73
|
+
}
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw responseError(response);
|
|
76
|
+
}
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = await response.text();
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (signal.aborted) {
|
|
83
|
+
throw timeoutError(url, timeoutMs, error);
|
|
84
|
+
}
|
|
85
|
+
throw new HttpRequestError('HTTP_INVALID_RESPONSE', 'The Laioutr API response could not be read. Please try again; if the problem persists, contact Laioutr support.', { cause: error, status: response.status });
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(text);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new HttpRequestError('HTTP_INVALID_RESPONSE', 'The Laioutr API returned invalid JSON. Please try again; if the problem persists, contact Laioutr support.', { cause: error, status: response.status });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -5,6 +5,7 @@ export interface ReleaseOptions {
|
|
|
5
5
|
version: string;
|
|
6
6
|
configSchema: Record<string, unknown>;
|
|
7
7
|
peerDependencies: Record<string, string>;
|
|
8
|
+
userAgent: string;
|
|
8
9
|
channel?: 'stable' | 'testing';
|
|
9
10
|
}
|
|
10
11
|
export declare const releaseAppVersion: (options: ReleaseOptions) => Promise<{
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
|
+
import { postJson } from './http.js';
|
|
2
3
|
const releaseResponseSchema = z.object({
|
|
3
4
|
message: z.string(),
|
|
4
5
|
versionId: z.string().optional(),
|
|
5
6
|
});
|
|
6
7
|
export const releaseAppVersion = async (options) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
packageName: options.packageName,
|
|
16
|
-
version: options.version,
|
|
17
|
-
configSchema: options.configSchema,
|
|
18
|
-
peerDependencies: options.peerDependencies,
|
|
19
|
-
channel: options.channel,
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
22
|
-
const body = await response.text();
|
|
23
|
-
if (response.status !== 200) {
|
|
24
|
-
throw new Error(`Release failed (${response.status}): ${body}`);
|
|
25
|
-
}
|
|
26
|
-
return releaseResponseSchema.parse(JSON.parse(body));
|
|
8
|
+
const data = await postJson(`${options.cockpitApiHost}/api/v1/app/release`, {
|
|
9
|
+
packageName: options.packageName,
|
|
10
|
+
version: options.version,
|
|
11
|
+
configSchema: options.configSchema,
|
|
12
|
+
peerDependencies: options.peerDependencies,
|
|
13
|
+
channel: options.channel,
|
|
14
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
15
|
+
return releaseResponseSchema.parse(data);
|
|
27
16
|
};
|
|
@@ -5,7 +5,8 @@ export default class AppRelease extends LaioutrBaseCommand {
|
|
|
5
5
|
static flags: {
|
|
6
6
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
7
|
channel: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
|
|
8
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
10
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -50,12 +50,13 @@ export default class AppRelease extends LaioutrBaseCommand {
|
|
|
50
50
|
this.log(`Publishing ${pkg.name}@${pkg.version}...`);
|
|
51
51
|
// 5. Call the release API
|
|
52
52
|
const result = await releaseAppVersion({
|
|
53
|
-
cockpitApiHost: flags
|
|
53
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
54
54
|
apiKey: flags.key,
|
|
55
55
|
packageName: pkg.name,
|
|
56
56
|
version: pkg.version,
|
|
57
57
|
configSchema,
|
|
58
58
|
peerDependencies,
|
|
59
|
+
userAgent: this.config.userAgent,
|
|
59
60
|
channel,
|
|
60
61
|
});
|
|
61
62
|
this.log(result.message);
|