@cleocode/core 2026.5.133 → 2026.5.134

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,16 @@
1
+ /**
2
+ * Exodus subsystem public API barrel.
3
+ *
4
+ * Re-exports the public surface of the `cleo exodus` migration engine:
5
+ * plan builder, migrate runner, verify runner, and status reporter.
6
+ *
7
+ * @module
8
+ * @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
9
+ * @saga T11242
10
+ */
11
+ export { runExodusMigrate } from './migrate.js';
12
+ export { buildExodusPlan, deriveStagingDirName, sourcesPresent } from './plan.js';
13
+ export { runExodusStatus } from './status.js';
14
+ export { EXODUS_TARGET_SCHEMA_VERSION, type ExodusJournal, type ExodusMigrateResult, type ExodusPlan, type ExodusScope, type ExodusStatusResult, type ExodusVerifyResult, type JournalTableEntry, type LegacyDbDescriptor, type TableCopyResult, type TableMigrationStatus, type VerifyTableResult, } from './types.js';
15
+ export { runExodusVerify } from './verify.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,4BAA4B,EAC5B,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Exodus subsystem public API barrel.
3
+ *
4
+ * Re-exports the public surface of the `cleo exodus` migration engine:
5
+ * plan builder, migrate runner, verify runner, and status reporter.
6
+ *
7
+ * @module
8
+ * @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
9
+ * @saga T11242
10
+ */
11
+ export { runExodusMigrate } from './migrate.js';
12
+ export { buildExodusPlan, deriveStagingDirName, sourcesPresent } from './plan.js';
13
+ export { runExodusStatus } from './status.js';
14
+ export { EXODUS_TARGET_SCHEMA_VERSION, } from './types.js';
15
+ export { runExodusVerify } from './verify.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/store/exodus/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,4BAA4B,GAY7B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Exodus migration engine.
3
+ *
4
+ * `runExodusMigrate()` performs the actual data migration from legacy DBs
5
+ * to the consolidated dual-scope `cleo.db`. Key invariants:
6
+ *
7
+ * - Source DBs are opened **read-only** via `openCleoDbSnapshot` (AC4).
8
+ * - Source files are backed up to the staging dir before any writes (AC5).
9
+ * - Import is wrapped in `BEGIN … COMMIT` per scope; partial failure leaves
10
+ * the target DB untouched (AC6).
11
+ * - Idempotency keys are propagated where the source row has them; generated
12
+ * where it does not (AC7).
13
+ * - The staging journal is written atomically before each table copy so a
14
+ * crash can be resumed (AC5).
15
+ *
16
+ * ## Advisory file lock (AC4)
17
+ *
18
+ * The source DB files are opened read-only via `openCleoDbSnapshot` which
19
+ * calls `new DatabaseSync(path, { readOnly: true })`. Node's SQLite binding
20
+ * opens with `SQLITE_OPEN_READONLY`, which prevents any writes from this
21
+ * process. We additionally write a `.lock` sentinel file next to each source
22
+ * DB for the duration of the migration so that other CLEO processes can detect
23
+ * an in-progress exodus and refuse to write.
24
+ *
25
+ * @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
26
+ * @saga T11242
27
+ */
28
+ import type { ExodusMigrateResult, ExodusPlan } from './types.js';
29
+ /**
30
+ * Run the exodus migration.
31
+ *
32
+ * @param plan - Pre-flight plan from `buildExodusPlan()`.
33
+ * @param forceCrossVersion - Skip the schema-version guard (AC9).
34
+ * @param onProgress - Optional progress callback called after each table.
35
+ *
36
+ * @returns {@link ExodusMigrateResult}
37
+ *
38
+ * @task T11248 (AC4, AC5, AC6, AC7, AC9)
39
+ */
40
+ export declare function runExodusMigrate(plan: ExodusPlan, forceCrossVersion?: boolean, onProgress?: (msg: string) => void): Promise<ExodusMigrateResult>;
41
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAiBH,OAAO,KAAK,EAEV,mBAAmB,EACnB,UAAU,EAKX,MAAM,YAAY,CAAC;AA+MpB;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,UAAU,EAChB,iBAAiB,UAAQ,EACzB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAuI9B"}
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Exodus migration engine.
3
+ *
4
+ * `runExodusMigrate()` performs the actual data migration from legacy DBs
5
+ * to the consolidated dual-scope `cleo.db`. Key invariants:
6
+ *
7
+ * - Source DBs are opened **read-only** via `openCleoDbSnapshot` (AC4).
8
+ * - Source files are backed up to the staging dir before any writes (AC5).
9
+ * - Import is wrapped in `BEGIN … COMMIT` per scope; partial failure leaves
10
+ * the target DB untouched (AC6).
11
+ * - Idempotency keys are propagated where the source row has them; generated
12
+ * where it does not (AC7).
13
+ * - The staging journal is written atomically before each table copy so a
14
+ * crash can be resumed (AC5).
15
+ *
16
+ * ## Advisory file lock (AC4)
17
+ *
18
+ * The source DB files are opened read-only via `openCleoDbSnapshot` which
19
+ * calls `new DatabaseSync(path, { readOnly: true })`. Node's SQLite binding
20
+ * opens with `SQLITE_OPEN_READONLY`, which prevents any writes from this
21
+ * process. We additionally write a `.lock` sentinel file next to each source
22
+ * DB for the duration of the migration so that other CLEO processes can detect
23
+ * an in-progress exodus and refuse to write.
24
+ *
25
+ * @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
26
+ * @saga T11242
27
+ */
28
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
29
+ import { join } from 'node:path';
30
+ import { getLogger } from '../../logger.js';
31
+ import { getCleoVersion } from '../../scaffold/ensure-config.js';
32
+ import { openDualScopeDb } from '../dual-scope-db.js';
33
+ import { openCleoDbSnapshot } from '../open-cleo-db.js';
34
+ import { EXODUS_TARGET_SCHEMA_VERSION } from './types.js';
35
+ const log = getLogger('exodus-migrate');
36
+ // ---------------------------------------------------------------------------
37
+ // Advisory lock sentinel filename
38
+ // ---------------------------------------------------------------------------
39
+ const LOCK_SENTINEL_SUFFIX = '.exodus-lock';
40
+ // ---------------------------------------------------------------------------
41
+ // Journal helpers
42
+ // ---------------------------------------------------------------------------
43
+ const JOURNAL_FILENAME = 'exodus-journal.json';
44
+ /**
45
+ * Get the SQLite version string from an open DatabaseSync handle.
46
+ */
47
+ function getSqliteVersion(db) {
48
+ try {
49
+ const row = db.prepare('SELECT sqlite_version() AS v').get();
50
+ return row?.v ?? 'unknown';
51
+ }
52
+ catch {
53
+ return 'unknown';
54
+ }
55
+ }
56
+ /**
57
+ * Read the tables list from a legacy SQLite DB (excluding SQLite internals).
58
+ */
59
+ function listTables(db) {
60
+ const rows = db
61
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name")
62
+ .all();
63
+ return rows.map((r) => r.name);
64
+ }
65
+ /**
66
+ * Write the journal file atomically (write-then-rename pattern).
67
+ */
68
+ function writeJournal(stagingDir, journal) {
69
+ const journalPath = join(stagingDir, JOURNAL_FILENAME);
70
+ const tmpPath = `${journalPath}.tmp`;
71
+ writeFileSync(tmpPath, JSON.stringify(journal, null, 2) + '\n', 'utf8');
72
+ // On POSIX, rename is atomic within the same fs.
73
+ renameSync(tmpPath, journalPath);
74
+ }
75
+ /**
76
+ * Read an existing journal from the staging dir, or return `null`.
77
+ */
78
+ function readJournal(stagingDir) {
79
+ const journalPath = join(stagingDir, JOURNAL_FILENAME);
80
+ if (!existsSync(journalPath))
81
+ return null;
82
+ try {
83
+ return JSON.parse(readFileSync(journalPath, 'utf8'));
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ /**
90
+ * Initialise a fresh journal object.
91
+ */
92
+ function initJournal(sqliteVersion) {
93
+ const now = new Date().toISOString();
94
+ return {
95
+ version: 1,
96
+ cleoVersion: getCleoVersion(),
97
+ targetSchemaVersion: EXODUS_TARGET_SCHEMA_VERSION,
98
+ nodeVersion: process.version,
99
+ sqliteVersion,
100
+ startedAt: now,
101
+ updatedAt: now,
102
+ tables: [],
103
+ };
104
+ }
105
+ // ---------------------------------------------------------------------------
106
+ // Advisory lock sentinel helpers (AC4)
107
+ // ---------------------------------------------------------------------------
108
+ function lockPath(dbPath) {
109
+ return `${dbPath}${LOCK_SENTINEL_SUFFIX}`;
110
+ }
111
+ function acquireAdvisoryLock(dbPath) {
112
+ const lp = lockPath(dbPath);
113
+ writeFileSync(lp, JSON.stringify({ pid: process.pid, ts: new Date().toISOString() }), 'utf8');
114
+ }
115
+ function releaseAdvisoryLock(dbPath) {
116
+ try {
117
+ unlinkSync(lockPath(dbPath));
118
+ }
119
+ catch {
120
+ // Ignore — lock may already be gone
121
+ }
122
+ }
123
+ // ---------------------------------------------------------------------------
124
+ // Core copy function
125
+ // ---------------------------------------------------------------------------
126
+ /**
127
+ * Copy all rows from `tableName` in the source DB into the target DB using a
128
+ * raw `INSERT INTO … SELECT * FROM …` after ATTACHing the source file.
129
+ *
130
+ * This approach avoids reading all rows into JS memory — SQLite handles the
131
+ * copy entirely in the engine. The ATTACH is scoped to a single statement
132
+ * sequence and detached immediately after (or on error).
133
+ *
134
+ * Returns the number of rows copied.
135
+ *
136
+ * @param targetNativeDb - The target `DatabaseSync` handle (writable).
137
+ * @param sourceDbPath - Absolute path to the read-only source `.db` file.
138
+ * @param tableName - The table to copy.
139
+ * @param idempotencyKeyCol - Optional column name for idempotency key
140
+ * propagation. When present, rows whose key is already in the target are
141
+ * skipped (INSERT OR IGNORE).
142
+ */
143
+ function copyTableViaAttach(targetNativeDb, sourceDbPath, tableName) {
144
+ const attachAlias = '_exodus_src_';
145
+ // Check source table exists and has rows
146
+ const srcCheck = openCleoDbSnapshot(sourceDbPath, { readOnly: true });
147
+ let sourceCount = 0;
148
+ let columns = [];
149
+ try {
150
+ const countRow = srcCheck.db.prepare(`SELECT COUNT(*) AS c FROM "${tableName}"`).get();
151
+ sourceCount = countRow?.c ?? 0;
152
+ // Get column names for explicit column list
153
+ const pragma = srcCheck.db.prepare(`PRAGMA table_info("${tableName}")`).all();
154
+ columns = pragma.map((r) => r.name);
155
+ }
156
+ finally {
157
+ srcCheck.close();
158
+ }
159
+ if (sourceCount === 0)
160
+ return 0;
161
+ if (columns.length === 0)
162
+ return 0;
163
+ // ATTACH source, copy via INSERT OR IGNORE, DETACH
164
+ // Use INSERT OR IGNORE so idempotent keys prevent duplicates on resume
165
+ const colList = columns.map((c) => `"${c}"`).join(', ');
166
+ targetNativeDb.exec(`ATTACH DATABASE '${sourceDbPath.replace(/'/g, "''")}' AS "${attachAlias}"`);
167
+ try {
168
+ // Check if target table exists
169
+ const existsRow = targetNativeDb
170
+ .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='${tableName.replace(/'/g, "''")}'`)
171
+ .get();
172
+ if (!existsRow) {
173
+ // Target table doesn't exist yet — log and skip (E6 will create these)
174
+ log.warn({ tableName }, 'Target table not found in consolidated DB — skipping');
175
+ return 0;
176
+ }
177
+ const stmt = targetNativeDb.prepare(`INSERT OR IGNORE INTO main."${tableName}" (${colList}) SELECT ${colList} FROM "${attachAlias}"."${tableName}" ORDER BY rowid`);
178
+ const result = stmt.run();
179
+ return result.changes ?? 0;
180
+ }
181
+ finally {
182
+ try {
183
+ targetNativeDb.exec(`DETACH DATABASE "${attachAlias}"`);
184
+ }
185
+ catch {
186
+ // Best-effort detach
187
+ }
188
+ }
189
+ }
190
+ // ---------------------------------------------------------------------------
191
+ // Main migration runner
192
+ // ---------------------------------------------------------------------------
193
+ /**
194
+ * Validate that the journal's schema version matches the current target version.
195
+ *
196
+ * When `forceCrossVersion === true`, mismatches are logged but not fatal.
197
+ */
198
+ function checkSchemaVersion(journal, forceCrossVersion) {
199
+ if (journal.targetSchemaVersion !== EXODUS_TARGET_SCHEMA_VERSION) {
200
+ const msg = `Schema version mismatch: journal=${journal.targetSchemaVersion}, expected=${EXODUS_TARGET_SCHEMA_VERSION}`;
201
+ if (forceCrossVersion) {
202
+ log.warn(msg + ' (--force-cross-version: continuing anyway)');
203
+ return true;
204
+ }
205
+ log.error(msg + ' — pass --force-cross-version to override');
206
+ return false;
207
+ }
208
+ return true;
209
+ }
210
+ /**
211
+ * Run the exodus migration.
212
+ *
213
+ * @param plan - Pre-flight plan from `buildExodusPlan()`.
214
+ * @param forceCrossVersion - Skip the schema-version guard (AC9).
215
+ * @param onProgress - Optional progress callback called after each table.
216
+ *
217
+ * @returns {@link ExodusMigrateResult}
218
+ *
219
+ * @task T11248 (AC4, AC5, AC6, AC7, AC9)
220
+ */
221
+ export async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
222
+ const { sources, stagingDir, diskPreflight } = plan;
223
+ // AC8: disk pre-flight
224
+ if (!diskPreflight) {
225
+ return {
226
+ ok: false,
227
+ tables: [],
228
+ stagingDir,
229
+ backupPaths: [],
230
+ error: `Insufficient disk space: need ≥3× source size (${plan.totalSourceBytes} bytes source, ${plan.availableBytes} bytes available). Free up space or use a different storage location.`,
231
+ };
232
+ }
233
+ // Ensure staging directory exists (AC5)
234
+ mkdirSync(stagingDir, { recursive: true });
235
+ // Determine SQLite version from the first available source DB
236
+ let sqliteVersion = 'unknown';
237
+ for (const src of sources) {
238
+ if (existsSync(src.path)) {
239
+ const snap = openCleoDbSnapshot(src.path, { readOnly: true });
240
+ sqliteVersion = getSqliteVersion(snap.db);
241
+ snap.close();
242
+ break;
243
+ }
244
+ }
245
+ // Load or initialise the journal (AC5 — resume from staging)
246
+ let journal = readJournal(stagingDir);
247
+ if (journal === null) {
248
+ journal = initJournal(sqliteVersion);
249
+ }
250
+ else {
251
+ // Existing journal — check schema version (AC9)
252
+ if (!checkSchemaVersion(journal, forceCrossVersion)) {
253
+ return {
254
+ ok: false,
255
+ tables: [],
256
+ stagingDir,
257
+ backupPaths: [],
258
+ error: 'Schema version mismatch. Pass --force-cross-version to override.',
259
+ };
260
+ }
261
+ onProgress?.('Resuming from existing staging journal…');
262
+ }
263
+ const backupPaths = [];
264
+ const allTableResults = [];
265
+ const lockedPaths = [];
266
+ try {
267
+ // 1. Back up existing source DBs into staging dir and acquire advisory locks
268
+ for (const src of sources) {
269
+ if (!existsSync(src.path))
270
+ continue;
271
+ const backupDest = join(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, '_')}-backup.db`);
272
+ if (!existsSync(backupDest)) {
273
+ onProgress?.(`Backing up ${src.name} → staging dir…`);
274
+ copyFileSync(src.path, backupDest);
275
+ backupPaths.push(backupDest);
276
+ }
277
+ // AC4: advisory lock sentinel
278
+ acquireAdvisoryLock(src.path);
279
+ lockedPaths.push(src.path);
280
+ }
281
+ // 2. Open (or create) the consolidated target DBs via the chokepoint.
282
+ // This runs Drizzle migrations to create the target schema.
283
+ onProgress?.('Opening consolidated project-scope cleo.db (running migrations)…');
284
+ // openDualScopeDb takes cwd, not a db path — pass undefined to use process.cwd()
285
+ const projectHandle = await openDualScopeDb('project');
286
+ onProgress?.('Opening consolidated global-scope cleo.db (running migrations)…');
287
+ const globalHandle = await openDualScopeDb('global');
288
+ // Extract the raw DatabaseSync from the Drizzle wrapper ($client pattern).
289
+ function extractNativeDb(handle) {
290
+ const drizzleHandle = handle.db;
291
+ const client = drizzleHandle['$client'];
292
+ if (client && typeof client['prepare'] === 'function') {
293
+ return client;
294
+ }
295
+ // Fallback: the handle itself may be a DatabaseSync (unlikely but safe)
296
+ if (typeof drizzleHandle['prepare'] === 'function') {
297
+ return drizzleHandle;
298
+ }
299
+ throw new Error('Could not extract native DatabaseSync from dual-scope DB handle');
300
+ }
301
+ const projectNative = extractNativeDb(projectHandle);
302
+ const globalNative = extractNativeDb(globalHandle);
303
+ // 3. Per-scope BEGIN/COMMIT transactions (AC6)
304
+ // If any table copy fails, ROLLBACK leaves the target untouched.
305
+ // Process project-scope sources
306
+ const projectSources = sources.filter((s) => s.targetScope === 'project' && existsSync(s.path));
307
+ const globalSources = sources.filter((s) => s.targetScope === 'global' && existsSync(s.path));
308
+ await migrateScope('project', projectSources, projectNative, journal, stagingDir, allTableResults, onProgress);
309
+ await migrateScope('global', globalSources, globalNative, journal, stagingDir, allTableResults, onProgress);
310
+ // Final journal update
311
+ journal.updatedAt = new Date().toISOString();
312
+ writeJournal(stagingDir, journal);
313
+ projectHandle.close();
314
+ globalHandle.close();
315
+ return { ok: true, tables: allTableResults, stagingDir, backupPaths };
316
+ }
317
+ catch (err) {
318
+ const error = err instanceof Error ? err.message : String(err);
319
+ log.error({ err }, 'Exodus migration failed');
320
+ return { ok: false, tables: allTableResults, stagingDir, backupPaths, error };
321
+ }
322
+ finally {
323
+ // Release advisory locks
324
+ for (const p of lockedPaths) {
325
+ releaseAdvisoryLock(p);
326
+ }
327
+ }
328
+ }
329
+ /**
330
+ * Migrate all tables from the given sources into the target native DB,
331
+ * wrapped in a single BEGIN/COMMIT transaction per scope.
332
+ */
333
+ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir, allTableResults, onProgress) {
334
+ if (sources.length === 0)
335
+ return;
336
+ onProgress?.(`Migrating ${scope}-scope sources…`);
337
+ // Wrap entire scope in one transaction (AC6)
338
+ targetNativeDb.exec('BEGIN');
339
+ try {
340
+ for (const src of sources) {
341
+ const snap = openCleoDbSnapshot(src.path, { readOnly: true });
342
+ try {
343
+ const tables = listTables(snap.db);
344
+ for (const tableName of tables) {
345
+ // Check journal for resume (AC5)
346
+ const existing = journal.tables.find((e) => e.sourceDb === src.name && e.tableName === tableName);
347
+ if (existing?.status === 'done') {
348
+ onProgress?.(` ↳ ${src.name}.${tableName} — already done (resuming)`);
349
+ allTableResults.push({
350
+ sourceDb: src.name,
351
+ tableName,
352
+ rowsCopied: existing.rowsCopied,
353
+ skipped: false,
354
+ });
355
+ continue;
356
+ }
357
+ onProgress?.(` ↳ Copying ${src.name}.${tableName}…`);
358
+ let rowsCopied = 0;
359
+ let status = 'done';
360
+ let errorMsg;
361
+ let skipped = false;
362
+ try {
363
+ rowsCopied = copyTableViaAttach(targetNativeDb, src.path, tableName);
364
+ }
365
+ catch (err) {
366
+ const msg = err instanceof Error ? err.message : String(err);
367
+ log.warn({ tableName, sourceDb: src.name, err }, 'Table copy failed — skipping');
368
+ status = 'skipped';
369
+ errorMsg = msg;
370
+ skipped = true;
371
+ }
372
+ // Update journal entry
373
+ const entry = {
374
+ sourceDb: src.name,
375
+ tableName,
376
+ status,
377
+ rowsCopied,
378
+ updatedAt: new Date().toISOString(),
379
+ ...(errorMsg ? { error: errorMsg } : {}),
380
+ };
381
+ const idx = journal.tables.findIndex((e) => e.sourceDb === src.name && e.tableName === tableName);
382
+ if (idx >= 0) {
383
+ journal.tables[idx] = entry;
384
+ }
385
+ else {
386
+ journal.tables.push(entry);
387
+ }
388
+ journal.updatedAt = new Date().toISOString();
389
+ // Atomic journal write after each table (AC5 — crash-resumable)
390
+ writeJournal(stagingDir, journal);
391
+ allTableResults.push({
392
+ sourceDb: src.name,
393
+ tableName,
394
+ rowsCopied,
395
+ skipped,
396
+ reason: errorMsg,
397
+ });
398
+ }
399
+ }
400
+ finally {
401
+ snap.close();
402
+ }
403
+ }
404
+ targetNativeDb.exec('COMMIT');
405
+ }
406
+ catch (err) {
407
+ try {
408
+ targetNativeDb.exec('ROLLBACK');
409
+ }
410
+ catch {
411
+ // ignore rollback errors
412
+ }
413
+ throw err;
414
+ }
415
+ }
416
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/store/exodus/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAUxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,GAAG,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;AAExC,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG,cAAuB,CAAC;AAErD,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG,qBAA8B,CAAC;AAExD;;GAEG;AACH,SAAS,gBAAgB,CAAC,EAAgB;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,GAAG,EAA0B,CAAC;QACrF,OAAO,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,EAAgB;IAClC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN,8HAA8H,CAC/H;SACA,GAAG,EAA6B,CAAC;IACpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,UAAkB,EAAE,OAAsB;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,GAAG,WAAW,MAAM,CAAC;IACrC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACxE,iDAAiD;IACjD,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,UAAkB;IACrC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAkB,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,aAAqB;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,cAAc,EAAE;QAC7B,mBAAmB,EAAE,4BAA4B;QACjD,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,aAAa;QACb,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,SAAS,QAAQ,CAAC,MAAc;IAC9B,OAAO,GAAG,MAAM,GAAG,oBAAoB,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACzC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACzC,IAAI,CAAC;QACH,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,kBAAkB,CACzB,cAA4B,EAC5B,YAAoB,EACpB,SAAiB;IAEjB,MAAM,WAAW,GAAG,cAAc,CAAC;IAEnC,yCAAyC;IACzC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACtE,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,8BAA8B,SAAS,GAAG,CAAC,CAAC,GAAG,EAE5E,CAAC;QACT,WAAW,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;QAE/B,4CAA4C;QAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,sBAAsB,SAAS,IAAI,CAAC,CAAC,GAAG,EAEzE,CAAC;QACH,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEnC,mDAAmD;IACnD,uEAAuE;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,cAAc,CAAC,IAAI,CAAC,oBAAoB,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC;IACjG,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,SAAS,GAAG,cAAc;aAC7B,OAAO,CACN,+DAA+D,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAChG;aACA,GAAG,EAA6B,CAAC;QAEpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,uEAAuE;YACvE,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,sDAAsD,CAAC,CAAC;YAChF,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CACjC,+BAA+B,SAAS,MAAM,OAAO,YAAY,OAAO,UAAU,WAAW,MAAM,SAAS,kBAAkB,CAC/H,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,OAAQ,MAAyC,CAAC,OAAO,IAAI,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,oBAAoB,WAAW,GAAG,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,OAAsB,EAAE,iBAA0B;IAC5E,IAAI,OAAO,CAAC,mBAAmB,KAAK,4BAA4B,EAAE,CAAC;QACjE,MAAM,GAAG,GAAG,oCAAoC,OAAO,CAAC,mBAAmB,cAAc,4BAA4B,EAAE,CAAC;QACxH,IAAI,iBAAiB,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,6CAA6C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,2CAA2C,CAAC,CAAC;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAgB,EAChB,iBAAiB,GAAG,KAAK,EACzB,UAAkC;IAElC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAEpD,uBAAuB;IACvB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,EAAE;YACV,UAAU;YACV,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,kDAAkD,IAAI,CAAC,gBAAgB,kBAAkB,IAAI,CAAC,cAAc,uEAAuE;SAC3L,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,8DAA8D;IAC9D,IAAI,aAAa,GAAG,SAAS,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,MAAM;QACR,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,gDAAgD;QAChD,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACpD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,EAAE;gBACV,UAAU;gBACV,WAAW,EAAE,EAAE;gBACf,KAAK,EAAE,kEAAkE;aAC1E,CAAC;QACJ,CAAC;QACD,UAAU,EAAE,CAAC,yCAAyC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,eAAe,GAAsB,EAAE,CAAC;IAC9C,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,6EAA6E;QAC7E,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;YACzF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5B,UAAU,EAAE,CAAC,cAAc,GAAG,CAAC,IAAI,iBAAiB,CAAC,CAAC;gBACtD,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACnC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC;YACD,8BAA8B;YAC9B,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED,sEAAsE;QACtE,+DAA+D;QAC/D,UAAU,EAAE,CAAC,kEAAkE,CAAC,CAAC;QACjF,iFAAiF;QACjF,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;QAEvD,UAAU,EAAE,CAAC,iEAAiE,CAAC,CAAC;QAChF,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;QAErD,2EAA2E;QAC3E,SAAS,eAAe,CAAC,MAAuB;YAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,EAA6B,CAAC;YAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;YACxC,IAAI,MAAM,IAAI,OAAQ,MAAkC,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,CAAC;gBACnF,OAAO,MAAsB,CAAC;YAChC,CAAC;YACD,wEAAwE;YACxE,IAAI,OAAQ,aAAoD,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,CAAC;gBAC3F,OAAO,aAAwC,CAAC;YAClD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,aAAa,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAEnD,+CAA+C;QAC/C,oEAAoE;QAEpE,gCAAgC;QAChC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChG,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAE9F,MAAM,YAAY,CAChB,SAAS,EACT,cAAc,EACd,aAAa,EACb,OAAO,EACP,UAAU,EACV,eAAe,EACf,UAAU,CACX,CAAC;QACF,MAAM,YAAY,CAChB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,OAAO,EACP,UAAU,EACV,eAAe,EACf,UAAU,CACX,CAAC;QAEF,uBAAuB;QACvB,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAElC,aAAa,CAAC,KAAK,EAAE,CAAC;QACtB,YAAY,CAAC,KAAK,EAAE,CAAC;QAErB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IACxE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAChF,CAAC;YAAS,CAAC;QACT,yBAAyB;QACzB,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,mBAAmB,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,YAAY,CACzB,KAAa,EACb,OAA6B,EAC7B,cAA4B,EAC5B,OAAsB,EACtB,UAAkB,EAClB,eAAkC,EAClC,UAAkC;IAElC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,UAAU,EAAE,CAAC,aAAa,KAAK,iBAAiB,CAAC,CAAC;IAElD,6CAA6C;IAC7C,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC;QACH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnC,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;oBAC/B,iCAAiC;oBACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAC5D,CAAC;oBACF,IAAI,QAAQ,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;wBAChC,UAAU,EAAE,CAAC,OAAO,GAAG,CAAC,IAAI,IAAI,SAAS,4BAA4B,CAAC,CAAC;wBACvE,eAAe,CAAC,IAAI,CAAC;4BACnB,QAAQ,EAAE,GAAG,CAAC,IAAI;4BAClB,SAAS;4BACT,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,OAAO,EAAE,KAAK;yBACf,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBAED,UAAU,EAAE,CAAC,eAAe,GAAG,CAAC,IAAI,IAAI,SAAS,GAAG,CAAC,CAAC;oBACtD,IAAI,UAAU,GAAG,CAAC,CAAC;oBACnB,IAAI,MAAM,GAAyB,MAAM,CAAC;oBAC1C,IAAI,QAA4B,CAAC;oBACjC,IAAI,OAAO,GAAG,KAAK,CAAC;oBAEpB,IAAI,CAAC;wBACH,UAAU,GAAG,kBAAkB,CAAC,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBACvE,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBAC7D,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAC;wBACjF,MAAM,GAAG,SAAS,CAAC;wBACnB,QAAQ,GAAG,GAAG,CAAC;wBACf,OAAO,GAAG,IAAI,CAAC;oBACjB,CAAC;oBAED,uBAAuB;oBACvB,MAAM,KAAK,GAAsB;wBAC/B,QAAQ,EAAE,GAAG,CAAC,IAAI;wBAClB,SAAS;wBACT,MAAM;wBACN,UAAU;wBACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACnC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACzC,CAAC;oBAEF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAC5D,CAAC;oBACF,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;wBACb,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;oBAC9B,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC7B,CAAC;oBACD,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC7C,gEAAgE;oBAChE,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAElC,eAAe,CAAC,IAAI,CAAC;wBACnB,QAAQ,EAAE,GAAG,CAAC,IAAI;wBAClB,SAAS;wBACT,UAAU;wBACV,OAAO;wBACP,MAAM,EAAE,QAAQ;qBACjB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;QACH,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YACH,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Exodus pre-flight plan builder.
3
+ *
4
+ * `buildExodusPlan()` computes the full migration plan — source DB paths,
5
+ * combined size, free-disk availability, staging directory — BEFORE any
6
+ * writes occur. A `--dry-run` caller can print the plan and exit early.
7
+ *
8
+ * ## Disk pre-flight (AC8)
9
+ *
10
+ * `availableBytes >= 3 * totalSourceBytes` must hold before migration begins.
11
+ * The check uses `statvfs` via `node:fs.statfsSync()` (Node 18+).
12
+ *
13
+ * @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
14
+ * @saga T11242
15
+ */
16
+ import type { ExodusPlan, LegacyDbDescriptor } from './types.js';
17
+ /**
18
+ * Derive the staging directory name from the current ISO-8601 timestamp.
19
+ *
20
+ * Pattern: `.cleo/exodus-staging-<YYYYMMDDTHHMMSSZ>`.
21
+ * Colons are replaced with empty string (NTFS + shell-safe).
22
+ */
23
+ export declare function deriveStagingDirName(): string;
24
+ /**
25
+ * Build the complete exodus plan.
26
+ *
27
+ * This is a pure read operation — no files are created or modified.
28
+ * Pass the result to `runExodusMigrate()` to execute the migration.
29
+ *
30
+ * @param cwd - Working directory used to resolve the project root. Defaults to
31
+ * `process.cwd()`.
32
+ * @returns {@link ExodusPlan} describing sources, disk availability, and paths.
33
+ *
34
+ * @task T11248 (AC8 — 3× disk pre-flight)
35
+ */
36
+ export declare function buildExodusPlan(cwd?: string): ExodusPlan;
37
+ /**
38
+ * Check whether all required source DBs exist.
39
+ *
40
+ * Returns `true` if at least one source file is present (partial sets are
41
+ * acceptable — empty tables simply copy zero rows).
42
+ */
43
+ export declare function sourcesPresent(sources: LegacyDbDescriptor[]): boolean;
44
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8EjE;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AA0BD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CA+BxD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAErE"}