Skip to content

Commit ec0f1f7

Browse files
fix: prevent sqlite reimport over legacy vault (#731)
1 parent 12ea523 commit ec0f1f7

File tree

5 files changed

+75
-26
lines changed

5 files changed

+75
-26
lines changed

src/main/index.ts

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable node/prefer-global/process */
2-
import { readFileSync } from 'node:fs'
32
import { readFile } from 'node:fs/promises'
43
import { createRequire } from 'node:module'
54
import path from 'node:path'
@@ -145,29 +144,10 @@ else {
145144
= (store.preferences.get('storage.vaultPath') as string | null)
146145
|| path.join(storagePath, 'markdown-vault')
147146
ensureFlatSpacesLayout(vaultPath)
148-
const statePath = path.join(
149-
vaultPath,
150-
'code',
151-
'.masscode',
152-
'state.json',
153-
)
154-
let vaultHasData = false
155-
156-
try {
157-
const stateContent = readFileSync(statePath, 'utf8')
158-
const state = JSON.parse(stateContent) as {
159-
folders?: unknown[]
160-
snippets?: unknown[]
161-
tags?: unknown[]
162-
}
163-
164-
vaultHasData = [state.folders, state.snippets, state.tags].some(
165-
collection => Array.isArray(collection) && collection.length > 0,
166-
)
167-
}
168-
catch {
169-
// state.json doesn't exist or is invalid; treat the vault as empty
170-
}
147+
const { hasMarkdownVaultData } = lazyRequire(
148+
'./storage/providers/markdown',
149+
) as typeof import('./storage/providers/markdown')
150+
const vaultHasData = hasMarkdownVaultData(vaultPath)
171151

172152
if (!vaultHasData) {
173153
const { closeDB } = lazyRequire('./db') as typeof import('./db')
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
export { migrateSqliteToMarkdownStorage } from './migrations'
2-
export { getMarkdownStorageErrorMessage, resetRuntimeCache } from './runtime'
2+
export {
3+
getMarkdownStorageErrorMessage,
4+
hasMarkdownVaultData,
5+
resetRuntimeCache,
6+
} from './runtime'
37
export { createMarkdownStorageProvider } from './storages'
48
export { startMarkdownWatcher, stopMarkdownWatcher } from './watcher'

src/main/storage/providers/markdown/runtime/__tests__/paths.test.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import os from 'node:os'
22
import path from 'node:path'
33
import fs from 'fs-extra'
44
import { afterEach, describe, expect, it, vi } from 'vitest'
5-
import { getPaths } from '../paths'
5+
import { getPaths, hasMarkdownVaultData } from '../paths'
66

77
vi.mock('electron-store', () => {
88
class MockStore {
@@ -80,6 +80,45 @@ afterEach(() => {
8080
})
8181

8282
describe('getPaths', () => {
83+
it('detects existing data in legacy root vault layout', () => {
84+
const vaultPath = createTempDir()
85+
86+
fs.ensureDirSync(path.join(vaultPath, '.masscode'))
87+
fs.writeJSONSync(path.join(vaultPath, '.masscode', 'state.json'), {
88+
counters: {
89+
contentId: 0,
90+
folderId: 1,
91+
snippetId: 1,
92+
tagId: 0,
93+
},
94+
folders: [
95+
{
96+
id: 1,
97+
name: 'Legacy',
98+
orderIndex: 0,
99+
parentId: null,
100+
},
101+
],
102+
snippets: [
103+
{
104+
filePath: 'Legacy/file.md',
105+
id: 1,
106+
},
107+
],
108+
tags: [],
109+
version: 2,
110+
})
111+
fs.ensureDirSync(path.join(vaultPath, 'Legacy'))
112+
fs.writeFileSync(path.join(vaultPath, 'Legacy', 'file.md'), '# Legacy')
113+
114+
expect(hasMarkdownVaultData(vaultPath)).toBe(true)
115+
expect(
116+
fs.pathExistsSync(
117+
path.join(vaultPath, 'code', '.masscode', 'state.json'),
118+
),
119+
).toBe(true)
120+
})
121+
83122
it('migrates legacy code vault root into code', () => {
84123
const vaultPath = createTempDir()
85124

src/main/storage/providers/markdown/runtime/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export {
3333
getNextFolderOrder,
3434
getPaths,
3535
getVaultPath,
36+
hasMarkdownVaultData,
3637
normalizeDirectoryPath,
3738
} from './paths'
3839

src/main/storage/providers/markdown/runtime/paths.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ interface LegacyStateFolderLike {
4141
parentId: number | null
4242
}
4343

44+
interface MarkdownStateCollectionsLike {
45+
folders?: unknown[]
46+
snippets?: unknown[]
47+
tags?: unknown[]
48+
}
49+
4450
function toTopLevelEntry(relativePath: string): string | null {
4551
const normalized = relativePath
4652
.replaceAll('\\', '/')
@@ -233,6 +239,25 @@ export function getPaths(vaultPath: string): Paths {
233239
}
234240
}
235241

242+
export function hasMarkdownVaultData(vaultPath: string): boolean {
243+
const { statePath } = getPaths(vaultPath)
244+
245+
if (!fs.pathExistsSync(statePath)) {
246+
return false
247+
}
248+
249+
try {
250+
const state = fs.readJSONSync(statePath) as MarkdownStateCollectionsLike
251+
252+
return [state.folders, state.snippets, state.tags].some(
253+
collection => Array.isArray(collection) && collection.length > 0,
254+
)
255+
}
256+
catch {
257+
return false
258+
}
259+
}
260+
236261
export {
237262
depthOfRelativePath,
238263
normalizeDirectoryPath,

0 commit comments

Comments
 (0)