@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.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +448 -2
  3. package/dist/client.js +163 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/commander-i18n.js +52 -0
  6. package/dist/commander-i18n.js.map +1 -0
  7. package/dist/commands/api.js +104 -0
  8. package/dist/commands/api.js.map +1 -0
  9. package/dist/commands/auth.js +104 -0
  10. package/dist/commands/auth.js.map +1 -0
  11. package/dist/commands/catalog.js +72 -0
  12. package/dist/commands/catalog.js.map +1 -0
  13. package/dist/commands/config.js +302 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/heartbeat.js +199 -0
  16. package/dist/commands/heartbeat.js.map +1 -0
  17. package/dist/commands/incidents.js +265 -0
  18. package/dist/commands/incidents.js.map +1 -0
  19. package/dist/commands/maintenance.js +211 -0
  20. package/dist/commands/maintenance.js.map +1 -0
  21. package/dist/commands/reports.js +170 -0
  22. package/dist/commands/reports.js.map +1 -0
  23. package/dist/commands/scenarios.js +361 -0
  24. package/dist/commands/scenarios.js.map +1 -0
  25. package/dist/commands/servers-add.js +152 -0
  26. package/dist/commands/servers-add.js.map +1 -0
  27. package/dist/commands/servers-checks.js +56 -0
  28. package/dist/commands/servers-checks.js.map +1 -0
  29. package/dist/commands/servers.js +424 -0
  30. package/dist/commands/servers.js.map +1 -0
  31. package/dist/config.js +107 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/confirm.js +34 -0
  34. package/dist/confirm.js.map +1 -0
  35. package/dist/context.js +27 -0
  36. package/dist/context.js.map +1 -0
  37. package/dist/duration.js +20 -0
  38. package/dist/duration.js.map +1 -0
  39. package/dist/errors.js +73 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/files.js +36 -0
  42. package/dist/files.js.map +1 -0
  43. package/dist/generated/openapi.js +6 -0
  44. package/dist/generated/openapi.js.map +1 -0
  45. package/dist/i18n.js +757 -0
  46. package/dist/i18n.js.map +1 -0
  47. package/dist/index.js +58 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/json-error.js +10 -0
  50. package/dist/json-error.js.map +1 -0
  51. package/dist/output.js +43 -0
  52. package/dist/output.js.map +1 -0
  53. package/dist/scenarios/config.js +228 -0
  54. package/dist/scenarios/config.js.map +1 -0
  55. package/dist/scenarios/plan.js +159 -0
  56. package/dist/scenarios/plan.js.map +1 -0
  57. package/dist/servers-config/export.js +72 -0
  58. package/dist/servers-config/export.js.map +1 -0
  59. package/dist/servers-config/fields.js +172 -0
  60. package/dist/servers-config/fields.js.map +1 -0
  61. package/dist/servers-config/forbidden-host.js +75 -0
  62. package/dist/servers-config/forbidden-host.js.map +1 -0
  63. package/dist/servers-config/host-pattern.js +6 -0
  64. package/dist/servers-config/host-pattern.js.map +1 -0
  65. package/dist/servers-config/parse.js +260 -0
  66. package/dist/servers-config/parse.js.map +1 -0
  67. package/dist/servers-config/plan.js +492 -0
  68. package/dist/servers-config/plan.js.map +1 -0
  69. package/dist/servers-update.js +157 -0
  70. package/dist/servers-update.js.map +1 -0
  71. package/dist/status-page.js +15 -0
  72. package/dist/status-page.js.map +1 -0
  73. package/dist/text-length.js +8 -0
  74. package/dist/text-length.js.map +1 -0
  75. package/dist/write-failure.js +37 -0
  76. package/dist/write-failure.js.map +1 -0
  77. 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,6 @@
1
+ /**
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=openapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/generated/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG"}