@checkstack/healthcheck-script-backend 0.3.17 → 0.4.1

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/src/strategy.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { spawn, type Subprocess } from "bun";
2
1
  import {
3
2
  HealthCheckStrategy,
4
3
  HealthCheckRunForAggregation,
@@ -14,6 +13,7 @@ import {
14
13
  type ConnectedClient,
15
14
  type InferAggregatedResult,
16
15
  baseStrategyConfigSchema,
16
+ defaultShellScriptRunner,
17
17
  } from "@checkstack/backend-api";
18
18
  import {
19
19
  healthResultBoolean,
@@ -35,7 +35,7 @@ import { extractErrorMessage } from "@checkstack/common";
35
35
 
36
36
  /**
37
37
  * Configuration schema for Script health checks.
38
- * Global defaults only - action params moved to ExecuteCollector.
38
+ * Global defaults only - action params live on the per-collector schema.
39
39
  */
40
40
  export const scriptConfigSchema = baseStrategyConfigSchema.extend({});
41
41
 
@@ -146,83 +146,29 @@ interface ScriptExecutionResult {
146
146
 
147
147
  export interface ScriptExecutor {
148
148
  execute(config: {
149
- command: string;
150
- args: string[];
149
+ script: string;
151
150
  cwd?: string;
152
151
  env?: Record<string, string>;
153
152
  timeout: number;
154
153
  }): Promise<ScriptExecutionResult>;
155
154
  }
156
155
 
157
- const SAFE_ENV_VARS = [
158
- "PATH",
159
- "HOME",
160
- "USER",
161
- "LANG",
162
- "LC_ALL",
163
- "LC_CTYPE",
164
- "TZ",
165
- "TMPDIR",
166
- "HOSTNAME",
167
- "SHELL",
168
- ];
169
-
170
- // Default executor using Bun.spawn
156
+ /**
157
+ * Default executor — delegates to the shared `ShellScriptRunner` in
158
+ * `@checkstack/backend-api`. That module is the canonical home for the
159
+ * `sh -c` + safe-env-vars + timeout/kill/cleanup pattern (also used by
160
+ * the integration shell provider). This thin adapter exists so tests
161
+ * can substitute a mock for `ScriptExecutor` without touching the
162
+ * shared runner.
163
+ */
171
164
  const defaultScriptExecutor: ScriptExecutor = {
172
165
  async execute(config) {
173
- let proc: Subprocess | undefined;
174
- let timedOut = false;
175
-
176
- const timeoutPromise = new Promise<never>((_, reject) => {
177
- setTimeout(() => {
178
- timedOut = true;
179
- proc?.kill();
180
- reject(new Error("Script execution timed out"));
181
- }, config.timeout);
166
+ return defaultShellScriptRunner.run({
167
+ script: config.script,
168
+ timeoutMs: config.timeout,
169
+ cwd: config.cwd,
170
+ env: config.env,
182
171
  });
183
-
184
- const safeEnv: Record<string, string> = {};
185
- for (const key of SAFE_ENV_VARS) {
186
- if (process.env[key] !== undefined) {
187
- safeEnv[key] = process.env[key]!;
188
- }
189
- }
190
-
191
- try {
192
- proc = spawn({
193
- cmd: [config.command, ...config.args],
194
- cwd: config.cwd,
195
- env: { ...safeEnv, ...config.env },
196
- stdout: "pipe",
197
- stderr: "pipe",
198
- });
199
-
200
- const [stdout, stderr, exitCode] = await Promise.race([
201
- Promise.all([
202
- new Response(proc.stdout as ReadableStream).text(),
203
- new Response(proc.stderr as ReadableStream).text(),
204
- proc.exited,
205
- ]),
206
- timeoutPromise,
207
- ]);
208
-
209
- return {
210
- exitCode,
211
- stdout: stdout.trim(),
212
- stderr: stderr.trim(),
213
- timedOut: false,
214
- };
215
- } catch (error) {
216
- if (timedOut) {
217
- return {
218
- exitCode: -1,
219
- stdout: "",
220
- stderr: "Script execution timed out",
221
- timedOut: true,
222
- };
223
- }
224
- throw error;
225
- }
226
172
  },
227
173
  };
228
174
 
@@ -310,8 +256,7 @@ export class ScriptHealthCheckStrategy implements HealthCheckStrategy<
310
256
  exec: async (request: ScriptRequest): Promise<ScriptResultType> => {
311
257
  try {
312
258
  const result = await this.executor.execute({
313
- command: request.command,
314
- args: request.args,
259
+ script: request.script,
315
260
  cwd: request.cwd,
316
261
  env: request.env,
317
262
  timeout: request.timeout,
@@ -2,12 +2,19 @@ import type { TransportClient } from "@checkstack/common";
2
2
 
3
3
  /**
4
4
  * Script execution request.
5
+ *
6
+ * The {@link script} field is interpreted by the host shell via `sh -c`,
7
+ * so it can contain pipes, redirects, variable expansion, command substitution,
8
+ * `if` / `for` / `while` blocks, etc. — anything POSIX `sh` understands.
5
9
  */
6
10
  export interface ScriptRequest {
7
- command: string;
8
- args: string[];
11
+ /** Shell script source. Executed via `sh -c <script>`. */
12
+ script: string;
13
+ /** Optional working directory. */
9
14
  cwd?: string;
15
+ /** Optional extra environment variables (merged on top of the safe-vars whitelist). */
10
16
  env?: Record<string, string>;
17
+ /** Maximum execution time in milliseconds. */
11
18
  timeout: number;
12
19
  }
13
20
 
@@ -23,7 +30,7 @@ export interface ScriptResult {
23
30
  }
24
31
 
25
32
  /**
26
- * Script transport client for command execution.
33
+ * Script transport client for shell-script execution.
27
34
  */
28
35
  export type ScriptTransportClient = TransportClient<
29
36
  ScriptRequest,