Skip to content

Commit d3bebca

Browse files
Shawclaude
andcommitted
chore(cloud): scripts/cloud/local-reset.mjs + root alias
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b1cc5e7 commit d3bebca

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
"db:cloud:migrate": "bun run packages/scripts/cloud/admin/migrate-with-diagnostics.ts",
160160
"db:cloud:studio": "bun run --cwd packages/cloud-shared db:studio",
161161
"db:cloud:pglite": "bun run packages/scripts/cloud/admin/dev/pglite-server.ts",
162+
"cloud:local:reset": "node scripts/cloud/local-reset.mjs",
162163
"publish:dry-run": "bun packages/scripts/publish-from-dist.mjs",
163164
"publish:packages": "bun packages/scripts/publish-from-dist.mjs --apply",
164165
"typecheck:dist": "NODE_OPTIONS='--max-old-space-size=8192' tsc --noEmit -p tsconfig.dist-paths.json"

scripts/cloud/local-reset.mjs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Local Cloud reset utility.
4+
*
5+
* - Wipes the PGlite data directory (only when DATABASE_URL is a local pglite:// path)
6+
* - Wipes the local in-memory Redis snapshot file (if any)
7+
* - Re-applies cloud-shared Drizzle migrations
8+
*
9+
* Refuses to run if DATABASE_URL looks like a remote Postgres host.
10+
*
11+
* Pass --dry-run to print actions without performing them.
12+
*/
13+
import { execSync } from "node:child_process";
14+
import { existsSync, rmSync, statSync } from "node:fs";
15+
import path from "node:path";
16+
import { fileURLToPath } from "node:url";
17+
18+
const __filename = fileURLToPath(import.meta.url);
19+
const __dirname = path.dirname(__filename);
20+
const repoRoot = path.resolve(__dirname, "..", "..");
21+
22+
const argv = process.argv.slice(2);
23+
const DRY = argv.includes("--dry-run");
24+
25+
function log(...args) {
26+
console.log("[cloud:local:reset]", ...args);
27+
}
28+
29+
function fail(msg) {
30+
console.error("[cloud:local:reset] ERROR:", msg);
31+
process.exit(1);
32+
}
33+
34+
const DATABASE_URL = process.env.DATABASE_URL ?? "";
35+
36+
// Safety: refuse anything that isn't an obviously local pglite path or localhost.
37+
const isPgliteLocal = /^pglite:\/\/\.\//.test(DATABASE_URL);
38+
const isLocalhostPg =
39+
/^postgres(ql)?:\/\/[^@]*@(localhost|127\.0\.0\.1)(:\d+)?\//.test(
40+
DATABASE_URL,
41+
);
42+
43+
if (!DATABASE_URL) {
44+
fail("DATABASE_URL is not set. Refusing to run.");
45+
}
46+
if (!isPgliteLocal && !isLocalhostPg) {
47+
fail(
48+
`DATABASE_URL='${DATABASE_URL}' does not look local (pglite://./… or postgres://…@localhost). Refusing.`,
49+
);
50+
}
51+
52+
const pgliteRel =
53+
isPgliteLocal && DATABASE_URL.replace(/^pglite:\/\//, "").trim();
54+
const pgliteAbs = pgliteRel ? path.resolve(repoRoot, pgliteRel) : null;
55+
const redisSnapshot = path.resolve(repoRoot, ".eliza", ".redis-mock-snapshot.json");
56+
57+
function maybeRemove(target, label) {
58+
if (!target) return;
59+
if (!existsSync(target)) {
60+
log(`${label}: nothing to remove at ${target}`);
61+
return;
62+
}
63+
const stat = statSync(target);
64+
const kind = stat.isDirectory() ? "directory" : "file";
65+
if (DRY) {
66+
log(`[dry-run] would remove ${kind} ${target} (${label})`);
67+
return;
68+
}
69+
log(`removing ${kind} ${target} (${label})`);
70+
rmSync(target, { recursive: true, force: true });
71+
}
72+
73+
maybeRemove(pgliteAbs, "PGlite data dir");
74+
maybeRemove(redisSnapshot, "in-memory redis snapshot");
75+
76+
const migrateCmd = "bun run --cwd packages/cloud-shared db:migrate";
77+
if (DRY) {
78+
log(`[dry-run] would run: ${migrateCmd}`);
79+
log("[dry-run] complete");
80+
process.exit(0);
81+
}
82+
83+
log(`running: ${migrateCmd}`);
84+
try {
85+
execSync(migrateCmd, { cwd: repoRoot, stdio: "inherit" });
86+
} catch (err) {
87+
fail(`migration step failed: ${err?.message ?? err}`);
88+
}
89+
log("done");

0 commit comments

Comments
 (0)