@fudrouter/fsrouter 0.6.103 → 0.6.104

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.
@@ -1,20 +1,73 @@
1
1
  // Recreate codebuddyAccounts table to drop the single-column UNIQUE(email)
2
2
  // and replace it with composite UNIQUE(email, provider).
3
+ // Idempotent: handles both legacy `ammailAlias` and renamed `fsmailAlias`
4
+ // columns in the old table (older DBs may have run migration 003/004 before
5
+ // this migration's version was recorded, leaving `fsmailAlias` in _old).
3
6
  export default {
4
7
  version: 2,
5
8
  name: "composite-unique-codebuddy-accounts",
6
9
  up(db) {
10
+ // If the table doesn't exist at all, just create it fresh and bail.
11
+ const exists = db.get(
12
+ "SELECT 1 FROM sqlite_master WHERE type='table' AND name='codebuddyAccounts'"
13
+ );
14
+ if (!exists) {
15
+ db.exec(`
16
+ CREATE TABLE codebuddyAccounts (
17
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
18
+ email TEXT NOT NULL,
19
+ password TEXT NOT NULL,
20
+ profileDir TEXT,
21
+ fsmailAlias TEXT,
22
+ signupMethod TEXT DEFAULT 'google',
23
+ apiKey TEXT,
24
+ apiKeyStatus TEXT DEFAULT 'pending',
25
+ lastError TEXT,
26
+ lastRunAt INTEGER,
27
+ createdAt TEXT NOT NULL,
28
+ provider TEXT DEFAULT 'codebuddy',
29
+ canvaEnrolled INTEGER DEFAULT 0,
30
+ UNIQUE(email, provider)
31
+ )
32
+ `);
33
+ db.exec("CREATE INDEX IF NOT EXISTS idx_cba_email ON codebuddyAccounts(email)");
34
+ return;
35
+ }
36
+
37
+ // Detect which alias column the existing (old) table uses.
38
+ const info = db.all("PRAGMA table_info(codebuddyAccounts)");
39
+ const cols = info.map((c) => c.name);
40
+ const hasFsmail = cols.includes("fsmailAlias");
41
+ const hasAmmail = cols.includes("ammailAlias");
42
+ const oldAlias = hasFsmail ? "fsmailAlias" : hasAmmail ? "ammailAlias" : null;
43
+
44
+ // Already on the target schema (composite unique + fsmailAlias) — skip.
45
+ if (hasFsmail) {
46
+ const idx = db.all(
47
+ "SELECT 1 FROM sqlite_master WHERE type='index' AND name='sqlite_autoindex_codebuddyAccounts_1'"
48
+ );
49
+ // The composite UNIQUE was added by this migration; if it's already there, nothing to do.
50
+ try {
51
+ db.get("SELECT email, provider FROM codebuddyAccounts LIMIT 1");
52
+ } catch { /* ignore */ }
53
+ // If a composite index already exists we can safely skip.
54
+ const compIdx = db.all(
55
+ "SELECT * FROM sqlite_master WHERE type='index' AND tbl_name='codebuddyAccounts' AND sql LIKE '%email%provider%'"
56
+ );
57
+ if (compIdx.length > 0) return;
58
+ }
59
+
7
60
  // 1. Rename existing table
8
61
  db.exec("ALTER TABLE codebuddyAccounts RENAME TO codebuddyAccounts_old");
9
62
 
10
- // 2. Create new table with unique(email, provider) constraint
63
+ // 2. Create new table with unique(email, provider) constraint + fsmailAlias
11
64
  db.exec(`
12
65
  CREATE TABLE codebuddyAccounts (
13
66
  id INTEGER PRIMARY KEY AUTOINCREMENT,
14
67
  email TEXT NOT NULL,
15
68
  password TEXT NOT NULL,
16
69
  profileDir TEXT,
17
- ammailAlias TEXT,
70
+ fsmailAlias TEXT,
18
71
  signupMethod TEXT DEFAULT 'google',
19
72
  apiKey TEXT,
20
73
  apiKeyStatus TEXT DEFAULT 'pending',
@@ -30,14 +83,15 @@ export default {
30
83
  // 3. Recreate index
31
84
  db.exec("CREATE INDEX IF NOT EXISTS idx_cba_email ON codebuddyAccounts(email)");
32
85
 
33
- // 4. Copy data from old table, ignoring any constraint violations.
86
+ // 4. Copy data from old table, mapping whichever alias column exists.
87
+ const aliasSelect = oldAlias || "NULL";
34
88
  db.exec(`
35
89
  INSERT OR IGNORE INTO codebuddyAccounts (
36
- id, email, password, profileDir, ammailAlias, signupMethod,
90
+ id, email, password, profileDir, fsmailAlias, signupMethod,
37
91
  apiKey, apiKeyStatus, lastError, lastRunAt, createdAt, provider, canvaEnrolled
38
92
  )
39
- SELECT
40
- id, email, password, profileDir, ammailAlias, signupMethod,
93
+ SELECT
94
+ id, email, password, profileDir, ${aliasSelect}, signupMethod,
41
95
  apiKey, apiKeyStatus, lastError, lastRunAt, createdAt, provider, canvaEnrolled
42
96
  FROM codebuddyAccounts_old
43
97
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fudrouter/fsrouter",
3
- "version": "0.6.103",
3
+ "version": "0.6.104",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "9Router v2 — Express Backend (API, SSE, DB, Auth, MITM)",