@statuser/cli 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +448 -2
- package/dist/client.js +163 -0
- package/dist/client.js.map +1 -0
- package/dist/commander-i18n.js +52 -0
- package/dist/commander-i18n.js.map +1 -0
- package/dist/commands/api.js +104 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/auth.js +104 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/catalog.js +72 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/config.js +302 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/heartbeat.js +199 -0
- package/dist/commands/heartbeat.js.map +1 -0
- package/dist/commands/incidents.js +265 -0
- package/dist/commands/incidents.js.map +1 -0
- package/dist/commands/maintenance.js +211 -0
- package/dist/commands/maintenance.js.map +1 -0
- package/dist/commands/reports.js +170 -0
- package/dist/commands/reports.js.map +1 -0
- package/dist/commands/scenarios.js +361 -0
- package/dist/commands/scenarios.js.map +1 -0
- package/dist/commands/servers-add.js +152 -0
- package/dist/commands/servers-add.js.map +1 -0
- package/dist/commands/servers-checks.js +56 -0
- package/dist/commands/servers-checks.js.map +1 -0
- package/dist/commands/servers.js +424 -0
- package/dist/commands/servers.js.map +1 -0
- package/dist/config.js +107 -0
- package/dist/config.js.map +1 -0
- package/dist/confirm.js +34 -0
- package/dist/confirm.js.map +1 -0
- package/dist/context.js +27 -0
- package/dist/context.js.map +1 -0
- package/dist/duration.js +20 -0
- package/dist/duration.js.map +1 -0
- package/dist/errors.js +73 -0
- package/dist/errors.js.map +1 -0
- package/dist/files.js +36 -0
- package/dist/files.js.map +1 -0
- package/dist/generated/openapi.js +6 -0
- package/dist/generated/openapi.js.map +1 -0
- package/dist/i18n.js +757 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/json-error.js +10 -0
- package/dist/json-error.js.map +1 -0
- package/dist/output.js +43 -0
- package/dist/output.js.map +1 -0
- package/dist/scenarios/config.js +228 -0
- package/dist/scenarios/config.js.map +1 -0
- package/dist/scenarios/plan.js +159 -0
- package/dist/scenarios/plan.js.map +1 -0
- package/dist/servers-config/export.js +72 -0
- package/dist/servers-config/export.js.map +1 -0
- package/dist/servers-config/fields.js +172 -0
- package/dist/servers-config/fields.js.map +1 -0
- package/dist/servers-config/forbidden-host.js +75 -0
- package/dist/servers-config/forbidden-host.js.map +1 -0
- package/dist/servers-config/host-pattern.js +6 -0
- package/dist/servers-config/host-pattern.js.map +1 -0
- package/dist/servers-config/parse.js +260 -0
- package/dist/servers-config/parse.js.map +1 -0
- package/dist/servers-config/plan.js +492 -0
- package/dist/servers-config/plan.js.map +1 -0
- package/dist/servers-update.js +157 -0
- package/dist/servers-update.js.map +1 -0
- package/dist/status-page.js +15 -0
- package/dist/status-page.js.map +1 -0
- package/dist/text-length.js +8 -0
- package/dist/text-length.js.map +1 -0
- package/dist/write-failure.js +37 -0
- package/dist/write-failure.js.map +1 -0
- package/package.json +70 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.js","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,WAAW,CAAC;AAE9B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,GAAG,GAAG,GAAG,UAAU,CAAC;AAEtD,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,qCAAqC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5C,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7C,iEAAiE;IACjE,oCAAoC;IACpC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,eAAe,EAAE,CAAC;QACpC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit codes are part of the CLI contract: CI pipelines branch on them.
|
|
3
|
+
*/
|
|
4
|
+
export const ExitCode = {
|
|
5
|
+
Ok: 0,
|
|
6
|
+
Failure: 1,
|
|
7
|
+
Usage: 2,
|
|
8
|
+
Auth: 3,
|
|
9
|
+
ScenarioFailed: 4,
|
|
10
|
+
};
|
|
11
|
+
/** An error whose message is already meant for the user. */
|
|
12
|
+
export class CliError extends Error {
|
|
13
|
+
exitCode;
|
|
14
|
+
constructor(message, exitCode = ExitCode.Failure) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.exitCode = exitCode;
|
|
17
|
+
this.name = 'CliError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** The connection was never set up: the request surely did not leave. */
|
|
21
|
+
export class NotSentError extends CliError {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = 'NotSentError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class StatuserApiError extends Error {
|
|
28
|
+
status;
|
|
29
|
+
errorCode;
|
|
30
|
+
meta;
|
|
31
|
+
constructor(status, message, errorCode, meta) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.status = status;
|
|
34
|
+
this.errorCode = errorCode;
|
|
35
|
+
this.meta = meta;
|
|
36
|
+
this.name = 'StatuserApiError';
|
|
37
|
+
}
|
|
38
|
+
get exitCode() {
|
|
39
|
+
return this.status === 401 ? ExitCode.Auth : ExitCode.Failure;
|
|
40
|
+
}
|
|
41
|
+
format() {
|
|
42
|
+
const code = this.errorCode ? ` (${this.errorCode})` : '';
|
|
43
|
+
return `API ${this.status}${code}: ${this.message}`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The backend answers with `message: string | string[]` (validation errors
|
|
48
|
+
* come as a list), `error_code`, `status_code` and sometimes `meta`.
|
|
49
|
+
*/
|
|
50
|
+
export function parseApiErrorBody(status, text) {
|
|
51
|
+
let body = null;
|
|
52
|
+
try {
|
|
53
|
+
const parsed = text ? JSON.parse(text) : null;
|
|
54
|
+
if (parsed && typeof parsed === 'object') {
|
|
55
|
+
body = parsed;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Not JSON — fall back to the raw text below.
|
|
60
|
+
}
|
|
61
|
+
const rawMessage = body?.message;
|
|
62
|
+
const message = Array.isArray(rawMessage)
|
|
63
|
+
? rawMessage.map(String).join('; ')
|
|
64
|
+
: typeof rawMessage === 'string'
|
|
65
|
+
? rawMessage
|
|
66
|
+
: text.slice(0, 500) || `HTTP ${status}`;
|
|
67
|
+
const errorCode = typeof body?.error_code === 'string' ? body.error_code : undefined;
|
|
68
|
+
const meta = body?.meta && typeof body.meta === 'object'
|
|
69
|
+
? body.meta
|
|
70
|
+
: undefined;
|
|
71
|
+
return new StatuserApiError(status, message, errorCode, meta);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { link, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { CliError, ExitCode } from './errors.js';
|
|
4
|
+
import { t } from './i18n.js';
|
|
5
|
+
/**
|
|
6
|
+
* Writes a file the CLI produced (exported config, PDF report) readable by
|
|
7
|
+
* the owner only: both can hold data the account would not publish. An
|
|
8
|
+
* existing file is replaced only with `force`, and always atomically, so an
|
|
9
|
+
* interrupted run never leaves half a file in place of a good one.
|
|
10
|
+
*/
|
|
11
|
+
export async function writeOwnFile(path, data, force) {
|
|
12
|
+
// A random name, removed only once this call has created it: a file
|
|
13
|
+
// that happened to exist under that name is not ours to delete.
|
|
14
|
+
const temp = `${path}.${randomUUID()}.tmp`;
|
|
15
|
+
await writeFile(temp, data, { mode: 0o600, flag: 'wx' });
|
|
16
|
+
try {
|
|
17
|
+
if (force) {
|
|
18
|
+
await rename(temp, path);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Unlike `rename`, `link` fails when the target exists.
|
|
22
|
+
try {
|
|
23
|
+
await link(temp, path);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.code === 'EEXIST') {
|
|
27
|
+
throw new CliError(t.fileExists(path), ExitCode.Usage);
|
|
28
|
+
}
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
await rm(temp, { force: true });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,WAAW,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,IAAqB,EACrB,KAAc;IAEd,oEAAoE;IACpE,gEAAgE;IAChE,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;IAC3C,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,wDAAwD;QACxD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/generated/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|