@laioutr/cli 0.3.1 → 0.4.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 +11 -0
- package/README.md +238 -1
- package/dist/api/deploy.d.ts +65 -0
- package/dist/api/deploy.js +34 -0
- package/dist/api/fetchRc.d.ts +10 -0
- package/dist/api/fetchRc.js +19 -0
- package/dist/api/http.d.ts +14 -0
- package/dist/api/http.js +28 -0
- package/dist/api/releaseAppVersion.d.ts +13 -0
- package/dist/api/releaseAppVersion.js +16 -0
- package/dist/commands/app/release.d.ts +12 -0
- package/dist/commands/app/release.js +63 -0
- package/dist/commands/deploy/list.d.ts +31 -0
- package/dist/commands/deploy/list.js +54 -0
- package/dist/commands/deploy/logs.d.ts +22 -0
- package/dist/commands/deploy/logs.js +51 -0
- package/dist/commands/deploy/status.d.ts +30 -0
- package/dist/commands/deploy/status.js +38 -0
- package/dist/commands/deploy/trigger.d.ts +23 -0
- package/dist/commands/deploy/trigger.js +129 -0
- package/dist/commands/rc/fetch.d.ts +18 -0
- package/dist/commands/rc/fetch.js +28 -0
- package/dist/commands/rc/update.d.ts +13 -0
- package/dist/commands/rc/update.js +33 -0
- 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 +20 -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 +11 -0
- package/dist/deploy-base-command.js +27 -0
- package/dist/format/detail.d.ts +19 -0
- package/dist/format/detail.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/laioutr-base-command.d.ts +8 -0
- package/dist/laioutr-base-command.js +18 -0
- package/dist/project.d.ts +14 -0
- package/dist/project.js +16 -0
- package/dist/rc/validation.d.ts +8 -0
- package/dist/rc/validation.js +8 -0
- package/oclif.manifest.json +543 -2
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @laioutr/cli
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 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).
|
|
8
|
+
|
|
9
|
+
- `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`.
|
|
10
|
+
- `laioutr deploy status` — show a deployment's status, environment, URL, and who created it.
|
|
11
|
+
- `laioutr deploy list` — list recent deployments for a project (`--limit`, default 20, max 100).
|
|
12
|
+
- `laioutr deploy logs` — fetch and follow a deployment's build logs.
|
|
13
|
+
|
|
3
14
|
## 0.3.1
|
|
4
15
|
|
|
5
16
|
### 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.0 linux-x64 node-v24.18.0
|
|
24
24
|
$ laioutr --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ laioutr COMMAND
|
|
@@ -31,6 +31,11 @@ USAGE
|
|
|
31
31
|
# Commands
|
|
32
32
|
|
|
33
33
|
<!-- commands -->
|
|
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)
|
|
34
39
|
* [`laioutr help [COMMAND]`](#laioutr-help-command)
|
|
35
40
|
* [`laioutr plugins`](#laioutr-plugins)
|
|
36
41
|
* [`laioutr plugins add PLUGIN`](#laioutr-plugins-add-plugin)
|
|
@@ -42,6 +47,163 @@ USAGE
|
|
|
42
47
|
* [`laioutr plugins uninstall [PLUGIN]`](#laioutr-plugins-uninstall-plugin)
|
|
43
48
|
* [`laioutr plugins unlink [PLUGIN]`](#laioutr-plugins-unlink-plugin)
|
|
44
49
|
* [`laioutr plugins update`](#laioutr-plugins-update)
|
|
50
|
+
* [`laioutr project fetch-rc [FILENAME]`](#laioutr-project-fetch-rc-filename)
|
|
51
|
+
* [`laioutr rc fetch [FILENAME]`](#laioutr-rc-fetch-filename)
|
|
52
|
+
* [`laioutr rc update [FILENAME]`](#laioutr-rc-update-filename)
|
|
53
|
+
|
|
54
|
+
## `laioutr app release`
|
|
55
|
+
|
|
56
|
+
Publish an app version to the Laioutr platform.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
USAGE
|
|
60
|
+
$ laioutr app release --cockpitApiHost <value> --cwd <value> -k <value> [-c stable|testing]
|
|
61
|
+
|
|
62
|
+
FLAGS
|
|
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
|
+
--cockpitApiHost=<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
|
+
|
|
70
|
+
DESCRIPTION
|
|
71
|
+
Publish an app version to the Laioutr platform.
|
|
72
|
+
|
|
73
|
+
EXAMPLES
|
|
74
|
+
$ laioutr app release
|
|
75
|
+
|
|
76
|
+
$ laioutr app release --channel testing
|
|
77
|
+
|
|
78
|
+
LAIOUTR_API_KEY=orgKey_xxx laioutr app release
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/app/release.ts)_
|
|
82
|
+
|
|
83
|
+
## `laioutr deploy list`
|
|
84
|
+
|
|
85
|
+
List recent deployments for a project.
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
USAGE
|
|
89
|
+
$ laioutr deploy list --cockpitApiHost <value> --cwd <value> -p <value> -k <value> [--json] [--limit <value>]
|
|
90
|
+
|
|
91
|
+
FLAGS
|
|
92
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
93
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
94
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
95
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
96
|
+
directory
|
|
97
|
+
--limit=<value> [default: 20] Maximum number of deployments to list (1-100)
|
|
98
|
+
|
|
99
|
+
GLOBAL FLAGS
|
|
100
|
+
--json Format output as json.
|
|
101
|
+
|
|
102
|
+
DESCRIPTION
|
|
103
|
+
List recent deployments for a project.
|
|
104
|
+
|
|
105
|
+
EXAMPLES
|
|
106
|
+
$ laioutr deploy list --project org/project --key orgKey_xxx
|
|
107
|
+
|
|
108
|
+
$ laioutr deploy list --project org/project --key orgKey_xxx --limit 50
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
_See code: [src/commands/deploy/list.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/deploy/list.ts)_
|
|
112
|
+
|
|
113
|
+
## `laioutr deploy logs`
|
|
114
|
+
|
|
115
|
+
Fetch and display build logs for a deployment.
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
USAGE
|
|
119
|
+
$ laioutr deploy logs --cockpitApiHost <value> --cwd <value> -p <value> -k <value> --deploymentId <value>
|
|
120
|
+
[--json]
|
|
121
|
+
|
|
122
|
+
FLAGS
|
|
123
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
124
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
125
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
126
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
127
|
+
directory
|
|
128
|
+
--deploymentId=<value> (required) Deployment ID
|
|
129
|
+
|
|
130
|
+
GLOBAL FLAGS
|
|
131
|
+
--json Format output as json.
|
|
132
|
+
|
|
133
|
+
DESCRIPTION
|
|
134
|
+
Fetch and display build logs for a deployment.
|
|
135
|
+
|
|
136
|
+
EXAMPLES
|
|
137
|
+
$ laioutr deploy logs --project org/project --key orgKey_xxx --deploymentId dep_abc123
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
_See code: [src/commands/deploy/logs.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/deploy/logs.ts)_
|
|
141
|
+
|
|
142
|
+
## `laioutr deploy status`
|
|
143
|
+
|
|
144
|
+
Show status of a deployment.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
USAGE
|
|
148
|
+
$ laioutr deploy status --cockpitApiHost <value> --cwd <value> -p <value> -k <value> --deploymentId <value>
|
|
149
|
+
[--json]
|
|
150
|
+
|
|
151
|
+
FLAGS
|
|
152
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
153
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
154
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
155
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
156
|
+
directory
|
|
157
|
+
--deploymentId=<value> (required) Deployment ID
|
|
158
|
+
|
|
159
|
+
GLOBAL FLAGS
|
|
160
|
+
--json Format output as json.
|
|
161
|
+
|
|
162
|
+
DESCRIPTION
|
|
163
|
+
Show status of a deployment.
|
|
164
|
+
|
|
165
|
+
EXAMPLES
|
|
166
|
+
$ laioutr deploy status --project org/project --key orgKey_xxx --deploymentId dep_abc123
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
_See code: [src/commands/deploy/status.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/deploy/status.ts)_
|
|
170
|
+
|
|
171
|
+
## `laioutr deploy trigger`
|
|
172
|
+
|
|
173
|
+
Trigger a project deployment.
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
USAGE
|
|
177
|
+
$ laioutr deploy trigger --cockpitApiHost <value> --cwd <value> -p <value> -k <value> [--json] [--wait] [--logs]
|
|
178
|
+
[--preview <value>]
|
|
179
|
+
|
|
180
|
+
FLAGS
|
|
181
|
+
-k, --key=<value> (required) Organization API key with project:deploy scope
|
|
182
|
+
-p, --project=<value> (required) Project identifier in org/project format
|
|
183
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
184
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
185
|
+
directory
|
|
186
|
+
--logs Stream build log output instead of spinner
|
|
187
|
+
--preview=<value> Create a preview deployment with optional name
|
|
188
|
+
--[no-]wait Wait for deployment to complete
|
|
189
|
+
|
|
190
|
+
GLOBAL FLAGS
|
|
191
|
+
--json Format output as json.
|
|
192
|
+
|
|
193
|
+
DESCRIPTION
|
|
194
|
+
Trigger a project deployment.
|
|
195
|
+
|
|
196
|
+
EXAMPLES
|
|
197
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx
|
|
198
|
+
|
|
199
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --no-wait
|
|
200
|
+
|
|
201
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --logs
|
|
202
|
+
|
|
203
|
+
$ laioutr deploy trigger --project org/project --key orgKey_xxx --preview my-feature
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
_See code: [src/commands/deploy/trigger.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/deploy/trigger.ts)_
|
|
45
207
|
|
|
46
208
|
## `laioutr help [COMMAND]`
|
|
47
209
|
|
|
@@ -352,4 +514,79 @@ DESCRIPTION
|
|
|
352
514
|
```
|
|
353
515
|
|
|
354
516
|
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.41/src/commands/plugins/update.ts)_
|
|
517
|
+
|
|
518
|
+
## `laioutr project fetch-rc [FILENAME]`
|
|
519
|
+
|
|
520
|
+
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
521
|
+
|
|
522
|
+
```
|
|
523
|
+
USAGE
|
|
524
|
+
$ laioutr project fetch-rc [FILENAME] --cockpitApiHost <value> --cwd <value> -e <value> -s <value> -p <value>
|
|
525
|
+
|
|
526
|
+
FLAGS
|
|
527
|
+
-e, --environmentName=<value> (required) [default: main] environment name
|
|
528
|
+
-p, --project=<value> (required) <organization slug>/<project slug>
|
|
529
|
+
-s, --projectSecret=<value> (required) project secret
|
|
530
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
531
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
532
|
+
directory
|
|
533
|
+
|
|
534
|
+
DESCRIPTION
|
|
535
|
+
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
536
|
+
|
|
537
|
+
ALIASES
|
|
538
|
+
$ laioutr project fetch-rc
|
|
539
|
+
|
|
540
|
+
EXAMPLES
|
|
541
|
+
$ laioutr project fetch-rc
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## `laioutr rc fetch [FILENAME]`
|
|
545
|
+
|
|
546
|
+
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
USAGE
|
|
550
|
+
$ laioutr rc fetch [FILENAME] --cockpitApiHost <value> --cwd <value> -e <value> -s <value> -p <value>
|
|
551
|
+
|
|
552
|
+
FLAGS
|
|
553
|
+
-e, --environmentName=<value> (required) [default: main] environment name
|
|
554
|
+
-p, --project=<value> (required) <organization slug>/<project slug>
|
|
555
|
+
-s, --projectSecret=<value> (required) project secret
|
|
556
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
557
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working
|
|
558
|
+
directory
|
|
559
|
+
|
|
560
|
+
DESCRIPTION
|
|
561
|
+
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
562
|
+
|
|
563
|
+
ALIASES
|
|
564
|
+
$ laioutr project fetch-rc
|
|
565
|
+
|
|
566
|
+
EXAMPLES
|
|
567
|
+
$ laioutr rc fetch
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/rc/fetch.ts)_
|
|
571
|
+
|
|
572
|
+
## `laioutr rc update [FILENAME]`
|
|
573
|
+
|
|
574
|
+
Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
575
|
+
|
|
576
|
+
```
|
|
577
|
+
USAGE
|
|
578
|
+
$ laioutr rc update [FILENAME] --cockpitApiHost <value> --cwd <value>
|
|
579
|
+
|
|
580
|
+
FLAGS
|
|
581
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
582
|
+
--cwd=<value> (required) [default: /home/runner/work/laioutr/laioutr/apps/cli] current working directory
|
|
583
|
+
|
|
584
|
+
DESCRIPTION
|
|
585
|
+
Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
586
|
+
|
|
587
|
+
EXAMPLES
|
|
588
|
+
$ laioutr rc update
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.4.0/src/commands/rc/update.ts)_
|
|
355
592
|
<!-- commandsstop -->
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface DeployApiOptions {
|
|
2
|
+
cockpitApiHost: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
organizationSlug: string;
|
|
5
|
+
projectSlug: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TriggerOptions extends DeployApiOptions {
|
|
8
|
+
previewName?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function triggerDeployment(options: TriggerOptions): Promise<{
|
|
11
|
+
deploymentId: string;
|
|
12
|
+
status: string;
|
|
13
|
+
environment: string;
|
|
14
|
+
previewName: string | null;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function fetchDeploymentStatus(options: DeployApiOptions & {
|
|
17
|
+
deploymentId: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
deploymentId: string;
|
|
20
|
+
status: string;
|
|
21
|
+
environment: string;
|
|
22
|
+
previewName: string | null;
|
|
23
|
+
url: string | null;
|
|
24
|
+
lastError: string | null;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
stoppedAt: string | null;
|
|
27
|
+
attribution: {
|
|
28
|
+
principalType: "user" | "api-key" | "system";
|
|
29
|
+
displayName: string;
|
|
30
|
+
email: string | null;
|
|
31
|
+
agentName: string | null;
|
|
32
|
+
redacted: boolean;
|
|
33
|
+
} | null;
|
|
34
|
+
}>;
|
|
35
|
+
export declare function fetchDeployments(options: DeployApiOptions & {
|
|
36
|
+
limit?: number;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
deployments: {
|
|
39
|
+
deploymentId: string;
|
|
40
|
+
status: string;
|
|
41
|
+
environment: string;
|
|
42
|
+
previewName: string | null;
|
|
43
|
+
url: string | null;
|
|
44
|
+
createdAt: string;
|
|
45
|
+
stoppedAt: string | null;
|
|
46
|
+
attribution: {
|
|
47
|
+
principalType: "user" | "api-key" | "system";
|
|
48
|
+
displayName: string;
|
|
49
|
+
email: string | null;
|
|
50
|
+
agentName: string | null;
|
|
51
|
+
redacted: boolean;
|
|
52
|
+
} | null;
|
|
53
|
+
}[];
|
|
54
|
+
}>;
|
|
55
|
+
export declare function fetchDeploymentLogs(options: DeployApiOptions & {
|
|
56
|
+
deploymentId: string;
|
|
57
|
+
}): Promise<{
|
|
58
|
+
lines: {
|
|
59
|
+
text: string;
|
|
60
|
+
level?: "error" | "warning" | null | undefined;
|
|
61
|
+
timestamp?: number | null | undefined;
|
|
62
|
+
}[] | null;
|
|
63
|
+
supported: boolean;
|
|
64
|
+
deploymentStatus: string;
|
|
65
|
+
}>;
|
|
@@ -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 });
|
|
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 });
|
|
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 });
|
|
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 });
|
|
33
|
+
return deploymentLogsResponseSchema.parse(data);
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface HostApiOptions {
|
|
2
|
+
cockpitApiHost: string;
|
|
3
|
+
}
|
|
4
|
+
export interface ProjectApiOptions extends HostApiOptions {
|
|
5
|
+
project: string;
|
|
6
|
+
projectSecret: string;
|
|
7
|
+
environmentName: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const fetchRc: (flags: ProjectApiOptions) => Promise<string>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { postJson } from './http.js';
|
|
3
|
+
import { parseProjectSlug } from '../project.js';
|
|
4
|
+
const apiResponseSchema = z.object({
|
|
5
|
+
content: z.string(),
|
|
6
|
+
});
|
|
7
|
+
export const fetchRc = async (flags) => {
|
|
8
|
+
const parsed = parseProjectSlug(flags.project);
|
|
9
|
+
if (!parsed) {
|
|
10
|
+
throw new Error(`Invalid project "${flags.project}" — expected <organization slug>/<project slug>.`);
|
|
11
|
+
}
|
|
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
|
+
});
|
|
18
|
+
return apiResponseSchema.parse(data).content;
|
|
19
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PostJsonOptions {
|
|
2
|
+
/** When set, sent as an `Authorization: Bearer <apiKey>` header. */
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
/** Extra headers, merged over the defaults (`Content-Type` + auth). */
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
9
|
+
*
|
|
10
|
+
* Throws if the response status is not 200 (the message carries the status and
|
|
11
|
+
* raw body) or if the body is not valid JSON. Callers validate the returned
|
|
12
|
+
* shape themselves — typically with a zod schema — so this returns `unknown`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function postJson(url: string, body: unknown, options?: PostJsonOptions): Promise<unknown>;
|
package/dist/api/http.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
3
|
+
*
|
|
4
|
+
* Throws if the response status is not 200 (the message carries the status and
|
|
5
|
+
* raw body) or if the body is not valid JSON. Callers validate the returned
|
|
6
|
+
* shape themselves — typically with a zod schema — so this returns `unknown`.
|
|
7
|
+
*/
|
|
8
|
+
export async function postJson(url, body, options = {}) {
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
...(options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {}),
|
|
14
|
+
...options.headers,
|
|
15
|
+
},
|
|
16
|
+
body: JSON.stringify(body),
|
|
17
|
+
});
|
|
18
|
+
const text = await response.text();
|
|
19
|
+
if (response.status !== 200) {
|
|
20
|
+
throw new Error(`Request failed (${response.status}): ${text}`);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(text);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error(`Failed to parse JSON response from ${url}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ReleaseOptions {
|
|
2
|
+
cockpitApiHost: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
packageName: string;
|
|
5
|
+
version: string;
|
|
6
|
+
configSchema: Record<string, unknown>;
|
|
7
|
+
peerDependencies: Record<string, string>;
|
|
8
|
+
channel?: 'stable' | 'testing';
|
|
9
|
+
}
|
|
10
|
+
export declare const releaseAppVersion: (options: ReleaseOptions) => Promise<{
|
|
11
|
+
message: string;
|
|
12
|
+
versionId?: string | undefined;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { postJson } from './http.js';
|
|
3
|
+
const releaseResponseSchema = z.object({
|
|
4
|
+
message: z.string(),
|
|
5
|
+
versionId: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
export const releaseAppVersion = async (options) => {
|
|
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 });
|
|
15
|
+
return releaseResponseSchema.parse(data);
|
|
16
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import LaioutrBaseCommand from '../../laioutr-base-command.js';
|
|
2
|
+
export default class AppRelease extends LaioutrBaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
channel: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
cockpitApiHost: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
import { releaseAppVersion } from '../../api/releaseAppVersion.js';
|
|
5
|
+
import LaioutrBaseCommand from '../../laioutr-base-command.js';
|
|
6
|
+
export default class AppRelease extends LaioutrBaseCommand {
|
|
7
|
+
static description = 'Publish an app version to the Laioutr platform.';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> app release',
|
|
10
|
+
'<%= config.bin %> app release --channel testing',
|
|
11
|
+
'LAIOUTR_API_KEY=orgKey_xxx <%= config.bin %> app release',
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
...LaioutrBaseCommand.flags,
|
|
15
|
+
key: Flags.string({
|
|
16
|
+
char: 'k',
|
|
17
|
+
description: 'API key for authentication',
|
|
18
|
+
env: 'LAIOUTR_API_KEY',
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
channel: Flags.string({
|
|
22
|
+
char: 'c',
|
|
23
|
+
description: 'Release channel (auto-detected from version if omitted)',
|
|
24
|
+
options: ['stable', 'testing'],
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { flags } = await this.parse(AppRelease);
|
|
29
|
+
// 1. Read package.json
|
|
30
|
+
const pkgPath = path.join(flags.cwd, 'package.json');
|
|
31
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
32
|
+
if (!pkg.name || !pkg.version) {
|
|
33
|
+
this.error('package.json must have "name" and "version" fields');
|
|
34
|
+
}
|
|
35
|
+
// 2. Import configSchema via jiti
|
|
36
|
+
let configSchema = {};
|
|
37
|
+
try {
|
|
38
|
+
const { createJiti } = await import('jiti');
|
|
39
|
+
const jiti = createJiti(flags.cwd);
|
|
40
|
+
const mod = await jiti.import(path.join(flags.cwd, 'src/module.ts'));
|
|
41
|
+
configSchema = mod.configSchema ?? {};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
this.warn('Could not import configSchema from src/module.ts — publishing without config schema');
|
|
45
|
+
}
|
|
46
|
+
// 3. Extract peer dependencies
|
|
47
|
+
const peerDependencies = pkg.peerDependencies ?? {};
|
|
48
|
+
// 4. Detect channel
|
|
49
|
+
const channel = flags.channel;
|
|
50
|
+
this.log(`Publishing ${pkg.name}@${pkg.version}...`);
|
|
51
|
+
// 5. Call the release API
|
|
52
|
+
const result = await releaseAppVersion({
|
|
53
|
+
cockpitApiHost: flags.cockpitApiHost,
|
|
54
|
+
apiKey: flags.key,
|
|
55
|
+
packageName: pkg.name,
|
|
56
|
+
version: pkg.version,
|
|
57
|
+
configSchema,
|
|
58
|
+
peerDependencies,
|
|
59
|
+
channel,
|
|
60
|
+
});
|
|
61
|
+
this.log(result.message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import DeployBaseCommand from '../../deploy-base-command.js';
|
|
2
|
+
export default class DeployList extends DeployBaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
cockpitApiHost: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<{
|
|
14
|
+
deployments: {
|
|
15
|
+
deploymentId: string;
|
|
16
|
+
status: string;
|
|
17
|
+
environment: string;
|
|
18
|
+
previewName: string | null;
|
|
19
|
+
url: string | null;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
stoppedAt: string | null;
|
|
22
|
+
attribution: {
|
|
23
|
+
principalType: "user" | "api-key" | "system";
|
|
24
|
+
displayName: string;
|
|
25
|
+
email: string | null;
|
|
26
|
+
agentName: string | null;
|
|
27
|
+
redacted: boolean;
|
|
28
|
+
} | null;
|
|
29
|
+
}[];
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { makeTable } from '@oclif/table';
|
|
3
|
+
import { fetchDeployments } from '../../api/deploy.js';
|
|
4
|
+
import { formatAttribution } from '../../deploy/attribution.js';
|
|
5
|
+
import DeployBaseCommand from '../../deploy-base-command.js';
|
|
6
|
+
export default class DeployList extends DeployBaseCommand {
|
|
7
|
+
static description = 'List recent deployments for a project.';
|
|
8
|
+
static enableJsonFlag = true;
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> deploy list --project org/project --key orgKey_xxx',
|
|
11
|
+
'<%= config.bin %> deploy list --project org/project --key orgKey_xxx --limit 50',
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
...DeployBaseCommand.flags,
|
|
15
|
+
limit: Flags.integer({
|
|
16
|
+
default: 20,
|
|
17
|
+
description: 'Maximum number of deployments to list (1-100)',
|
|
18
|
+
max: 100,
|
|
19
|
+
min: 1,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { flags } = await this.parse(DeployList);
|
|
24
|
+
const { organizationSlug, projectSlug } = this.parseProject(flags.project);
|
|
25
|
+
const result = await fetchDeployments({
|
|
26
|
+
cockpitApiHost: flags.cockpitApiHost,
|
|
27
|
+
apiKey: flags.key,
|
|
28
|
+
organizationSlug,
|
|
29
|
+
projectSlug,
|
|
30
|
+
limit: flags.limit,
|
|
31
|
+
});
|
|
32
|
+
if (result.deployments.length === 0) {
|
|
33
|
+
this.log('No deployments found.');
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
const rows = result.deployments.map((d) => ({
|
|
37
|
+
ID: d.deploymentId,
|
|
38
|
+
Type: d.environment,
|
|
39
|
+
Preview: d.previewName ?? '—',
|
|
40
|
+
Status: d.status,
|
|
41
|
+
URL: d.url ?? '—',
|
|
42
|
+
'Created by': formatAttribution(d.attribution),
|
|
43
|
+
}));
|
|
44
|
+
this.log(makeTable({
|
|
45
|
+
data: rows,
|
|
46
|
+
// Keep our exact header casing (ID / URL / Created by) instead of the
|
|
47
|
+
// default case-formatter, and truncate the middle of long cells (URLs)
|
|
48
|
+
// so both ends stay visible.
|
|
49
|
+
headerOptions: { formatter: (header) => header },
|
|
50
|
+
overflow: 'truncate-middle',
|
|
51
|
+
}));
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import DeployBaseCommand from '../../deploy-base-command.js';
|
|
2
|
+
export default class DeployLogs extends DeployBaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
deploymentId: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
cockpitApiHost: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<{
|
|
14
|
+
lines: {
|
|
15
|
+
text: string;
|
|
16
|
+
level?: "error" | "warning" | null | undefined;
|
|
17
|
+
timestamp?: number | null | undefined;
|
|
18
|
+
}[] | null;
|
|
19
|
+
supported: boolean;
|
|
20
|
+
deploymentStatus: string;
|
|
21
|
+
}>;
|
|
22
|
+
}
|