|
|
@ -7,30 +7,14 @@ import { |
|
|
|
} from '@ghostfolio/common/config'; |
|
|
|
import { DATE_FORMAT, interpolate } from '@ghostfolio/common/helper'; |
|
|
|
|
|
|
|
import { Injectable, Logger, NestMiddleware } from '@nestjs/common'; |
|
|
|
import { format } from 'date-fns'; |
|
|
|
import { NextFunction, Request, Response } from 'express'; |
|
|
|
import * as fs from 'fs'; |
|
|
|
import { join } from 'path'; |
|
|
|
|
|
|
|
const i18nService = new I18nService(); |
|
|
|
|
|
|
|
let indexHtmlMap: { [languageCode: string]: string } = {}; |
|
|
|
|
|
|
|
const title = 'Ghostfolio'; |
|
|
|
|
|
|
|
try { |
|
|
|
indexHtmlMap = SUPPORTED_LANGUAGE_CODES.reduce( |
|
|
|
(map, languageCode) => ({ |
|
|
|
...map, |
|
|
|
[languageCode]: fs.readFileSync( |
|
|
|
join(__dirname, '..', 'client', languageCode, 'index.html'), |
|
|
|
'utf8' |
|
|
|
) |
|
|
|
}), |
|
|
|
{} |
|
|
|
); |
|
|
|
} catch {} |
|
|
|
|
|
|
|
const locales = { |
|
|
|
'/de/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt': { |
|
|
|
featureGraphicPath: 'assets/images/blog/ghostfolio-x-sackgeld.png', |
|
|
@ -94,29 +78,32 @@ const locales = { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const isFileRequest = (filename: string) => { |
|
|
|
if (filename === '/assets/LICENSE') { |
|
|
|
return true; |
|
|
|
} else if ( |
|
|
|
filename.includes('auth/ey') || |
|
|
|
filename.includes( |
|
|
|
'personal-finance-tools/open-source-alternative-to-de.fi' |
|
|
|
) || |
|
|
|
filename.includes( |
|
|
|
'personal-finance-tools/open-source-alternative-to-markets.sh' |
|
|
|
@Injectable() |
|
|
|
export class HtmlTemplateMiddleware implements NestMiddleware { |
|
|
|
private indexHtmlMap: { [languageCode: string]: string } = {}; |
|
|
|
|
|
|
|
public constructor(private readonly i18nService: I18nService) { |
|
|
|
try { |
|
|
|
this.indexHtmlMap = SUPPORTED_LANGUAGE_CODES.reduce( |
|
|
|
(map, languageCode) => ({ |
|
|
|
...map, |
|
|
|
[languageCode]: fs.readFileSync( |
|
|
|
join(__dirname, '..', 'client', languageCode, 'index.html'), |
|
|
|
'utf8' |
|
|
|
) |
|
|
|
) { |
|
|
|
return false; |
|
|
|
}), |
|
|
|
{} |
|
|
|
); |
|
|
|
} catch (error) { |
|
|
|
Logger.error( |
|
|
|
'Failed to initialize index HTML map', |
|
|
|
error, |
|
|
|
'HTMLTemplateMiddleware' |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return filename.split('.').pop() !== filename; |
|
|
|
}; |
|
|
|
|
|
|
|
export const HtmlTemplateMiddleware = async ( |
|
|
|
request: Request, |
|
|
|
response: Response, |
|
|
|
next: NextFunction |
|
|
|
) => { |
|
|
|
public use(request: Request, response: Response, next: NextFunction) { |
|
|
|
const path = request.originalUrl.replace(/\/$/, ''); |
|
|
|
let languageCode = path.substr(1, 2); |
|
|
|
|
|
|
@ -130,30 +117,30 @@ export const HtmlTemplateMiddleware = async ( |
|
|
|
if ( |
|
|
|
path.startsWith('/api/') || |
|
|
|
path.startsWith(STORYBOOK_PATH) || |
|
|
|
isFileRequest(path) || |
|
|
|
this.isFileRequest(path) || |
|
|
|
!environment.production |
|
|
|
) { |
|
|
|
// Skip
|
|
|
|
next(); |
|
|
|
} else { |
|
|
|
const indexHtml = interpolate(indexHtmlMap[languageCode], { |
|
|
|
const indexHtml = interpolate(this.indexHtmlMap[languageCode], { |
|
|
|
currentDate, |
|
|
|
languageCode, |
|
|
|
path, |
|
|
|
rootUrl, |
|
|
|
description: i18nService.getTranslation({ |
|
|
|
description: this.i18nService.getTranslation({ |
|
|
|
languageCode, |
|
|
|
id: 'metaDescription' |
|
|
|
}), |
|
|
|
featureGraphicPath: |
|
|
|
locales[path]?.featureGraphicPath ?? 'assets/cover.png', |
|
|
|
keywords: i18nService.getTranslation({ |
|
|
|
keywords: this.i18nService.getTranslation({ |
|
|
|
languageCode, |
|
|
|
id: 'metaKeywords' |
|
|
|
}), |
|
|
|
title: |
|
|
|
locales[path]?.title ?? |
|
|
|
`${title} – ${i18nService.getTranslation({ |
|
|
|
`${title} – ${this.i18nService.getTranslation({ |
|
|
|
languageCode, |
|
|
|
id: 'slogan' |
|
|
|
})}` |
|
|
@ -161,4 +148,23 @@ export const HtmlTemplateMiddleware = async ( |
|
|
|
|
|
|
|
return response.send(indexHtml); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private isFileRequest(filename: string) { |
|
|
|
if (filename === '/assets/LICENSE') { |
|
|
|
return true; |
|
|
|
} else if ( |
|
|
|
filename.includes('auth/ey') || |
|
|
|
filename.includes( |
|
|
|
'personal-finance-tools/open-source-alternative-to-de.fi' |
|
|
|
) || |
|
|
|
filename.includes( |
|
|
|
'personal-finance-tools/open-source-alternative-to-markets.sh' |
|
|
|
) |
|
|
|
) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return filename.split('.').pop() !== filename; |
|
|
|
} |
|
|
|
} |
|
|
|