@laioutr/cli 0.4.0 → 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 +6 -0
- package/README.md +78 -67
- package/dist/api/deploy.d.ts +1 -0
- package/dist/api/deploy.js +4 -4
- package/dist/api/fetchRc.d.ts +1 -0
- package/dist/api/fetchRc.js +1 -1
- package/dist/api/http.d.ts +19 -3
- package/dist/api/http.js +82 -17
- package/dist/api/releaseAppVersion.d.ts +1 -0
- package/dist/api/releaseAppVersion.js +1 -1
- package/dist/commands/app/release.d.ts +2 -1
- package/dist/commands/app/release.js +2 -1
- package/dist/commands/deploy/list.d.ts +2 -1
- package/dist/commands/deploy/list.js +2 -1
- package/dist/commands/deploy/logs.d.ts +3 -2
- package/dist/commands/deploy/logs.js +8 -5
- package/dist/commands/deploy/status.d.ts +3 -2
- package/dist/commands/deploy/status.js +7 -4
- package/dist/commands/deploy/trigger.d.ts +2 -1
- package/dist/commands/deploy/trigger.js +2 -1
- 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/log-renderer.js +2 -1
- package/dist/deploy-base-command.d.ts +2 -1
- package/dist/format/color.d.ts +5 -0
- package/dist/format/color.js +10 -0
- package/dist/laioutr-base-command.d.ts +9 -1
- package/dist/laioutr-base-command.js +21 -3
- package/oclif.manifest.json +127 -41
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
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
|
+
|
|
3
9
|
## 0.4.0
|
|
4
10
|
|
|
5
11
|
### Minor 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.4.
|
|
23
|
+
@laioutr/cli/0.4.1 linux-x64 node-v24.18.0
|
|
24
24
|
$ laioutr --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ laioutr COMMAND
|
|
@@ -57,15 +57,16 @@ Publish an app version to the Laioutr platform.
|
|
|
57
57
|
|
|
58
58
|
```
|
|
59
59
|
USAGE
|
|
60
|
-
$ laioutr app release --
|
|
60
|
+
$ laioutr app release --cockpit-api-host <value> --cwd <value> -k <value> [--no-color] [-c stable|testing]
|
|
61
61
|
|
|
62
62
|
FLAGS
|
|
63
|
-
-c, --channel=<option>
|
|
64
|
-
|
|
65
|
-
-k, --key=<value>
|
|
66
|
-
--
|
|
67
|
-
--cwd=<value>
|
|
68
|
-
|
|
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
|
|
69
70
|
|
|
70
71
|
DESCRIPTION
|
|
71
72
|
Publish an app version to the Laioutr platform.
|
|
@@ -78,7 +79,7 @@ EXAMPLES
|
|
|
78
79
|
LAIOUTR_API_KEY=orgKey_xxx laioutr app release
|
|
79
80
|
```
|
|
80
81
|
|
|
81
|
-
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
82
|
+
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/app/release.ts)_
|
|
82
83
|
|
|
83
84
|
## `laioutr deploy list`
|
|
84
85
|
|
|
@@ -86,15 +87,17 @@ List recent deployments for a project.
|
|
|
86
87
|
|
|
87
88
|
```
|
|
88
89
|
USAGE
|
|
89
|
-
$ laioutr deploy list --
|
|
90
|
+
$ laioutr deploy list --cockpit-api-host <value> --cwd <value> -p <value> -k <value> [--json] [--no-color]
|
|
91
|
+
[--limit <value>]
|
|
90
92
|
|
|
91
93
|
FLAGS
|
|
92
|
-
-k, --key=<value>
|
|
93
|
-
-p, --project=<value>
|
|
94
|
-
--
|
|
95
|
-
--cwd=<value>
|
|
96
|
-
|
|
97
|
-
--limit=<value>
|
|
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
|
|
98
101
|
|
|
99
102
|
GLOBAL FLAGS
|
|
100
103
|
--json Format output as json.
|
|
@@ -108,7 +111,7 @@ EXAMPLES
|
|
|
108
111
|
$ laioutr deploy list --project org/project --key orgKey_xxx --limit 50
|
|
109
112
|
```
|
|
110
113
|
|
|
111
|
-
_See code: [src/commands/deploy/list.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
114
|
+
_See code: [src/commands/deploy/list.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/list.ts)_
|
|
112
115
|
|
|
113
116
|
## `laioutr deploy logs`
|
|
114
117
|
|
|
@@ -116,16 +119,17 @@ Fetch and display build logs for a deployment.
|
|
|
116
119
|
|
|
117
120
|
```
|
|
118
121
|
USAGE
|
|
119
|
-
$ laioutr deploy logs --
|
|
120
|
-
[--json]
|
|
122
|
+
$ laioutr deploy logs --cockpit-api-host <value> --cwd <value> -p <value> -k <value> --deployment-id <value>
|
|
123
|
+
[--json] [--no-color]
|
|
121
124
|
|
|
122
125
|
FLAGS
|
|
123
|
-
-k, --key=<value>
|
|
124
|
-
-p, --project=<value>
|
|
125
|
-
--
|
|
126
|
-
--cwd=<value>
|
|
127
|
-
|
|
128
|
-
--
|
|
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
|
|
129
133
|
|
|
130
134
|
GLOBAL FLAGS
|
|
131
135
|
--json Format output as json.
|
|
@@ -134,10 +138,10 @@ DESCRIPTION
|
|
|
134
138
|
Fetch and display build logs for a deployment.
|
|
135
139
|
|
|
136
140
|
EXAMPLES
|
|
137
|
-
$ laioutr deploy logs --project org/project --key orgKey_xxx --
|
|
141
|
+
$ laioutr deploy logs --project org/project --key orgKey_xxx --deployment-id dep_abc123
|
|
138
142
|
```
|
|
139
143
|
|
|
140
|
-
_See code: [src/commands/deploy/logs.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
144
|
+
_See code: [src/commands/deploy/logs.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/logs.ts)_
|
|
141
145
|
|
|
142
146
|
## `laioutr deploy status`
|
|
143
147
|
|
|
@@ -145,16 +149,17 @@ Show status of a deployment.
|
|
|
145
149
|
|
|
146
150
|
```
|
|
147
151
|
USAGE
|
|
148
|
-
$ laioutr deploy status --
|
|
149
|
-
[--json]
|
|
152
|
+
$ laioutr deploy status --cockpit-api-host <value> --cwd <value> -p <value> -k <value> --deployment-id <value>
|
|
153
|
+
[--json] [--no-color]
|
|
150
154
|
|
|
151
155
|
FLAGS
|
|
152
|
-
-k, --key=<value>
|
|
153
|
-
-p, --project=<value>
|
|
154
|
-
--
|
|
155
|
-
--cwd=<value>
|
|
156
|
-
|
|
157
|
-
--
|
|
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
|
|
158
163
|
|
|
159
164
|
GLOBAL FLAGS
|
|
160
165
|
--json Format output as json.
|
|
@@ -163,10 +168,10 @@ DESCRIPTION
|
|
|
163
168
|
Show status of a deployment.
|
|
164
169
|
|
|
165
170
|
EXAMPLES
|
|
166
|
-
$ laioutr deploy status --project org/project --key orgKey_xxx --
|
|
171
|
+
$ laioutr deploy status --project org/project --key orgKey_xxx --deployment-id dep_abc123
|
|
167
172
|
```
|
|
168
173
|
|
|
169
|
-
_See code: [src/commands/deploy/status.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
174
|
+
_See code: [src/commands/deploy/status.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/status.ts)_
|
|
170
175
|
|
|
171
176
|
## `laioutr deploy trigger`
|
|
172
177
|
|
|
@@ -174,18 +179,19 @@ Trigger a project deployment.
|
|
|
174
179
|
|
|
175
180
|
```
|
|
176
181
|
USAGE
|
|
177
|
-
$ laioutr deploy trigger --
|
|
178
|
-
[--preview <value>]
|
|
182
|
+
$ laioutr deploy trigger --cockpit-api-host <value> --cwd <value> -p <value> -k <value> [--json] [--no-color]
|
|
183
|
+
[--wait] [--logs] [--preview <value>]
|
|
179
184
|
|
|
180
185
|
FLAGS
|
|
181
|
-
-k, --key=<value>
|
|
182
|
-
-p, --project=<value>
|
|
183
|
-
--
|
|
184
|
-
--cwd=<value>
|
|
185
|
-
|
|
186
|
-
--logs
|
|
187
|
-
--
|
|
188
|
-
--
|
|
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
|
|
189
195
|
|
|
190
196
|
GLOBAL FLAGS
|
|
191
197
|
--json Format output as json.
|
|
@@ -203,7 +209,7 @@ EXAMPLES
|
|
|
203
209
|
$ laioutr deploy trigger --project org/project --key orgKey_xxx --preview my-feature
|
|
204
210
|
```
|
|
205
211
|
|
|
206
|
-
_See code: [src/commands/deploy/trigger.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
212
|
+
_See code: [src/commands/deploy/trigger.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/deploy/trigger.ts)_
|
|
207
213
|
|
|
208
214
|
## `laioutr help [COMMAND]`
|
|
209
215
|
|
|
@@ -521,15 +527,17 @@ Fetches the laioutrrc.json of a project from the cockpit api.
|
|
|
521
527
|
|
|
522
528
|
```
|
|
523
529
|
USAGE
|
|
524
|
-
$ 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]
|
|
525
532
|
|
|
526
533
|
FLAGS
|
|
527
|
-
-e, --
|
|
528
|
-
-p, --project=<value>
|
|
529
|
-
-s, --
|
|
530
|
-
--
|
|
531
|
-
--cwd=<value>
|
|
532
|
-
|
|
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
|
|
533
541
|
|
|
534
542
|
DESCRIPTION
|
|
535
543
|
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
@@ -547,15 +555,17 @@ Fetches the laioutrrc.json of a project from the cockpit api.
|
|
|
547
555
|
|
|
548
556
|
```
|
|
549
557
|
USAGE
|
|
550
|
-
$ laioutr rc fetch [FILENAME] --
|
|
558
|
+
$ laioutr rc fetch [FILENAME] --cockpit-api-host <value> --cwd <value> -e <value> -s <value> -p <value>
|
|
559
|
+
[--no-color]
|
|
551
560
|
|
|
552
561
|
FLAGS
|
|
553
|
-
-e, --
|
|
554
|
-
-p, --project=<value>
|
|
555
|
-
-s, --
|
|
556
|
-
--
|
|
557
|
-
--cwd=<value>
|
|
558
|
-
|
|
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
|
|
559
569
|
|
|
560
570
|
DESCRIPTION
|
|
561
571
|
Fetches the laioutrrc.json of a project from the cockpit api.
|
|
@@ -567,7 +577,7 @@ EXAMPLES
|
|
|
567
577
|
$ laioutr rc fetch
|
|
568
578
|
```
|
|
569
579
|
|
|
570
|
-
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
580
|
+
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/rc/fetch.ts)_
|
|
571
581
|
|
|
572
582
|
## `laioutr rc update [FILENAME]`
|
|
573
583
|
|
|
@@ -575,11 +585,12 @@ Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
|
575
585
|
|
|
576
586
|
```
|
|
577
587
|
USAGE
|
|
578
|
-
$ laioutr rc update [FILENAME] --
|
|
588
|
+
$ laioutr rc update [FILENAME] --cockpit-api-host <value> --cwd <value> [--no-color]
|
|
579
589
|
|
|
580
590
|
FLAGS
|
|
581
|
-
--
|
|
582
|
-
--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
|
|
583
594
|
|
|
584
595
|
DESCRIPTION
|
|
585
596
|
Updates an existing laioutrrc.json file with the latest from the cockpit api.
|
|
@@ -588,5 +599,5 @@ EXAMPLES
|
|
|
588
599
|
$ laioutr rc update
|
|
589
600
|
```
|
|
590
601
|
|
|
591
|
-
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.4.
|
|
602
|
+
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.4.1/src/commands/rc/update.ts)_
|
|
592
603
|
<!-- commandsstop -->
|
package/dist/api/deploy.d.ts
CHANGED
package/dist/api/deploy.js
CHANGED
|
@@ -5,7 +5,7 @@ export async function triggerDeployment(options) {
|
|
|
5
5
|
organizationSlug: options.organizationSlug,
|
|
6
6
|
projectSlug: options.projectSlug,
|
|
7
7
|
previewName: options.previewName,
|
|
8
|
-
}, { apiKey: options.apiKey });
|
|
8
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
9
9
|
return deployTriggerResponseSchema.parse(data);
|
|
10
10
|
}
|
|
11
11
|
export async function fetchDeploymentStatus(options) {
|
|
@@ -13,7 +13,7 @@ export async function fetchDeploymentStatus(options) {
|
|
|
13
13
|
organizationSlug: options.organizationSlug,
|
|
14
14
|
projectSlug: options.projectSlug,
|
|
15
15
|
deploymentId: options.deploymentId,
|
|
16
|
-
}, { apiKey: options.apiKey });
|
|
16
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
17
17
|
return deploymentStatusResponseSchema.parse(data);
|
|
18
18
|
}
|
|
19
19
|
export async function fetchDeployments(options) {
|
|
@@ -21,7 +21,7 @@ export async function fetchDeployments(options) {
|
|
|
21
21
|
organizationSlug: options.organizationSlug,
|
|
22
22
|
projectSlug: options.projectSlug,
|
|
23
23
|
limit: options.limit,
|
|
24
|
-
}, { apiKey: options.apiKey });
|
|
24
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
25
25
|
return deploymentsListResponseSchema.parse(data);
|
|
26
26
|
}
|
|
27
27
|
export async function fetchDeploymentLogs(options) {
|
|
@@ -29,6 +29,6 @@ export async function fetchDeploymentLogs(options) {
|
|
|
29
29
|
organizationSlug: options.organizationSlug,
|
|
30
30
|
projectSlug: options.projectSlug,
|
|
31
31
|
deploymentId: options.deploymentId,
|
|
32
|
-
}, { apiKey: options.apiKey });
|
|
32
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
33
33
|
return deploymentLogsResponseSchema.parse(data);
|
|
34
34
|
}
|
package/dist/api/fetchRc.d.ts
CHANGED
package/dist/api/fetchRc.js
CHANGED
|
@@ -14,6 +14,6 @@ export const fetchRc = async (flags) => {
|
|
|
14
14
|
organizationSlug: parsed.organizationSlug,
|
|
15
15
|
projectSecret: flags.projectSecret,
|
|
16
16
|
projectSlug: parsed.projectSlug,
|
|
17
|
-
});
|
|
17
|
+
}, { userAgent: flags.userAgent });
|
|
18
18
|
return apiResponseSchema.parse(data).content;
|
|
19
19
|
};
|
package/dist/api/http.d.ts
CHANGED
|
@@ -1,14 +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
|
+
}
|
|
1
11
|
export interface PostJsonOptions {
|
|
2
12
|
/** When set, sent as an `Authorization: Bearer <apiKey>` header. */
|
|
3
13
|
apiKey?: string;
|
|
4
14
|
/** Extra headers, merged over the defaults (`Content-Type` + auth). */
|
|
5
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;
|
|
6
20
|
}
|
|
7
21
|
/**
|
|
8
22
|
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
9
23
|
*
|
|
10
|
-
* Throws
|
|
11
|
-
*
|
|
12
|
-
* shape themselves — typically with a zod schema — so this returns
|
|
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`.
|
|
13
28
|
*/
|
|
14
29
|
export declare function postJson(url: string, body: unknown, options?: PostJsonOptions): Promise<unknown>;
|
|
30
|
+
export {};
|
package/dist/api/http.js
CHANGED
|
@@ -1,28 +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
|
+
}
|
|
1
43
|
/**
|
|
2
44
|
* POSTs a JSON body to `url` and returns the parsed JSON response.
|
|
3
45
|
*
|
|
4
|
-
* Throws
|
|
5
|
-
*
|
|
6
|
-
* shape themselves — typically with a zod schema — so this returns
|
|
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`.
|
|
7
50
|
*/
|
|
8
51
|
export async function postJson(url, body, options = {}) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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 });
|
|
21
86
|
}
|
|
22
87
|
try {
|
|
23
88
|
return JSON.parse(text);
|
|
24
89
|
}
|
|
25
|
-
catch {
|
|
26
|
-
throw new
|
|
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 });
|
|
27
92
|
}
|
|
28
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<{
|
|
@@ -11,6 +11,6 @@ export const releaseAppVersion = async (options) => {
|
|
|
11
11
|
configSchema: options.configSchema,
|
|
12
12
|
peerDependencies: options.peerDependencies,
|
|
13
13
|
channel: options.channel,
|
|
14
|
-
}, { apiKey: options.apiKey });
|
|
14
|
+
}, { apiKey: options.apiKey, userAgent: options.userAgent });
|
|
15
15
|
return releaseResponseSchema.parse(data);
|
|
16
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);
|
|
@@ -7,7 +7,8 @@ export default class DeployList extends DeployBaseCommand {
|
|
|
7
7
|
limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
|
|
10
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
run(): Promise<{
|
|
@@ -23,10 +23,11 @@ export default class DeployList extends DeployBaseCommand {
|
|
|
23
23
|
const { flags } = await this.parse(DeployList);
|
|
24
24
|
const { organizationSlug, projectSlug } = this.parseProject(flags.project);
|
|
25
25
|
const result = await fetchDeployments({
|
|
26
|
-
cockpitApiHost: flags
|
|
26
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
27
27
|
apiKey: flags.key,
|
|
28
28
|
organizationSlug,
|
|
29
29
|
projectSlug,
|
|
30
|
+
userAgent: this.config.userAgent,
|
|
30
31
|
limit: flags.limit,
|
|
31
32
|
});
|
|
32
33
|
if (result.deployments.length === 0) {
|
|
@@ -4,10 +4,11 @@ export default class DeployLogs extends DeployBaseCommand {
|
|
|
4
4
|
static enableJsonFlag: boolean;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
|
|
7
|
+
'deployment-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
|
|
10
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
run(): Promise<{
|
|
@@ -6,10 +6,12 @@ import DeployBaseCommand from '../../deploy-base-command.js';
|
|
|
6
6
|
export default class DeployLogs extends DeployBaseCommand {
|
|
7
7
|
static description = 'Fetch and display build logs for a deployment.';
|
|
8
8
|
static enableJsonFlag = true;
|
|
9
|
-
static examples = ['<%= config.bin %> deploy logs --project org/project --key orgKey_xxx --
|
|
9
|
+
static examples = ['<%= config.bin %> deploy logs --project org/project --key orgKey_xxx --deployment-id dep_abc123'];
|
|
10
10
|
static flags = {
|
|
11
11
|
...DeployBaseCommand.flags,
|
|
12
|
-
|
|
12
|
+
'deployment-id': Flags.string({
|
|
13
|
+
aliases: ['deploymentId'],
|
|
14
|
+
deprecateAliases: true,
|
|
13
15
|
description: 'Deployment ID',
|
|
14
16
|
required: true,
|
|
15
17
|
}),
|
|
@@ -18,11 +20,12 @@ export default class DeployLogs extends DeployBaseCommand {
|
|
|
18
20
|
const { flags } = await this.parse(DeployLogs);
|
|
19
21
|
const { organizationSlug, projectSlug } = this.parseProject(flags.project);
|
|
20
22
|
const apiOptions = {
|
|
21
|
-
cockpitApiHost: flags
|
|
23
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
22
24
|
apiKey: flags.key,
|
|
23
25
|
organizationSlug,
|
|
24
26
|
projectSlug,
|
|
25
|
-
|
|
27
|
+
userAgent: this.config.userAgent,
|
|
28
|
+
deploymentId: flags['deployment-id'],
|
|
26
29
|
};
|
|
27
30
|
// Initial fetch
|
|
28
31
|
const initial = await fetchDeploymentLogs(apiOptions);
|
|
@@ -31,7 +34,7 @@ export default class DeployLogs extends DeployBaseCommand {
|
|
|
31
34
|
return initial;
|
|
32
35
|
}
|
|
33
36
|
const isFollowing = !isTerminalStatus(initial.deploymentStatus);
|
|
34
|
-
this.log(`Build log for deployment ${flags
|
|
37
|
+
this.log(`Build log for deployment ${flags['deployment-id']}${isFollowing ? ' (following)' : ''}`);
|
|
35
38
|
this.log('');
|
|
36
39
|
const renderer = new LogRenderer();
|
|
37
40
|
renderer.render(initial.lines, (msg) => this.log(msg));
|
|
@@ -4,10 +4,11 @@ export default class DeployStatus extends DeployBaseCommand {
|
|
|
4
4
|
static enableJsonFlag: boolean;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
|
|
7
|
+
'deployment-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
|
|
10
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
run(): Promise<{
|
|
@@ -6,10 +6,12 @@ import { formatDetail } from '../../format/detail.js';
|
|
|
6
6
|
export default class DeployStatus extends DeployBaseCommand {
|
|
7
7
|
static description = 'Show status of a deployment.';
|
|
8
8
|
static enableJsonFlag = true;
|
|
9
|
-
static examples = ['<%= config.bin %> deploy status --project org/project --key orgKey_xxx --
|
|
9
|
+
static examples = ['<%= config.bin %> deploy status --project org/project --key orgKey_xxx --deployment-id dep_abc123'];
|
|
10
10
|
static flags = {
|
|
11
11
|
...DeployBaseCommand.flags,
|
|
12
|
-
|
|
12
|
+
'deployment-id': Flags.string({
|
|
13
|
+
aliases: ['deploymentId'],
|
|
14
|
+
deprecateAliases: true,
|
|
13
15
|
description: 'Deployment ID',
|
|
14
16
|
required: true,
|
|
15
17
|
}),
|
|
@@ -18,11 +20,12 @@ export default class DeployStatus extends DeployBaseCommand {
|
|
|
18
20
|
const { flags } = await this.parse(DeployStatus);
|
|
19
21
|
const { organizationSlug, projectSlug } = this.parseProject(flags.project);
|
|
20
22
|
const status = await fetchDeploymentStatus({
|
|
21
|
-
cockpitApiHost: flags
|
|
23
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
22
24
|
apiKey: flags.key,
|
|
23
25
|
organizationSlug,
|
|
24
26
|
projectSlug,
|
|
25
|
-
|
|
27
|
+
userAgent: this.config.userAgent,
|
|
28
|
+
deploymentId: flags['deployment-id'],
|
|
26
29
|
});
|
|
27
30
|
this.log(formatDetail([
|
|
28
31
|
['Status', status.status],
|
|
@@ -9,7 +9,8 @@ export default class DeployTrigger extends DeployBaseCommand {
|
|
|
9
9
|
preview: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
|
|
12
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
};
|
|
15
16
|
run(): Promise<{
|
|
@@ -31,10 +31,11 @@ export default class DeployTrigger extends DeployBaseCommand {
|
|
|
31
31
|
const { flags } = await this.parse(DeployTrigger);
|
|
32
32
|
const { organizationSlug, projectSlug } = this.parseProject(flags.project);
|
|
33
33
|
const apiOptions = {
|
|
34
|
-
cockpitApiHost: flags
|
|
34
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
35
35
|
apiKey: flags.key,
|
|
36
36
|
organizationSlug,
|
|
37
37
|
projectSlug,
|
|
38
|
+
userAgent: this.config.userAgent,
|
|
38
39
|
};
|
|
39
40
|
// A named preview requires a non-empty name — the deploy route rejects an
|
|
40
41
|
// empty `previewName`, and an unnamed preview is not supported by this contract.
|
|
@@ -6,10 +6,11 @@ export default class ProjectRcFetch extends LaioutrBaseCommand {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'environment-name': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
'project-secret': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
|
|
12
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
};
|
|
15
16
|
static aliases: string[];
|
|
@@ -12,15 +12,36 @@ export default class ProjectRcFetch extends LaioutrBaseCommand {
|
|
|
12
12
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
13
13
|
static flags = {
|
|
14
14
|
...LaioutrBaseCommand.flags,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
'environment-name': Flags.string({
|
|
16
|
+
aliases: ['environmentName'],
|
|
17
|
+
char: 'e',
|
|
18
|
+
default: 'main',
|
|
19
|
+
deprecateAliases: true,
|
|
20
|
+
description: 'Environment name',
|
|
21
|
+
env: 'ENVIRONMENT_NAME',
|
|
22
|
+
required: true,
|
|
23
|
+
}),
|
|
24
|
+
'project-secret': Flags.string({
|
|
25
|
+
aliases: ['projectSecret'],
|
|
26
|
+
char: 's',
|
|
27
|
+
deprecateAliases: true,
|
|
28
|
+
description: 'Project secret',
|
|
29
|
+
env: 'PROJECT_SECRET',
|
|
30
|
+
required: true,
|
|
31
|
+
}),
|
|
17
32
|
project: Flags.string({ char: 'p', description: '<organization slug>/<project slug>', env: 'PROJECT', required: true }),
|
|
18
33
|
};
|
|
19
34
|
static aliases = ['project:fetch-rc'];
|
|
20
35
|
static deprecateAliases = true;
|
|
21
36
|
async run() {
|
|
22
37
|
const { args, flags } = await this.parse(ProjectRcFetch);
|
|
23
|
-
const rc = await fetchRc(
|
|
38
|
+
const rc = await fetchRc({
|
|
39
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
40
|
+
environmentName: flags['environment-name'],
|
|
41
|
+
project: flags.project,
|
|
42
|
+
projectSecret: flags['project-secret'],
|
|
43
|
+
userAgent: this.config.userAgent,
|
|
44
|
+
});
|
|
24
45
|
const filePath = path.join(flags.cwd, args.fileName);
|
|
25
46
|
this.log('Writing RC file', filePath);
|
|
26
47
|
return writeFile(filePath, rc);
|
|
@@ -6,7 +6,8 @@ export default class ProjectRcUpdate extends LaioutrBaseCommand {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
|
-
|
|
9
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
11
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
};
|
|
12
13
|
run(): Promise<void>;
|
|
@@ -19,10 +19,11 @@ export default class ProjectRcUpdate extends LaioutrBaseCommand {
|
|
|
19
19
|
const currentRcRaw = await readFile(path.join(flags.cwd, args.fileName), 'utf-8');
|
|
20
20
|
const currentRc = rcWithLaioutrMetaSchema.parse(JSON.parse(currentRcRaw));
|
|
21
21
|
const options = {
|
|
22
|
-
|
|
22
|
+
cockpitApiHost: flags['cockpit-api-host'],
|
|
23
23
|
project: currentRc.laioutr.projectSlug,
|
|
24
24
|
projectSecret: currentRc.laioutr.projectSecretKey,
|
|
25
25
|
environmentName: currentRc.laioutr.environmentName,
|
|
26
|
+
userAgent: this.config.userAgent,
|
|
26
27
|
};
|
|
27
28
|
this.log('Fetching latest RC for project', options.project);
|
|
28
29
|
const rc = await fetchRc(options);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stripColorsIfDisabled } from '../format/color.js';
|
|
1
2
|
export class LogRenderer {
|
|
2
3
|
lastIndex = 0;
|
|
3
4
|
/**
|
|
@@ -9,7 +10,7 @@ export class LogRenderer {
|
|
|
9
10
|
return 0;
|
|
10
11
|
const newLines = lines.slice(this.lastIndex);
|
|
11
12
|
for (const line of newLines) {
|
|
12
|
-
log(line.text);
|
|
13
|
+
log(stripColorsIfDisabled(line.text));
|
|
13
14
|
}
|
|
14
15
|
this.lastIndex = lines.length;
|
|
15
16
|
return newLines.length;
|
|
@@ -4,7 +4,8 @@ export default abstract class DeployBaseCommand extends LaioutrBaseCommand {
|
|
|
4
4
|
static flags: {
|
|
5
5
|
project: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
6
|
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
|
|
7
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
9
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
10
|
};
|
|
10
11
|
protected parseProject(project: string): ProjectSlugs;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
2
|
+
function hasNoColorFlag(argv) {
|
|
3
|
+
const flagIndex = argv.indexOf('--no-color');
|
|
4
|
+
const separatorIndex = argv.indexOf('--');
|
|
5
|
+
return flagIndex !== -1 && (separatorIndex === -1 || flagIndex < separatorIndex);
|
|
6
|
+
}
|
|
7
|
+
export function stripColorsIfDisabled(text, output = process.stdout) {
|
|
8
|
+
const colorsDisabled = !output.isTTY || Boolean(process.env.NO_COLOR) || process.env.TERM === 'dumb' || hasNoColorFlag(process.argv);
|
|
9
|
+
return colorsDisabled ? stripVTControlCharacters(text) : text;
|
|
10
|
+
}
|
|
@@ -2,7 +2,15 @@ import { Command } from '@oclif/core';
|
|
|
2
2
|
export default abstract class LaioutrBaseCommand extends Command {
|
|
3
3
|
static args: {};
|
|
4
4
|
static flags: {
|
|
5
|
-
|
|
5
|
+
'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
'cockpit-api-host': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
7
|
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
8
|
};
|
|
9
|
+
protected toErrorJson(error: unknown): {
|
|
10
|
+
error: {
|
|
11
|
+
status?: number | undefined;
|
|
12
|
+
code: string;
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
8
16
|
}
|
|
@@ -2,17 +2,35 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
export default class LaioutrBaseCommand extends Command {
|
|
3
3
|
static args = {};
|
|
4
4
|
static flags = {
|
|
5
|
-
|
|
5
|
+
'no-color': Flags.boolean({
|
|
6
|
+
description: 'Disable color in output',
|
|
7
|
+
}),
|
|
8
|
+
'cockpit-api-host': Flags.string({
|
|
9
|
+
aliases: ['cockpitApiHost'],
|
|
6
10
|
default: 'https://cockpit.laioutr.cloud',
|
|
7
|
-
|
|
11
|
+
deprecateAliases: true,
|
|
12
|
+
description: 'Cockpit API host',
|
|
8
13
|
env: 'COCKPIT_API_HOST',
|
|
9
14
|
required: true,
|
|
10
15
|
}),
|
|
11
16
|
cwd: Flags.string({
|
|
12
17
|
default: process.cwd(),
|
|
13
|
-
description: '
|
|
18
|
+
description: 'Current working directory',
|
|
14
19
|
env: 'CWD',
|
|
15
20
|
required: true,
|
|
16
21
|
}),
|
|
17
22
|
};
|
|
23
|
+
toErrorJson(error) {
|
|
24
|
+
if (!(error instanceof Error)) {
|
|
25
|
+
return { error: { code: 'CLI_ERROR', message: 'An unexpected error occurred.' } };
|
|
26
|
+
}
|
|
27
|
+
const details = error;
|
|
28
|
+
return {
|
|
29
|
+
error: {
|
|
30
|
+
code: typeof details.code === 'string' ? details.code : 'CLI_ERROR',
|
|
31
|
+
message: details.message || 'An unexpected error occurred.',
|
|
32
|
+
...(typeof details.status === 'number' ? { status: details.status } : {}),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
18
36
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -10,10 +10,20 @@
|
|
|
10
10
|
"LAIOUTR_API_KEY=orgKey_xxx <%= config.bin %> app release"
|
|
11
11
|
],
|
|
12
12
|
"flags": {
|
|
13
|
-
"
|
|
14
|
-
"description": "
|
|
13
|
+
"no-color": {
|
|
14
|
+
"description": "Disable color in output",
|
|
15
|
+
"name": "no-color",
|
|
16
|
+
"allowNo": false,
|
|
17
|
+
"type": "boolean"
|
|
18
|
+
},
|
|
19
|
+
"cockpit-api-host": {
|
|
20
|
+
"aliases": [
|
|
21
|
+
"cockpitApiHost"
|
|
22
|
+
],
|
|
23
|
+
"deprecateAliases": true,
|
|
24
|
+
"description": "Cockpit API host",
|
|
15
25
|
"env": "COCKPIT_API_HOST",
|
|
16
|
-
"name": "
|
|
26
|
+
"name": "cockpit-api-host",
|
|
17
27
|
"required": true,
|
|
18
28
|
"default": "https://cockpit.laioutr.cloud",
|
|
19
29
|
"hasDynamicHelp": false,
|
|
@@ -21,7 +31,7 @@
|
|
|
21
31
|
"type": "option"
|
|
22
32
|
},
|
|
23
33
|
"cwd": {
|
|
24
|
-
"description": "
|
|
34
|
+
"description": "Current working directory",
|
|
25
35
|
"env": "CWD",
|
|
26
36
|
"name": "cwd",
|
|
27
37
|
"required": true,
|
|
@@ -85,10 +95,20 @@
|
|
|
85
95
|
"allowNo": false,
|
|
86
96
|
"type": "boolean"
|
|
87
97
|
},
|
|
88
|
-
"
|
|
89
|
-
"description": "
|
|
98
|
+
"no-color": {
|
|
99
|
+
"description": "Disable color in output",
|
|
100
|
+
"name": "no-color",
|
|
101
|
+
"allowNo": false,
|
|
102
|
+
"type": "boolean"
|
|
103
|
+
},
|
|
104
|
+
"cockpit-api-host": {
|
|
105
|
+
"aliases": [
|
|
106
|
+
"cockpitApiHost"
|
|
107
|
+
],
|
|
108
|
+
"deprecateAliases": true,
|
|
109
|
+
"description": "Cockpit API host",
|
|
90
110
|
"env": "COCKPIT_API_HOST",
|
|
91
|
-
"name": "
|
|
111
|
+
"name": "cockpit-api-host",
|
|
92
112
|
"required": true,
|
|
93
113
|
"default": "https://cockpit.laioutr.cloud",
|
|
94
114
|
"hasDynamicHelp": false,
|
|
@@ -96,7 +116,7 @@
|
|
|
96
116
|
"type": "option"
|
|
97
117
|
},
|
|
98
118
|
"cwd": {
|
|
99
|
-
"description": "
|
|
119
|
+
"description": "Current working directory",
|
|
100
120
|
"env": "CWD",
|
|
101
121
|
"name": "cwd",
|
|
102
122
|
"required": true,
|
|
@@ -155,7 +175,7 @@
|
|
|
155
175
|
"args": {},
|
|
156
176
|
"description": "Fetch and display build logs for a deployment.",
|
|
157
177
|
"examples": [
|
|
158
|
-
"<%= config.bin %> deploy logs --project org/project --key orgKey_xxx --
|
|
178
|
+
"<%= config.bin %> deploy logs --project org/project --key orgKey_xxx --deployment-id dep_abc123"
|
|
159
179
|
],
|
|
160
180
|
"flags": {
|
|
161
181
|
"json": {
|
|
@@ -165,10 +185,20 @@
|
|
|
165
185
|
"allowNo": false,
|
|
166
186
|
"type": "boolean"
|
|
167
187
|
},
|
|
168
|
-
"
|
|
169
|
-
"description": "
|
|
188
|
+
"no-color": {
|
|
189
|
+
"description": "Disable color in output",
|
|
190
|
+
"name": "no-color",
|
|
191
|
+
"allowNo": false,
|
|
192
|
+
"type": "boolean"
|
|
193
|
+
},
|
|
194
|
+
"cockpit-api-host": {
|
|
195
|
+
"aliases": [
|
|
196
|
+
"cockpitApiHost"
|
|
197
|
+
],
|
|
198
|
+
"deprecateAliases": true,
|
|
199
|
+
"description": "Cockpit API host",
|
|
170
200
|
"env": "COCKPIT_API_HOST",
|
|
171
|
-
"name": "
|
|
201
|
+
"name": "cockpit-api-host",
|
|
172
202
|
"required": true,
|
|
173
203
|
"default": "https://cockpit.laioutr.cloud",
|
|
174
204
|
"hasDynamicHelp": false,
|
|
@@ -176,7 +206,7 @@
|
|
|
176
206
|
"type": "option"
|
|
177
207
|
},
|
|
178
208
|
"cwd": {
|
|
179
|
-
"description": "
|
|
209
|
+
"description": "Current working directory",
|
|
180
210
|
"env": "CWD",
|
|
181
211
|
"name": "cwd",
|
|
182
212
|
"required": true,
|
|
@@ -205,9 +235,13 @@
|
|
|
205
235
|
"multiple": false,
|
|
206
236
|
"type": "option"
|
|
207
237
|
},
|
|
208
|
-
"
|
|
238
|
+
"deployment-id": {
|
|
239
|
+
"aliases": [
|
|
240
|
+
"deploymentId"
|
|
241
|
+
],
|
|
242
|
+
"deprecateAliases": true,
|
|
209
243
|
"description": "Deployment ID",
|
|
210
|
-
"name": "
|
|
244
|
+
"name": "deployment-id",
|
|
211
245
|
"required": true,
|
|
212
246
|
"hasDynamicHelp": false,
|
|
213
247
|
"multiple": false,
|
|
@@ -235,7 +269,7 @@
|
|
|
235
269
|
"args": {},
|
|
236
270
|
"description": "Show status of a deployment.",
|
|
237
271
|
"examples": [
|
|
238
|
-
"<%= config.bin %> deploy status --project org/project --key orgKey_xxx --
|
|
272
|
+
"<%= config.bin %> deploy status --project org/project --key orgKey_xxx --deployment-id dep_abc123"
|
|
239
273
|
],
|
|
240
274
|
"flags": {
|
|
241
275
|
"json": {
|
|
@@ -245,10 +279,20 @@
|
|
|
245
279
|
"allowNo": false,
|
|
246
280
|
"type": "boolean"
|
|
247
281
|
},
|
|
248
|
-
"
|
|
249
|
-
"description": "
|
|
282
|
+
"no-color": {
|
|
283
|
+
"description": "Disable color in output",
|
|
284
|
+
"name": "no-color",
|
|
285
|
+
"allowNo": false,
|
|
286
|
+
"type": "boolean"
|
|
287
|
+
},
|
|
288
|
+
"cockpit-api-host": {
|
|
289
|
+
"aliases": [
|
|
290
|
+
"cockpitApiHost"
|
|
291
|
+
],
|
|
292
|
+
"deprecateAliases": true,
|
|
293
|
+
"description": "Cockpit API host",
|
|
250
294
|
"env": "COCKPIT_API_HOST",
|
|
251
|
-
"name": "
|
|
295
|
+
"name": "cockpit-api-host",
|
|
252
296
|
"required": true,
|
|
253
297
|
"default": "https://cockpit.laioutr.cloud",
|
|
254
298
|
"hasDynamicHelp": false,
|
|
@@ -256,7 +300,7 @@
|
|
|
256
300
|
"type": "option"
|
|
257
301
|
},
|
|
258
302
|
"cwd": {
|
|
259
|
-
"description": "
|
|
303
|
+
"description": "Current working directory",
|
|
260
304
|
"env": "CWD",
|
|
261
305
|
"name": "cwd",
|
|
262
306
|
"required": true,
|
|
@@ -285,9 +329,13 @@
|
|
|
285
329
|
"multiple": false,
|
|
286
330
|
"type": "option"
|
|
287
331
|
},
|
|
288
|
-
"
|
|
332
|
+
"deployment-id": {
|
|
333
|
+
"aliases": [
|
|
334
|
+
"deploymentId"
|
|
335
|
+
],
|
|
336
|
+
"deprecateAliases": true,
|
|
289
337
|
"description": "Deployment ID",
|
|
290
|
-
"name": "
|
|
338
|
+
"name": "deployment-id",
|
|
291
339
|
"required": true,
|
|
292
340
|
"hasDynamicHelp": false,
|
|
293
341
|
"multiple": false,
|
|
@@ -328,10 +376,20 @@
|
|
|
328
376
|
"allowNo": false,
|
|
329
377
|
"type": "boolean"
|
|
330
378
|
},
|
|
331
|
-
"
|
|
332
|
-
"description": "
|
|
379
|
+
"no-color": {
|
|
380
|
+
"description": "Disable color in output",
|
|
381
|
+
"name": "no-color",
|
|
382
|
+
"allowNo": false,
|
|
383
|
+
"type": "boolean"
|
|
384
|
+
},
|
|
385
|
+
"cockpit-api-host": {
|
|
386
|
+
"aliases": [
|
|
387
|
+
"cockpitApiHost"
|
|
388
|
+
],
|
|
389
|
+
"deprecateAliases": true,
|
|
390
|
+
"description": "Cockpit API host",
|
|
333
391
|
"env": "COCKPIT_API_HOST",
|
|
334
|
-
"name": "
|
|
392
|
+
"name": "cockpit-api-host",
|
|
335
393
|
"required": true,
|
|
336
394
|
"default": "https://cockpit.laioutr.cloud",
|
|
337
395
|
"hasDynamicHelp": false,
|
|
@@ -339,7 +397,7 @@
|
|
|
339
397
|
"type": "option"
|
|
340
398
|
},
|
|
341
399
|
"cwd": {
|
|
342
|
-
"description": "
|
|
400
|
+
"description": "Current working directory",
|
|
343
401
|
"env": "CWD",
|
|
344
402
|
"name": "cwd",
|
|
345
403
|
"required": true,
|
|
@@ -421,10 +479,20 @@
|
|
|
421
479
|
"<%= config.bin %> <%= command.id %>"
|
|
422
480
|
],
|
|
423
481
|
"flags": {
|
|
424
|
-
"
|
|
425
|
-
"description": "
|
|
482
|
+
"no-color": {
|
|
483
|
+
"description": "Disable color in output",
|
|
484
|
+
"name": "no-color",
|
|
485
|
+
"allowNo": false,
|
|
486
|
+
"type": "boolean"
|
|
487
|
+
},
|
|
488
|
+
"cockpit-api-host": {
|
|
489
|
+
"aliases": [
|
|
490
|
+
"cockpitApiHost"
|
|
491
|
+
],
|
|
492
|
+
"deprecateAliases": true,
|
|
493
|
+
"description": "Cockpit API host",
|
|
426
494
|
"env": "COCKPIT_API_HOST",
|
|
427
|
-
"name": "
|
|
495
|
+
"name": "cockpit-api-host",
|
|
428
496
|
"required": true,
|
|
429
497
|
"default": "https://cockpit.laioutr.cloud",
|
|
430
498
|
"hasDynamicHelp": false,
|
|
@@ -432,7 +500,7 @@
|
|
|
432
500
|
"type": "option"
|
|
433
501
|
},
|
|
434
502
|
"cwd": {
|
|
435
|
-
"description": "
|
|
503
|
+
"description": "Current working directory",
|
|
436
504
|
"env": "CWD",
|
|
437
505
|
"name": "cwd",
|
|
438
506
|
"required": true,
|
|
@@ -441,22 +509,30 @@
|
|
|
441
509
|
"multiple": false,
|
|
442
510
|
"type": "option"
|
|
443
511
|
},
|
|
444
|
-
"
|
|
512
|
+
"environment-name": {
|
|
513
|
+
"aliases": [
|
|
514
|
+
"environmentName"
|
|
515
|
+
],
|
|
445
516
|
"char": "e",
|
|
446
|
-
"
|
|
517
|
+
"deprecateAliases": true,
|
|
518
|
+
"description": "Environment name",
|
|
447
519
|
"env": "ENVIRONMENT_NAME",
|
|
448
|
-
"name": "
|
|
520
|
+
"name": "environment-name",
|
|
449
521
|
"required": true,
|
|
450
522
|
"default": "main",
|
|
451
523
|
"hasDynamicHelp": false,
|
|
452
524
|
"multiple": false,
|
|
453
525
|
"type": "option"
|
|
454
526
|
},
|
|
455
|
-
"
|
|
527
|
+
"project-secret": {
|
|
528
|
+
"aliases": [
|
|
529
|
+
"projectSecret"
|
|
530
|
+
],
|
|
456
531
|
"char": "s",
|
|
457
|
-
"
|
|
532
|
+
"deprecateAliases": true,
|
|
533
|
+
"description": "Project secret",
|
|
458
534
|
"env": "PROJECT_SECRET",
|
|
459
|
-
"name": "
|
|
535
|
+
"name": "project-secret",
|
|
460
536
|
"required": true,
|
|
461
537
|
"hasDynamicHelp": false,
|
|
462
538
|
"multiple": false,
|
|
@@ -503,10 +579,20 @@
|
|
|
503
579
|
"<%= config.bin %> <%= command.id %>"
|
|
504
580
|
],
|
|
505
581
|
"flags": {
|
|
506
|
-
"
|
|
507
|
-
"description": "
|
|
582
|
+
"no-color": {
|
|
583
|
+
"description": "Disable color in output",
|
|
584
|
+
"name": "no-color",
|
|
585
|
+
"allowNo": false,
|
|
586
|
+
"type": "boolean"
|
|
587
|
+
},
|
|
588
|
+
"cockpit-api-host": {
|
|
589
|
+
"aliases": [
|
|
590
|
+
"cockpitApiHost"
|
|
591
|
+
],
|
|
592
|
+
"deprecateAliases": true,
|
|
593
|
+
"description": "Cockpit API host",
|
|
508
594
|
"env": "COCKPIT_API_HOST",
|
|
509
|
-
"name": "
|
|
595
|
+
"name": "cockpit-api-host",
|
|
510
596
|
"required": true,
|
|
511
597
|
"default": "https://cockpit.laioutr.cloud",
|
|
512
598
|
"hasDynamicHelp": false,
|
|
@@ -514,7 +600,7 @@
|
|
|
514
600
|
"type": "option"
|
|
515
601
|
},
|
|
516
602
|
"cwd": {
|
|
517
|
-
"description": "
|
|
603
|
+
"description": "Current working directory",
|
|
518
604
|
"env": "CWD",
|
|
519
605
|
"name": "cwd",
|
|
520
606
|
"required": true,
|
|
@@ -541,5 +627,5 @@
|
|
|
541
627
|
]
|
|
542
628
|
}
|
|
543
629
|
},
|
|
544
|
-
"version": "0.4.
|
|
630
|
+
"version": "0.4.1"
|
|
545
631
|
}
|