checkly 8.20.0 → 8.21.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 (51) hide show
  1. package/dist/ai-context/public-skills/checkly/SKILL.md +22 -2
  2. package/dist/constructs/agentic-check-codegen.js +1 -0
  3. package/dist/constructs/agentic-check-codegen.js.map +1 -1
  4. package/dist/constructs/agentic-check.d.ts +37 -0
  5. package/dist/constructs/api-check-bundle.d.ts +44 -0
  6. package/dist/constructs/api-check.d.ts +40 -0
  7. package/dist/constructs/browser-check-bundle.d.ts +41 -0
  8. package/dist/constructs/browser-check.d.ts +37 -0
  9. package/dist/constructs/check-codegen.d.ts +22 -0
  10. package/dist/constructs/check-codegen.js +20 -0
  11. package/dist/constructs/check-codegen.js.map +1 -1
  12. package/dist/constructs/check.d.ts +151 -1
  13. package/dist/constructs/check.js +112 -0
  14. package/dist/constructs/check.js.map +1 -1
  15. package/dist/constructs/dns-monitor.d.ts +40 -1
  16. package/dist/constructs/dns-monitor.js +7 -0
  17. package/dist/constructs/dns-monitor.js.map +1 -1
  18. package/dist/constructs/grpc-monitor.d.ts +40 -1
  19. package/dist/constructs/grpc-monitor.js +7 -0
  20. package/dist/constructs/grpc-monitor.js.map +1 -1
  21. package/dist/constructs/heartbeat-monitor-codegen.js +3 -1
  22. package/dist/constructs/heartbeat-monitor-codegen.js.map +1 -1
  23. package/dist/constructs/icmp-monitor.d.ts +40 -1
  24. package/dist/constructs/icmp-monitor.js +7 -0
  25. package/dist/constructs/icmp-monitor.js.map +1 -1
  26. package/dist/constructs/monitor.d.ts +32 -0
  27. package/dist/constructs/multi-step-check-bundle.d.ts +39 -0
  28. package/dist/constructs/multi-step-check.d.ts +36 -0
  29. package/dist/constructs/playwright-check-bundle.d.ts +44 -0
  30. package/dist/constructs/playwright-check.d.ts +37 -0
  31. package/dist/constructs/ssl-monitor-codegen.js +3 -1
  32. package/dist/constructs/ssl-monitor-codegen.js.map +1 -1
  33. package/dist/constructs/ssl-monitor.d.ts +50 -0
  34. package/dist/constructs/tcp-monitor.d.ts +40 -1
  35. package/dist/constructs/tcp-monitor.js +7 -0
  36. package/dist/constructs/tcp-monitor.js.map +1 -1
  37. package/dist/constructs/traceroute-monitor-codegen.js +3 -1
  38. package/dist/constructs/traceroute-monitor-codegen.js.map +1 -1
  39. package/dist/constructs/traceroute-monitor.d.ts +36 -0
  40. package/dist/constructs/url-monitor.d.ts +46 -1
  41. package/dist/constructs/url-monitor.js +4 -0
  42. package/dist/constructs/url-monitor.js.map +1 -1
  43. package/dist/helpers/result-assets.js +19 -6
  44. package/dist/helpers/result-assets.js.map +1 -1
  45. package/dist/rest/api.js +5 -0
  46. package/dist/rest/api.js.map +1 -1
  47. package/dist/rest/retry.d.ts +55 -0
  48. package/dist/rest/retry.js +169 -0
  49. package/dist/rest/retry.js.map +1 -0
  50. package/oclif.manifest.json +601 -601
  51. package/package.json +3 -2
