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.
- package/dist/ai-context/public-skills/checkly/SKILL.md +22 -2
- package/dist/constructs/agentic-check-codegen.js +1 -0
- package/dist/constructs/agentic-check-codegen.js.map +1 -1
- package/dist/constructs/agentic-check.d.ts +37 -0
- package/dist/constructs/api-check-bundle.d.ts +44 -0
- package/dist/constructs/api-check.d.ts +40 -0
- package/dist/constructs/browser-check-bundle.d.ts +41 -0
- package/dist/constructs/browser-check.d.ts +37 -0
- package/dist/constructs/check-codegen.d.ts +22 -0
- package/dist/constructs/check-codegen.js +20 -0
- package/dist/constructs/check-codegen.js.map +1 -1
- package/dist/constructs/check.d.ts +151 -1
- package/dist/constructs/check.js +112 -0
- package/dist/constructs/check.js.map +1 -1
- package/dist/constructs/dns-monitor.d.ts +40 -1
- package/dist/constructs/dns-monitor.js +7 -0
- package/dist/constructs/dns-monitor.js.map +1 -1
- package/dist/constructs/grpc-monitor.d.ts +40 -1
- package/dist/constructs/grpc-monitor.js +7 -0
- package/dist/constructs/grpc-monitor.js.map +1 -1
- package/dist/constructs/heartbeat-monitor-codegen.js +3 -1
- package/dist/constructs/heartbeat-monitor-codegen.js.map +1 -1
- package/dist/constructs/icmp-monitor.d.ts +40 -1
- package/dist/constructs/icmp-monitor.js +7 -0
- package/dist/constructs/icmp-monitor.js.map +1 -1
- package/dist/constructs/monitor.d.ts +32 -0
- package/dist/constructs/multi-step-check-bundle.d.ts +39 -0
- package/dist/constructs/multi-step-check.d.ts +36 -0
- package/dist/constructs/playwright-check-bundle.d.ts +44 -0
- package/dist/constructs/playwright-check.d.ts +37 -0
- package/dist/constructs/ssl-monitor-codegen.js +3 -1
- package/dist/constructs/ssl-monitor-codegen.js.map +1 -1
- package/dist/constructs/ssl-monitor.d.ts +50 -0
- package/dist/constructs/tcp-monitor.d.ts +40 -1
- package/dist/constructs/tcp-monitor.js +7 -0
- package/dist/constructs/tcp-monitor.js.map +1 -1
- package/dist/constructs/traceroute-monitor-codegen.js +3 -1
- package/dist/constructs/traceroute-monitor-codegen.js.map +1 -1
- package/dist/constructs/traceroute-monitor.d.ts +36 -0
- package/dist/constructs/url-monitor.d.ts +46 -1
- package/dist/constructs/url-monitor.js +4 -0
- package/dist/constructs/url-monitor.js.map +1 -1
- package/dist/helpers/result-assets.js +19 -6
- package/dist/helpers/result-assets.js.map +1 -1
- package/dist/rest/api.js +5 -0
- package/dist/rest/api.js.map +1 -1
- package/dist/rest/retry.d.ts +55 -0
- package/dist/rest/retry.js +169 -0
- package/dist/rest/retry.js.map +1 -0
- package/oclif.manifest.json +601 -601
- 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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"}
|