/ opencodehub / scripts / verify-env-config.ts
Swadhin Biswas refactor(storage): trim to local + S3-compatible; add NAS exposure guide · 6/4/2026
ca015da
88 lines · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
 * Verify the two supported storage backends (`local` and `s3`) end-to-end:
 *  1. Environment validation accepts a valid S3 config and rejects an incomplete one.
 *  2. `getStorageConfig()` returns a clean, S3-shaped object from env vars.
 *  3. `createStorageAdapter` produces an `S3StorageAdapter` for `type=s3` and a
 *     `LocalStorageAdapter` for `type=local`.
 *
 * Usage:  bun run scripts/verify-env-config.ts
 */
import { validateEnvironment } from "../src/lib/env-validation";
import { createStorageAdapter, getStorageConfig } from "../src/lib/storage";

process.env.JWT_SECRET ??= "a".repeat(32);
process.env.SESSION_SECRET ??= "a".repeat(32);
process.env.INTERNAL_HOOK_SECRET ??= "a".repeat(32);
process.env.SITE_URL ??= "http://localhost:3000";

function assert(cond: boolean, msg: string) {
  if (!cond) {
    console.error(`❌ ${msg}`);
    process.exit(1);
  }
  console.log(`✅ ${msg}`);
}

function clearStorageEnv() {
  for (const k of [
    "STORAGE_TYPE",
    "STORAGE_PATH",
    "STORAGE_BUCKET",
    "STORAGE_REGION",
    "STORAGE_ENDPOINT",
    "STORAGE_ACCESS_KEY_ID",
    "STORAGE_SECRET_ACCESS_KEY",
  ]) {
    delete process.env[k];
  }
}

async function verify() {
  console.log("Running storage verification...\n");

  // 1. local default
  console.log("[1/3] Default (local) config:");
  clearStorageEnv();
  const localCfg = getStorageConfig();
  assert(localCfg.type === "local", "default type is 'local'");
  assert(localCfg.basePath === "./data/storage", "default basePath is './data/storage'");

  // 2. s3 valid
  console.log("\n[2/3] Valid S3 config:");
  clearStorageEnv();
  process.env.STORAGE_TYPE = "s3";
  process.env.STORAGE_BUCKET = "my-bucket";
  process.env.STORAGE_ACCESS_KEY_ID = "AKIA-test";
  process.env.STORAGE_SECRET_ACCESS_KEY = "secret";
  process.env.STORAGE_REGION = "us-west-2";
  process.env.STORAGE_ENDPOINT = "https://s3.us-west-2.example.com";
  const valid = validateEnvironment(false);
  assert(valid, "validation passes for a complete S3 config");
  const s3Cfg = getStorageConfig();
  assert(s3Cfg.type === "s3", "getStorageConfig returns type='s3'");
  assert(s3Cfg.bucket === "my-bucket", "bucket is read from env");
  assert(s3Cfg.region === "us-west-2", "region is read from env");
  assert(s3Cfg.endpoint === "https://s3.us-west-2.example.com", "endpoint is read from env");
  const adapter = createStorageAdapter(s3Cfg);
  assert(adapter.constructor.name === "S3StorageAdapter", "factory returns S3StorageAdapter");

  // 3. s3 missing required
  console.log("\n[3/3] Missing required S3 vars (validation should reject):");
  clearStorageEnv();
  process.env.STORAGE_TYPE = "s3";
  // no bucket / creds
  const invalid = validateEnvironment(false);
  assert(!invalid, "validation fails when S3 vars are missing");

  // local adapter round-trip
  clearStorageEnv();
  process.env.STORAGE_TYPE = "local";
  process.env.STORAGE_PATH = "/tmp/opencodehub-test-storage";
  const localAdapter = createStorageAdapter(getStorageConfig());
  assert(localAdapter.constructor.name === "LocalStorageAdapter", "factory returns LocalStorageAdapter for type=local");

  console.log("\n🎉 ALL VERIFICATION CHECKS PASSED!");
}

verify();