@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,361 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { inspect } from 'node:util';
3
+ import { authedClient, globalOptions } from '../context.js';
4
+ import { CliError, ExitCode } from '../errors.js';
5
+ import { t } from '../i18n.js';
6
+ import { printErr, printJson, printLine } from '../output.js';
7
+ import { loadScenarioConfig, resolveEnvValue, scenarioEnvProblem, SCENARIO_DEFAULT_LOCATION, SCENARIO_DEFAULT_TIMEOUT, SCENARIO_LOCATIONS, SCENARIO_TIMEOUTS, } from '../scenarios/config.js';
8
+ import { buildDeployPlan } from '../scenarios/plan.js';
9
+ import { checkScenarioLimits } from '../servers-config/plan.js';
10
+ import { describeWriteFailure } from '../write-failure.js';
11
+ import { listServers, parseId } from './servers.js';
12
+ // The sandbox may wait up to 30 s for a free slot on top of the run itself,
13
+ // then uploads artifacts.
14
+ const PREVIEW_OVERHEAD_MS = 90_000;
15
+ const collect = (value, previous) => [...previous, value];
16
+ export function registerScenariosCommands(program) {
17
+ const scenarios = program.command('scenarios').description(t.cmdScenarios);
18
+ scenarios
19
+ .command('test')
20
+ .description(t.cmdScenariosTest)
21
+ .argument('<file>')
22
+ .option('--timeout <seconds>', t.optTimeout, String(SCENARIO_DEFAULT_TIMEOUT))
23
+ .option('--location <code>', t.optLocation, SCENARIO_DEFAULT_LOCATION)
24
+ .option('--env <KEY=VALUE>', t.optEnv, collect, [])
25
+ .action(async (file, opts, command) => {
26
+ const timeout = Number(opts.timeout);
27
+ if (!SCENARIO_TIMEOUTS.includes(timeout)) {
28
+ throw new CliError(t.optTimeout, ExitCode.Usage);
29
+ }
30
+ if (!SCENARIO_LOCATIONS.includes(opts.location)) {
31
+ throw new CliError(t.optLocation, ExitCode.Usage);
32
+ }
33
+ const env = Object.create(null);
34
+ for (const [position, raw] of opts.env.entries()) {
35
+ const index = raw.indexOf('=');
36
+ // The argument may be a bare value: it is never quoted back.
37
+ // A bad name may be part of a secret passed by mistake
38
+ // (`--env 'YWJj=='`): the problem is named by position only.
39
+ if (index <= 0 ||
40
+ scenarioEnvProblem({ [raw.slice(0, index)]: '' }) !== null) {
41
+ throw new CliError(t.argInvalid('--env', position + 1), ExitCode.Usage);
42
+ }
43
+ env[raw.slice(0, index)] = resolveEnvValue(raw.slice(index + 1), file, process.env);
44
+ }
45
+ const envProblem = scenarioEnvProblem(env);
46
+ if (envProblem)
47
+ throw new CliError(envProblem, ExitCode.Usage);
48
+ let script;
49
+ try {
50
+ script = await readFile(file, 'utf8');
51
+ }
52
+ catch {
53
+ throw new CliError(t.configNotFound(file), ExitCode.Usage);
54
+ }
55
+ const json = globalOptions(command).json;
56
+ if (!json)
57
+ printErr(t.scenarioRunning);
58
+ const { client } = await authedClient(command);
59
+ // Not retried on a dropped connection: the run may have happened, and
60
+ // the account allows one on-demand run at a time.
61
+ const result = await client.call({
62
+ method: 'POST',
63
+ path: '/v1/scenario-runs/preview',
64
+ body: {
65
+ scenario_script: script,
66
+ // Both checked against the spec enums above.
67
+ request_timeout: timeout,
68
+ locations: [
69
+ opts.location,
70
+ ],
71
+ ...(Object.keys(env).length ? { scenario_env: env } : {}),
72
+ },
73
+ timeoutMs: timeout * 1000 + PREVIEW_OVERHEAD_MS,
74
+ });
75
+ // The test may print or compare its passwords; the run result comes
76
+ // back verbatim, so the values passed here are masked before output.
77
+ const masked = maskSecrets(result, Object.values(env));
78
+ if (json)
79
+ printJson(masked);
80
+ else
81
+ printRunResult(masked);
82
+ process.exitCode = runExitCode(result.status);
83
+ });
84
+ scenarios
85
+ .command('run')
86
+ .description(t.cmdScenariosRun)
87
+ .argument('<id>', 'id', parseId)
88
+ .action(async (id, _opts, command) => {
89
+ const { client } = await authedClient(command);
90
+ const server = await client.call({
91
+ method: 'GET',
92
+ path: `/v1/servers/${id}`,
93
+ });
94
+ if (server.protocol !== 'scenario') {
95
+ throw new CliError(t.scenarioNotScenario(id, server.protocol), ExitCode.Usage);
96
+ }
97
+ // The answer comes when the run ends: up to the scenario's timeout
98
+ // plus the start. Not retried on a dropped connection — the run may
99
+ // have happened, and it counts like a scheduled one.
100
+ const result = await client.call({
101
+ method: 'POST',
102
+ path: `/v1/servers/${id}/scenario-run`,
103
+ timeoutMs: server.request_timeout * 1000 + PREVIEW_OVERHEAD_MS,
104
+ });
105
+ // The API returns the saved run's console and error verbatim, and the
106
+ // values of its variables are not readable. In CI they usually sit in
107
+ // the environment under the same names (the config refers to them as
108
+ // `$NAME`): those are masked, the rest are named in a warning.
109
+ const keys = server.scenario_env_keys ?? [];
110
+ const known = keys.filter((key) => process.env[key]);
111
+ const unknown = keys.filter((key) => !process.env[key]);
112
+ if (unknown.length)
113
+ printErr(t.scenarioEnvUnmasked(unknown.join(', ')));
114
+ const masked = maskSecrets(result, known.map((key) => process.env[key]));
115
+ if (globalOptions(command).json)
116
+ printJson(masked);
117
+ else
118
+ printRunResult(masked);
119
+ process.exitCode = runExitCode(result.status);
120
+ });
121
+ scenarios
122
+ .command('deploy')
123
+ .description(t.cmdScenariosDeploy)
124
+ .option('-c, --config <path>', t.optConfig, 'statuser.json')
125
+ .option('--dry-run', t.optDryRun)
126
+ .action(async (opts, command) => {
127
+ const config = await loadScenarioConfig(opts.config);
128
+ const { client } = await authedClient(command);
129
+ // The whole account: duplicate scripts are checked account-wide.
130
+ const [servers, current] = await Promise.all([
131
+ listServers(client),
132
+ client.call({
133
+ method: 'GET',
134
+ path: '/v1/billing/current-plan',
135
+ }),
136
+ ]);
137
+ const plan = buildDeployPlan(config, servers);
138
+ // Plan limits before the first write, as `apply` does.
139
+ const creates = plan.steps.filter((s) => s.kind === 'create').length;
140
+ checkScenarioLimits(plan.steps, servers.filter((s) => s.protocol === 'scenario').length, current.features);
141
+ if (creates &&
142
+ servers.length + creates > current.features.servers_limit) {
143
+ throw new CliError(t.applyServersLimit(current.features.servers_limit, servers.length, creates), ExitCode.Usage);
144
+ }
145
+ const json = globalOptions(command).json;
146
+ const pending = plan.steps.filter((s) => s.kind !== 'unchanged');
147
+ if (!json) {
148
+ printLine(t.deployPlanTitle(plan.projectId));
149
+ for (const step of plan.steps)
150
+ printLine(describeStep(step));
151
+ for (const item of plan.unmanaged) {
152
+ printLine(t.deployUnmanaged(item.name ?? '', item.id));
153
+ }
154
+ if (pending.some((s) => s.kind === 'update' && s.fields.includes('env'))) {
155
+ printErr(t.deployEnvAlwaysSent);
156
+ }
157
+ }
158
+ const applied = [];
159
+ const summary = () => ({
160
+ project_id: plan.projectId,
161
+ dry_run: !!opts.dryRun,
162
+ // Bodies are left out: they carry scenario env values.
163
+ steps: plan.steps.map((step) => ({
164
+ name: step.scenario.name,
165
+ action: step.kind,
166
+ id: step.kind === 'create' ? null : step.serverId,
167
+ fields: step.kind === 'update' ? step.fields : undefined,
168
+ })),
169
+ unmanaged: plan.unmanaged,
170
+ applied,
171
+ });
172
+ if (opts.dryRun || !pending.length) {
173
+ if (json)
174
+ printJson(summary());
175
+ else
176
+ printLine(opts.dryRun ? t.deployDryRunDone : t.deployNothing);
177
+ return;
178
+ }
179
+ for (const step of pending) {
180
+ try {
181
+ if (step.kind === 'create') {
182
+ const created = await client.call({
183
+ method: 'POST',
184
+ path: '/v1/servers',
185
+ body: step.body,
186
+ });
187
+ applied.push({
188
+ name: step.scenario.name,
189
+ action: 'create',
190
+ id: created.id,
191
+ });
192
+ }
193
+ else if (step.kind === 'update') {
194
+ await client.call({
195
+ method: 'PATCH',
196
+ path: `/v1/servers/${step.serverId}`,
197
+ body: step.body,
198
+ });
199
+ applied.push({
200
+ name: step.scenario.name,
201
+ action: 'update',
202
+ id: step.serverId,
203
+ });
204
+ }
205
+ if (!json)
206
+ printLine(t.deployApplied(step.scenario.name));
207
+ }
208
+ catch (error) {
209
+ const failure = describeWriteFailure(step.scenario.name, error);
210
+ if (json)
211
+ printJson({ ...summary(), error: failure });
212
+ throw new CliError(failure.message, failure.exitCode);
213
+ }
214
+ }
215
+ if (json)
216
+ printJson(summary());
217
+ });
218
+ }
219
+ export function describeStep(step) {
220
+ switch (step.kind) {
221
+ case 'create':
222
+ return t.deployCreate(step.scenario.name);
223
+ case 'update':
224
+ return t.deployUpdate(step.scenario.name, step.serverId, step.fields.join(', '));
225
+ case 'unchanged':
226
+ return t.deployUnchanged(step.scenario.name, step.serverId);
227
+ }
228
+ }
229
+ function printRunResult(result) {
230
+ if (result.status === 'passed') {
231
+ printLine(t.scenarioPassed(((result.duration_ms ?? 0) / 1000).toFixed(1)));
232
+ }
233
+ else if (result.status === 'runner_error') {
234
+ printLine(t.scenarioRunnerError);
235
+ }
236
+ else {
237
+ printLine(t.scenarioFailed(result.status));
238
+ if (result.failed_test)
239
+ printLine(t.scenarioFailedTest(result.failed_test));
240
+ if (result.error)
241
+ printLine(t.scenarioError(result.error));
242
+ }
243
+ for (const [kind, url] of Object.entries(result.artifact_urls ?? {})) {
244
+ if (url)
245
+ printLine(t.scenarioArtifact(kind, url));
246
+ }
247
+ }
248
+ /** passed → 0, a site-side failure → 4, our sandbox failing → 1. */
249
+ function runExitCode(status) {
250
+ if (status === 'passed')
251
+ return ExitCode.Ok;
252
+ if (status === 'runner_error')
253
+ return ExitCode.Failure;
254
+ return ExitCode.ScenarioFailed;
255
+ }
256
+ /**
257
+ * Masks the given secret values in the diagnostic fields of a run result:
258
+ * the error, the failed test title and the console. Structural fields
259
+ * (status, location, links) are left intact — they are the contract.
260
+ */
261
+ export function maskSecrets(result, secrets) {
262
+ const values = secretForms(secrets);
263
+ if (!values.length)
264
+ return result;
265
+ const mask = (text) => typeof text === 'string' ? maskText(text, values) : text;
266
+ return {
267
+ ...result,
268
+ error: mask(result.error),
269
+ failed_test: mask(result.failed_test),
270
+ console: result.console?.map((entry) => ({
271
+ ...entry,
272
+ text: mask(entry.text) ?? '',
273
+ })) ?? null,
274
+ };
275
+ }
276
+ /**
277
+ * Every form a value may take in the run's output: as given, escaped by
278
+ * `JSON.stringify` in the script, and without trailing whitespace, which
279
+ * the runner trims from console lines.
280
+ */
281
+ function secretForms(secrets) {
282
+ const forms = new Set();
283
+ for (const secret of secrets) {
284
+ // util.inspect (`console.log({ password })`) breaks a long multiline
285
+ // string into one literal per line, joined with `+` and indented by
286
+ // nesting: each line of the value is masked on its own too. Lines
287
+ // shorter than four characters are left, so as not to mask everywhere.
288
+ const lines = secret.includes('\n')
289
+ ? secret.split('\n').filter((line) => line.length >= 4)
290
+ : [];
291
+ for (const part of [secret, ...lines]) {
292
+ addForms(forms, part);
293
+ }
294
+ }
295
+ return [...forms];
296
+ }
297
+ function addForms(forms, secret) {
298
+ // util.inspect has its own escaping and quote choice.
299
+ for (const form of [
300
+ secret,
301
+ JSON.stringify(secret).slice(1, -1),
302
+ inspect(secret).slice(1, -1),
303
+ ]) {
304
+ for (const variant of [form, form.trimEnd()]) {
305
+ if (variant)
306
+ forms.add(variant);
307
+ }
308
+ }
309
+ }
310
+ /**
311
+ * Finds every place a value occupies in the original text first and only
312
+ * then replaces them: masking one value before searching for the next
313
+ * would break an overlapping one. The backend cuts long lines and appends
314
+ * `…`, so the start of a value at the cut is masked too.
315
+ */
316
+ function maskText(text, values) {
317
+ const cut = text.endsWith('…');
318
+ const body = cut ? text.slice(0, -1) : text;
319
+ const ranges = [];
320
+ for (const value of values) {
321
+ for (let at = body.indexOf(value); at >= 0; at = body.indexOf(value, at + 1)) {
322
+ ranges.push([at, at + value.length]);
323
+ }
324
+ // The runner keeps only the last part of a long error, without a mark:
325
+ // a value cut at the start shows as its tail. Four characters at least,
326
+ // so a common last letter does not mask the start of every line.
327
+ for (let length = Math.min(value.length - 1, body.length); length >= 4; length -= 1) {
328
+ if (body.startsWith(value.slice(-length))) {
329
+ ranges.push([0, length]);
330
+ break;
331
+ }
332
+ }
333
+ if (cut) {
334
+ for (let length = Math.min(value.length - 1, body.length); length > 0; length -= 1) {
335
+ if (body.endsWith(value.slice(0, length))) {
336
+ ranges.push([body.length - length, body.length]);
337
+ break;
338
+ }
339
+ }
340
+ }
341
+ }
342
+ if (!ranges.length)
343
+ return text;
344
+ ranges.sort((a, b) => a[0] - b[0]);
345
+ const merged = [];
346
+ for (const [start, end] of ranges) {
347
+ const last = merged.at(-1);
348
+ if (last && start <= last[1])
349
+ last[1] = Math.max(last[1], end);
350
+ else
351
+ merged.push([start, end]);
352
+ }
353
+ let out = '';
354
+ let pos = 0;
355
+ for (const [start, end] of merged) {
356
+ out += `${body.slice(pos, start)}***`;
357
+ pos = end;
358
+ }
359
+ return `${out}${body.slice(pos)}${cut ? '…' : ''}`;
360
+ }
361
+ //# sourceMappingURL=scenarios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/commands/scenarios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { isIP } from 'node:net';
2
+ import { authedClient, globalOptions } from '../context.js';
3
+ import { CliError, ExitCode } from '../errors.js';
4
+ import { t } from '../i18n.js';
5
+ import { printErr, printJson, printLine } from '../output.js';
6
+ import { SCENARIO_LOCATIONS } from '../scenarios/config.js';
7
+ import { parseServersSection } from '../servers-config/parse.js';
8
+ import { buildServersPlan } from '../servers-config/plan.js';
9
+ import { listServers, parseId, redactServer } from './servers.js';
10
+ const ADD_PROTOCOLS = ['http', 'keyword', 'ping', 'tcp', 'dns', 'heartbeat'];
11
+ /**
12
+ * One server, with the panel defaults for everything not given. The entry
13
+ * goes through the same parser and plan as `apply`, so the same checks run
14
+ * before the write: ranges, the host gate, account-wide duplicates and the
15
+ * plan. Settings without a flag here are changed later by `servers update`.
16
+ */
17
+ export function registerServersAdd(servers) {
18
+ servers
19
+ .command('add')
20
+ .description(t.cmdServersAdd)
21
+ .argument('[host]', t.argServerHost)
22
+ .option('--name <name>', t.optServerName)
23
+ .option('--protocol <protocol>', t.optAddProtocol)
24
+ .option('--project <id>', t.optProject, parseId)
25
+ .option('--port <port>', t.optPort)
26
+ .option('--keyword <word>', t.optKeyword)
27
+ .option('--keyword-absent', t.optKeywordAbsent)
28
+ .option('--dns-types <types>', t.optDnsTypes)
29
+ .option('--interval <seconds>', t.optInterval)
30
+ .option('--timeout <seconds>', t.optRequestTimeout)
31
+ .option('--regions <codes>', t.optRegions)
32
+ .option('--dry-run', t.optDryRun)
33
+ .action(async (host, opts, command) => {
34
+ const entry = buildEntry(host, opts);
35
+ // The parser names the place as in a file, `servers[0].port`; here
36
+ // the field name alone says which flag to fix.
37
+ const desired = parseServersSection([entry], process.env, (problem) => usage(problem.replace(/^servers\[0\]\.?/, '')), { allowUnnamed: true });
38
+ const label = entry.name ?? host ?? '';
39
+ desired[0].at = label;
40
+ const { client } = await authedClient(command);
41
+ const [account, current, projectId] = await Promise.all([
42
+ listServers(client),
43
+ client.call({
44
+ method: 'GET',
45
+ path: '/v1/billing/current-plan',
46
+ }),
47
+ opts.project ?? defaultProject(client),
48
+ ]);
49
+ const plan = buildServersPlan(desired, projectId, account, current.features, 0, { createOnly: true });
50
+ const step = plan.steps[0];
51
+ if (step.kind !== 'create')
52
+ throw new Error('expected a create step');
53
+ for (const warning of step.warnings)
54
+ printErr(warning);
55
+ const json = globalOptions(command).json;
56
+ if (opts.dryRun) {
57
+ if (json)
58
+ printJson({ dry_run: true, body: step.body });
59
+ else
60
+ printLine(t.addDryRun(label));
61
+ return;
62
+ }
63
+ const created = await client.call({
64
+ method: 'POST',
65
+ path: '/v1/servers',
66
+ body: step.body,
67
+ });
68
+ if (json)
69
+ printJson(redactServer(created));
70
+ else
71
+ printLine(t.addCreated(created.id, created.name || label));
72
+ });
73
+ }
74
+ function buildEntry(host, opts) {
75
+ const protocol = opts.protocol ?? guessProtocol(host);
76
+ if (!ADD_PROTOCOLS.includes(protocol)) {
77
+ usage(`--protocol: ${t.cfgOneOf(ADD_PROTOCOLS.join(', '))}`);
78
+ }
79
+ if (protocol === 'heartbeat') {
80
+ if (host)
81
+ usage(t.addHostNotUsed);
82
+ // A heartbeat is told apart by its name: the API requires one.
83
+ if (!opts.name?.trim())
84
+ usage(`--name: ${t.cfgNonEmptyString}`);
85
+ }
86
+ else if (!host) {
87
+ usage(t.addHostNeeded);
88
+ }
89
+ const entry = { protocol };
90
+ if (host)
91
+ entry.host = host;
92
+ if (opts.name !== undefined)
93
+ entry.name = opts.name;
94
+ if (opts.port !== undefined)
95
+ entry.port = integer('--port', opts.port);
96
+ if (opts.keyword !== undefined)
97
+ entry.keyword = opts.keyword;
98
+ if (opts.keywordAbsent)
99
+ entry.keyword_mode = 'absent';
100
+ if (opts.dnsTypes !== undefined)
101
+ entry.dns_record_types = list(opts.dnsTypes);
102
+ if (opts.interval !== undefined) {
103
+ entry.check_interval = integer('--interval', opts.interval);
104
+ }
105
+ if (opts.timeout !== undefined) {
106
+ entry.request_timeout = integer('--timeout', opts.timeout);
107
+ }
108
+ if (opts.regions !== undefined) {
109
+ const regions = list(opts.regions);
110
+ for (const region of regions) {
111
+ if (!SCENARIO_LOCATIONS.includes(region)) {
112
+ usage(t.regionInvalid(region));
113
+ }
114
+ }
115
+ entry.locations = regions;
116
+ }
117
+ return entry;
118
+ }
119
+ /** A URL is an HTTP check, an address literal a ping; anything else is asked. */
120
+ function guessProtocol(host) {
121
+ if (!host)
122
+ return 'heartbeat';
123
+ if (/^https?:\/\//i.test(host.trim()))
124
+ return 'http';
125
+ if (isIP(host.trim().replace(/^\[|\]$/g, '')))
126
+ return 'ping';
127
+ return usage(t.addProtocolNeeded(host));
128
+ }
129
+ /** Where the API puts a server without `project_id`: the oldest project. */
130
+ async function defaultProject(client) {
131
+ const projects = await client.call({
132
+ method: 'GET',
133
+ path: '/v1/projects',
134
+ });
135
+ return Math.min(...projects.map((project) => project.id));
136
+ }
137
+ function integer(flag, raw) {
138
+ const value = Number(raw);
139
+ if (!Number.isInteger(value))
140
+ usage(`${flag}: ${t.numberInvalid(raw)}`);
141
+ return value;
142
+ }
143
+ function list(raw) {
144
+ return raw
145
+ .split(',')
146
+ .map((item) => item.trim())
147
+ .filter(Boolean);
148
+ }
149
+ function usage(message) {
150
+ throw new CliError(message, ExitCode.Usage);
151
+ }
152
+ //# sourceMappingURL=servers-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"servers-add.js","sourceRoot":"","sources":["../../src/commands/servers-add.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AAK/E,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;AAgB7E;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;SAC5B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,aAAa,CAAC;SACnC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,aAAa,CAAC;SACxC,MAAM,CAAC,uBAAuB,EAAE,CAAC,CAAC,cAAc,CAAC;SACjD,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC;SAClC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,UAAU,CAAC;SACxC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,gBAAgB,CAAC;SAC9C,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,WAAW,CAAC;SAC5C,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,WAAW,CAAC;SAC7C,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,iBAAiB,CAAC;SAClD,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,UAAU,CAAC;SACzC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC;SAChC,MAAM,CACL,KAAK,EAAE,IAAwB,EAAE,IAAgB,EAAE,OAAgB,EAAE,EAAE;QACrE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,mEAAmE;QACnE,+CAA+C;QAC/C,MAAM,OAAO,GAAG,mBAAmB,CACjC,CAAC,KAAK,CAAC,EACP,OAAO,CAAC,GAAG,EACX,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,EAC3D,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB,CAAC;QACF,MAAM,KAAK,GAAI,KAAK,CAAC,IAA2B,IAAI,IAAI,IAAI,EAAE,CAAC;QAC/D,OAAO,CAAC,CAAC,CAAE,CAAC,EAAE,GAAG,KAAK,CAAC;QAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACtD,WAAW,CAAC,MAAM,CAAC;YACnB,MAAM,CAAC,IAAI,CAAc;gBACvB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,0BAA0B;aACjC,CAAC;YACF,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC;SACvC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,CAC3B,OAAO,EACP,SAAS,EACT,OAAO,EACP,OAAO,CAAC,QAAQ,EAChB,CAAC,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACrB,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACtE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;YAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;QACzC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,IAAI;gBAAE,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;;gBACnD,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAS;YACxC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,IAAI;YAAE,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;;YACtC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC,CACF,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CACjB,IAAwB,EACxB,IAAgB;IAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,IAAI,IAAI;YAAE,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,+DAA+D;QAC/D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,KAAK,CAAC,WAAW,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,KAAK,GAA4B,EAAE,QAAQ,EAAE,CAAC;IACpD,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACpD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7D,IAAI,IAAI,CAAC,aAAa;QAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC;IACtD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9E,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,KAAK,CAAC,cAAc,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAe,CAAC,EAAE,CAAC;gBAClD,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,SAAS,aAAa,CAAC,IAAwB;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,WAAW,CAAC;IAC9B,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,MAAM,CAAC;IACrD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7D,OAAO,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,cAAc,CAAC,MAAsB;IAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAY;QAC5C,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,cAAc;KACrB,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,OAAO,CAAC,IAAY,EAAE,GAAW;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,KAAK,CAAC,OAAe;IAC5B,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { authedClient, globalOptions } from '../context.js';
2
+ import { t } from '../i18n.js';
3
+ import { formatTime, printJson, printLine, printTable } from '../output.js';
4
+ import { parseWhen } from './incidents.js';
5
+ import { parseId } from './servers.js';
6
+ /**
7
+ * Checks of a server as the panel's chart gets them: points over the
8
+ * period, each with the status and latency per location. Longer periods
9
+ * come aggregated into time buckets by the API.
10
+ */
11
+ export function registerServersChecks(servers) {
12
+ servers
13
+ .command('checks')
14
+ .description(t.cmdServersChecks)
15
+ .argument('<id>', 'id', parseId)
16
+ .option('--since <when>', t.optChecksSince)
17
+ .option('--until <when>', t.optChecksUntil)
18
+ .action(async (id, opts, command) => {
19
+ const query = {
20
+ startDate: opts.since ? parseWhen(opts.since) : undefined,
21
+ endDate: opts.until ? parseWhen(opts.until) : undefined,
22
+ };
23
+ const { client } = await authedClient(command);
24
+ const groups = await client.call({
25
+ method: 'GET',
26
+ path: `/v1/servers/${id}/checks`,
27
+ query,
28
+ });
29
+ if (globalOptions(command).json) {
30
+ printJson(groups);
31
+ return;
32
+ }
33
+ // For a day the API adds the last raw checks (`raw:…`) on top of the
34
+ // aggregated points, so the panel's chart keeps moving between them;
35
+ // in a table they repeat the points next to them.
36
+ const points = groups.some((g) => !g.group_id.startsWith('raw:'))
37
+ ? groups.filter((g) => !g.group_id.startsWith('raw:'))
38
+ : groups;
39
+ if (!points.length) {
40
+ printLine(t.checksEmpty);
41
+ return;
42
+ }
43
+ printTable([t.colTime, t.colStatus, t.colLocations], points.map((group) => [
44
+ formatTime(group.group_checked_at),
45
+ group.locations.some((l) => l.status === 'offline')
46
+ ? 'offline'
47
+ : 'online',
48
+ group.locations
49
+ .map((l) => l.status === 'online'
50
+ ? `${l.location} ${Math.round(l.latency)} ms`
51
+ : `${l.location} ${l.status}`)
52
+ .join(', '),
53
+ ]));
54
+ });
55
+ }
56
+ //# sourceMappingURL=servers-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"servers-checks.js","sourceRoot":"","sources":["../../src/commands/servers-checks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAevC;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC;SAC/B,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;SAC/B,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,cAAc,CAAC;SAC1C,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,cAAc,CAAC;SAC1C,MAAM,CACL,KAAK,EACH,EAAU,EACV,IAAwC,EACxC,OAAgB,EAChB,EAAE;QACF,MAAM,KAAK,GAAG;YACZ,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YACzD,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SACxD,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAe;YAC7C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,eAAe,EAAE,SAAS;YAChC,KAAK;SACN,CAAC,CAAC;QACH,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,qEAAqE;QACrE,qEAAqE;QACrE,kDAAkD;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/D,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC,CAAC,MAAM,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,UAAU,CACR,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,EACxC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACpB,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC;YAClC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;gBACjD,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,QAAQ;YACZ,KAAK,CAAC,SAAS;iBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,MAAM,KAAK,QAAQ;gBACnB,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK;gBAC7C,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,CAChC;iBACA,IAAI,CAAC,IAAI,CAAC;SACd,CAAC,CACH,CAAC;IACJ,CAAC,CACF,CAAC;AACN,CAAC"}