diff --git a/src/main/engine/MetaEngine.ts b/src/main/engine/MetaEngine.ts index 9ec4b7f..21e953e 100644 --- a/src/main/engine/MetaEngine.ts +++ b/src/main/engine/MetaEngine.ts @@ -255,7 +255,8 @@ export class MetaEngine extends EventEmitter { try { await this.ensureMetaDirExists(); const filePath = this.getProjectMetadataFilePath(); - const content = JSON.stringify(this.projectMetadata, null, 2); + const { dataPath: _dataPath, ...persistedMetadata } = this.projectMetadata || {}; + const content = JSON.stringify(persistedMetadata, null, 2); await fs.writeFile(filePath, content, 'utf-8'); } catch (error) { console.error('[MetaEngine] Failed to save project metadata:', error); @@ -439,22 +440,11 @@ export class MetaEngine extends EventEmitter { // Handle project metadata if (projectMetadataFileExists) { await this.loadProjectMetadata(); - - // Keep dataPath authoritative in database (selected folder path on create/open). - // If project.json has a stale dataPath, update project.json from database. - const projectData = await this.fetchProjectFromDatabase(); - if (!projectData) { - throw new Error(`Project not found in database: ${this.currentProjectId}`); - } - - const databaseDataPath = projectData.dataPath || undefined; - if (this.projectMetadata && this.projectMetadata.dataPath !== databaseDataPath) { - this.projectMetadata = { - ...this.projectMetadata, - dataPath: databaseDataPath, - }; + if (this.projectMetadata?.dataPath !== undefined) { + const { dataPath: _dataPath, ...metadataWithoutDataPath } = this.projectMetadata; + this.projectMetadata = metadataWithoutDataPath; await this.saveProjectMetadata(); - console.log(`[MetaEngine] Synced dataPath from database to project.json: ${databaseDataPath || '(default)'}`); + console.log('[MetaEngine] Removed deprecated dataPath from project.json'); } } else { // No file exists, fetch project data from database and create file @@ -465,7 +455,6 @@ export class MetaEngine extends EventEmitter { this.projectMetadata = { name: projectData.name, description: projectData.description || undefined, - dataPath: projectData.dataPath || undefined, maxPostsPerPage: DEFAULT_MAX_POSTS_PER_PAGE, }; await this.saveProjectMetadata(); diff --git a/src/main/engine/PreviewServer.ts b/src/main/engine/PreviewServer.ts index 59e45ae..03c7c19 100644 --- a/src/main/engine/PreviewServer.ts +++ b/src/main/engine/PreviewServer.ts @@ -284,9 +284,9 @@ function buildCanonicalPostPath(post: PostData): string { return `/${year}/${month}/${day}/${post.slug}`; } -function getPageHtml(content: string, title: string): string { +function getPageHtml(content: string, title: string, language: string): string { return ` - +
@@ -452,7 +452,8 @@ export class PreviewServer { return; } - this.respond(res, 200, getPageHtml(result, resolvePageTitle(metadata, context.projectName, context.projectDescription))); + const language = metadata?.mainLanguage?.trim() || 'en'; + this.respond(res, 200, getPageHtml(result, resolvePageTitle(metadata, context.projectName, context.projectDescription), language)); } catch (error) { console.error('[PreviewServer] Request failed:', error); this.respond(res, 500, 'Internal Server Error'); diff --git a/tests/engine/MetaEngine.test.ts b/tests/engine/MetaEngine.test.ts index 28653c5..417e4de 100644 --- a/tests/engine/MetaEngine.test.ts +++ b/tests/engine/MetaEngine.test.ts @@ -472,6 +472,20 @@ describe('MetaEngine', () => { expect(parsed.description).toBe('Test description'); }); + it('should not persist dataPath to filesystem project metadata', async () => { + await metaEngine.setProjectMetadata({ + name: 'Test Project', + dataPath: '/custom/project/path', + }); + + const metaDir = metaEngine.getMetaDir(); + const projectPath = normalizePath(`${metaDir}/project.json`); + const content = mockFiles.get(projectPath); + const parsed = JSON.parse(content!); + + expect(parsed.dataPath).toBeUndefined(); + }); + it('should load project metadata from filesystem', async () => { const metaDir = metaEngine.getMetaDir(); const projectPath = normalizePath(`${metaDir}/project.json`); @@ -757,7 +771,7 @@ describe('MetaEngine', () => { expect(normalizePath(metaDir)).toContain(normalizePath(customDataDir)); }); - it('should sync dataPath from database to project.json if different', async () => { + it('should ignore and remove dataPath from project.json during syncOnStartup', async () => { const metaDir = metaEngine.getMetaDir(); const oldPath = path.join('old', 'path', 'from', 'file'); const newPath = path.join('new', 'path', 'from', 'database'); @@ -783,7 +797,7 @@ describe('MetaEngine', () => { const savedProjectJson = mockFiles.get(normalizePath(`${metaDir}/project.json`)); expect(savedProjectJson).toBeDefined(); const parsed = JSON.parse(savedProjectJson!); - expect(normalizePath(parsed.dataPath)).toBe(normalizePath(newPath)); + expect(parsed.dataPath).toBeUndefined(); expect(mockLocalDb.update).not.toHaveBeenCalled(); }); }); diff --git a/tests/engine/PreviewServer.test.ts b/tests/engine/PreviewServer.test.ts index 4c138cc..f65097f 100644 --- a/tests/engine/PreviewServer.test.ts +++ b/tests/engine/PreviewServer.test.ts @@ -14,7 +14,7 @@ type PostEngineLike = { }; type SettingsEngineLike = { - getProjectMetadata: () => Promise<{ maxPostsPerPage?: number } | null>; + getProjectMetadata: () => Promise<{ maxPostsPerPage?: number; mainLanguage?: string } | null>; setProjectContext: (projectId: string, dataDir?: string) => void; }; @@ -335,6 +335,30 @@ describe('PreviewServer', () => { expect(html).not.toContain('