@kedge/cli 0.0.0-stage → 0.10.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.
@@ -0,0 +1,66 @@
1
+ // The CLI's own audited batches against a store's D1 (p0.5 §3.4, D-054):
2
+ // `staff`, direct `keys create`, and a CLI session's row (p0.10 §6.2), each
3
+ // one file through `wrangler d1 execute`, locally or on Cloudflare.
4
+ import { spawnSync } from "node:child_process";
5
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
8
+ import type { CliBatch } from "@kedge/db";
9
+ import { wranglerBin } from "./cf";
10
+ import { childStdio } from "./output";
11
+
12
+ /** Runs one CLI batch against the store's D1; tests replace it. */
13
+ export type Executor = (
14
+ b: CliBatch,
15
+ opts: { database: string; remote: boolean; cwd: string; config?: string; env?: Record<string, string> },
16
+ ) => number;
17
+
18
+ /** The bootstrap Wrangler's whole environment: PATH, an empty HOME, and what Kedge resolved. */
19
+ export function bootstrapEnv(
20
+ env: NodeJS.ProcessEnv,
21
+ home: string,
22
+ resolved: Record<string, string> = {},
23
+ ): Record<string, string> {
24
+ return { PATH: env.PATH ?? "", HOME: home, WRANGLER_SEND_METRICS: "false", CI: "1", ...resolved };
25
+ }
26
+
27
+ export const wranglerExecute: Executor = (b, opts) => {
28
+ const dir = mkdtempSync(join(tmpdir(), "kedge-"));
29
+ const file = join(dir, "batch.sql");
30
+ // An empty dotenv file of our own: Wrangler then loads none of the store's, whose stale
31
+ // CLOUDFLARE_* values could redirect the resolved credentials (codex code r4).
32
+ const envFile = join(dir, "empty.env");
33
+ try {
34
+ writeFileSync(file, b.sql, { mode: 0o600 });
35
+ writeFileSync(envFile, "");
36
+ // The CLI's own Wrangler with only what Kedge resolved: an inherited environment could carry a
37
+ // global API key, which Wrangler prefers to a token and would send instead (codex code r5),
38
+ // and an empty HOME holds no one's login. The store directory stays the working one, for its
39
+ // config and its local state.
40
+ const r = spawnSync(
41
+ process.execPath,
42
+ [
43
+ wranglerBin(),
44
+ "d1",
45
+ "execute",
46
+ opts.database,
47
+ "--file",
48
+ file,
49
+ opts.remote ? "--remote" : "--local",
50
+ "--yes",
51
+ "--env-file",
52
+ envFile,
53
+ ...(opts.config ? ["-c", opts.config] : []),
54
+ ],
55
+ {
56
+ cwd: opts.cwd,
57
+ stdio: childStdio(),
58
+ env: bootstrapEnv(process.env, dir, opts.env),
59
+ },
60
+ );
61
+ return r.status ?? 1;
62
+ } finally {
63
+ // The file holds no secret (only digests), but it needn't outlive the run.
64
+ rmSync(dir, { recursive: true, force: true });
65
+ }
66
+ };