@@ -0,0 +1,55 @@
1
+ import { AxiosInstance, AxiosResponse } from 'axios';
2
+ declare module 'axios' {
3
+ interface AxiosRequestConfig {
4
+ /**
5
+ * Opts a mutating request (POST/PUT/PATCH/DELETE) into transient-error
6
+ * retries. Only set this on endpoints known to be idempotent: a mutation
7
+ * that received a gateway error may still have been applied upstream, and
8
+ * a retry would apply it again.
9
+ *
10
+ * Only honored by the shared REST instance created in api.ts — bare
11
+ * axios calls (e.g. presigned-URL asset downloads) register no retry
12
+ * interceptor, so the flag is inert there.
13
+ *
14
+ * Do not combine with a custom transformRequest: a retry replays the
15
+ * already-transformed body through the transform again, and reuses the
16
+ * previous attempt's Content-Length header, so a non-idempotent or
17
+ * length-changing transform silently corrupts or truncates the body on
18
+ * the wire. (The default JSON transform is idempotent, and
19
+ * stream-producing transforms are blocked by the stream-body guard.)
20
+ */
21
+ checklyRetry?: boolean;
22
+ /** Internal: attempts already made for this logical request. */
23
+ checklyRetryAttempt?: number;
24
+ }
25
+ }
26
+ export interface RetryOptions {
27
+ /** Total attempts including the initial request. */
28
+ attempts?: number;
29
+ /** Base delay for exponential backoff, in milliseconds. */
30
+ baseDelayMs?: number;
31
+ /** Cap for a single jittered backoff delay, in milliseconds. */
32
+ maxBackoffDelayMs?: number;
33
+ /** Largest server-provided Retry-After honored verbatim, in milliseconds. */
34
+ maxRetryAfterMs?: number;
35
+ /**
36
+ * Overridable in tests to avoid real sleeps. The abort signal fires when
37
+ * the wait is abandoned early; a sleep should cancel its timer then.
38
+ */
39
+ sleep?: (ms: number, abortSignal?: AbortSignal) => Promise<void>;
40
+ /** Overridable in tests to make jitter deterministic. */
41
+ random?: () => number;
42
+ }
43
+ /**
44
+ * Parses a Retry-After header value (delay-seconds or HTTP-date) into a
45
+ * delay in milliseconds, or undefined if the value is absent or malformed.
46
+ */
47
+ export declare function parseRetryAfter(value: unknown): number | undefined;
48
+ /**
49
+ * Creates an axios response rejection handler that retries transient upstream
50
+ * failures with bounded, jittered exponential backoff. Register it before the
51
+ * error-mapping interceptor so it sees the raw AxiosError; a successful retry
52
+ * resolves into the next interceptor's fulfilled handler, and an exhausted
53
+ * one rethrows into its rejection handler.
54
+ */
55
+ export declare function createRetryInterceptor(api: AxiosInstance, options?: RetryOptions): (error: unknown) => Promise<AxiosResponse>;
@@ -0,0 +1,169 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ import { isAxiosError } from 'axios';
3
+ import Debug from 'debug';
4
+ const debug = Debug('checkly:cli:rest:retry');
5
+ const DEFAULT_ATTEMPTS = 3;
6
+ const DEFAULT_BASE_DELAY_MS = 250;
7
+ const DEFAULT_MAX_BACKOFF_DELAY_MS = 2000;
8
+ // An explicit server hint is trusted for longer than our own backoff would
9
+ // wait, but still bounded so interactive commands cannot stall indefinitely.
10
+ const DEFAULT_MAX_RETRY_AFTER_MS = 10_000;
11
+ // The transient gateway class only. 408 is deliberately excluded: the API
12
+ // uses it to end long-poll requests, and the polling callers own that retry
13
+ // cadence. Plain 500 is also a conscious exclusion, even though brief API
14
+ // degradations have been observed to produce the occasional 500 alongside
15
+ // 502s: a 500 is just as often a deterministic application failure, and
16
+ // retrying those multiplies load and latency for no benefit.
17
+ const RETRYABLE_STATUS_CODES = new Set([429, 502, 503, 504]);
18
+ // Connection-level failures where no response arrived. Safe to retry for
19
+ // idempotent requests even if the request reached the server.
20
+ const RETRYABLE_ERROR_CODES = new Set([
21
+ 'ECONNRESET',
22
+ 'ETIMEDOUT',
23
+ 'ECONNABORTED',
24
+ 'EAI_AGAIN',
25
+ 'ERR_NETWORK',
26
+ 'EPIPE',
27
+ ]);
28
+ const IDEMPOTENT_METHODS = new Set(['get', 'head', 'options']);
29
+ // The timer must stay ref'd while the wait is live: the caller is awaiting
30
+ // the retried request, and an unref'd timer would let the event loop drain
31
+ // mid-backoff, silently exiting the process with the request unresolved.
32
+ // When the wait is abandoned early (request aborted), the timer is cancelled
33
+ // through the signal so it cannot keep the process alive for the remainder
34
+ // of the delay either.
35
+ function defaultSleep(ms, abortSignal) {
36
+ return delay(ms, undefined, { signal: abortSignal }).catch((err) => {
37
+ // A cancelled backoff sleep is not an error; the caller re-checks the
38
+ // request's own signal after waking up.
39
+ if (err?.name !== 'AbortError') {
40
+ throw err;
41
+ }
42
+ });
43
+ }
44
+ // Resolves when the sleep finishes or the signal aborts, whichever comes
45
+ // first, so an aborted caller is not kept waiting out the backoff delay.
46
+ async function sleepUnlessAborted(sleep, ms, signal) {
47
+ if (signal?.aborted) {
48
+ return;
49
+ }
50
+ // A real AbortController of our own (config.signal is only a
51
+ // GenericAbortSignal, which node's timers reject): aborted once the race
52
+ // settles, so a lost sleep timer cannot linger and keep the process alive.
53
+ const sleepAbort = new AbortController();
54
+ let onAbort;
55
+ try {
56
+ await Promise.race([
57
+ sleep(ms, sleepAbort.signal),
58
+ new Promise(resolve => {
59
+ onAbort = resolve;
60
+ signal?.addEventListener?.('abort', onAbort);
61
+ }),
62
+ ]);
63
+ }
64
+ finally {
65
+ sleepAbort.abort();
66
+ if (onAbort !== undefined) {
67
+ signal?.removeEventListener?.('abort', onAbort);
68
+ }
69
+ }
70
+ }
71
+ /**
72
+ * Parses a Retry-After header value (delay-seconds or HTTP-date) into a
73
+ * delay in milliseconds, or undefined if the value is absent or malformed.
74
+ */
75
+ export function parseRetryAfter(value) {
76
+ if (typeof value !== 'string' || value === '') {
77
+ return undefined;
78
+ }
79
+ const seconds = Number(value);
80
+ if (!Number.isNaN(seconds)) {
81
+ return seconds >= 0 ? seconds * 1000 : undefined;
82
+ }
83
+ const date = Date.parse(value);
84
+ if (Number.isNaN(date)) {
85
+ return undefined;
86
+ }
87
+ return Math.max(0, date - Date.now());
88
+ }
89
+ function isStream(value) {
90
+ return value !== null && typeof value === 'object' && typeof value.pipe === 'function';
91
+ }
92
+ /**
93
+ * Whether the request itself may be replayed: idempotent method (or explicit
94
+ * opt-in), not aborted, and no single-use stream involved on either side.
95
+ */
96
+ function isRetryableRequest(config) {
97
+ if (config.signal?.aborted) {
98
+ return false;
99
+ }
100
+ // Streamed responses (e.g. the deployment progress SSE stream) may have
101
+ // been partially consumed by the caller and cannot be transparently
102
+ // reissued. Streamed request bodies (e.g. gzipped payloads and file
103
+ // uploads) are single-use and already drained by the failed attempt. If
104
+ // upload resilience is wanted later, it belongs at the call site, which
105
+ // can re-create the stream (e.g. re-open the file) before retrying.
106
+ if (config.responseType === 'stream' || isStream(config.data)) {
107
+ return false;
108
+ }
109
+ const method = (config.method ?? 'get').toLowerCase();
110
+ return IDEMPOTENT_METHODS.has(method) || config.checklyRetry === true;
111
+ }
112
+ /**
113
+ * Whether the failure looks transient: a retryable gateway status, or a
114
+ * connection-level error with no response at all.
115
+ */
116
+ function isRetryableFailure(error) {
117
+ if (error.response !== undefined) {
118
+ return RETRYABLE_STATUS_CODES.has(error.response.status);
119
+ }
120
+ return error.code !== undefined && RETRYABLE_ERROR_CODES.has(error.code);
121
+ }
122
+ /**
123
+ * Creates an axios response rejection handler that retries transient upstream
124
+ * failures with bounded, jittered exponential backoff. Register it before the
125
+ * error-mapping interceptor so it sees the raw AxiosError; a successful retry
126
+ * resolves into the next interceptor's fulfilled handler, and an exhausted
127
+ * one rethrows into its rejection handler.
128
+ */
129
+ export function createRetryInterceptor(api, options) {
130
+ const { attempts = DEFAULT_ATTEMPTS, baseDelayMs = DEFAULT_BASE_DELAY_MS, maxBackoffDelayMs = DEFAULT_MAX_BACKOFF_DELAY_MS, maxRetryAfterMs = DEFAULT_MAX_RETRY_AFTER_MS, sleep = defaultSleep, random = Math.random, } = options ?? {};
131
+ return async function retryInterceptor(error) {
132
+ if (!isAxiosError(error) || error.config === undefined) {
133
+ throw error;
134
+ }
135
+ const { config } = error;
136
+ if (!isRetryableRequest(config) || !isRetryableFailure(error)) {
137
+ throw error;
138
+ }
139
+ const attempt = config.checklyRetryAttempt ?? 1;
140
+ if (attempt >= attempts) {
141
+ throw error;
142
+ }
143
+ const status = error.response?.status;
144
+ const retryAfterMs = parseRetryAfter(error.response?.headers?.['retry-after']);
145
+ let delayMs;
146
+ if (retryAfterMs !== undefined && retryAfterMs <= maxRetryAfterMs) {
147
+ delayMs = retryAfterMs;
148
+ }
149
+ else if (status === 429 && retryAfterMs !== undefined) {
150
+ // The server asked for a longer wait than our delay budget allows.
151
+ // Retrying earlier than requested would likely just get throttled
152
+ // again, so give up instead.
153
+ throw error;
154
+ }
155
+ else {
156
+ // Full jitter: a uniformly random delay up to the exponential bound
157
+ // spreads out concurrent clients hitting the same degraded gateway.
158
+ delayMs = Math.round(random() * Math.min(maxBackoffDelayMs, baseDelayMs * 2 ** (attempt - 1)));
159
+ }
160
+ debug('Retrying %s %s after %s (attempt %d of %d, delay %dms)', (config.method ?? 'get').toUpperCase(), config.url, status ?? error.code, attempt + 1, attempts, delayMs);
161
+ await sleepUnlessAborted(sleep, delayMs, config.signal);
162
+ if (config.signal?.aborted) {
163
+ throw error;
164
+ }
165
+ config.checklyRetryAttempt = attempt + 1;
166
+ return api.request(config);
167
+ };
168
+ }
169
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/rest/retry.ts"],"names":[],"mappings":"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"}