"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var ApiService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiService = exports.render = void 0;
const common_1 = require("@nestjs/common");
const lodash_1 = require("lodash");
const node_fs_1 = require("node:fs");
const config_repository_1 = require("../repositories/config.repository");
const logging_repository_1 = require("../repositories/logging.repository");
const auth_service_1 = require("./auth.service");
const shared_link_service_1 = require("./shared-link.service");
const render = (index, meta) => {
    const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) => item ? (0, lodash_1.escape)(item) : '');
    const tags = `
    <meta name="description" content="${description}" />

    <!-- Facebook Meta Tags -->
    <meta property="og:type" content="website" />
    <meta property="og:title" content="${title}" />
    <meta property="og:description" content="${description}" />
    ${imageUrl ? `<meta property="og:image" content="${imageUrl}" />` : ''}

    <!-- Twitter Meta Tags -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="${title}" />
    <meta name="twitter:description" content="${description}" />

    ${imageUrl ? `<meta name="twitter:image" content="${imageUrl}" />` : ''}`;
    return index.replace('<!-- metadata:tags -->', tags);
};
exports.render = render;
let ApiService = ApiService_1 = class ApiService {
    authService;
    sharedLinkService;
    configRepository;
    logger;
    constructor(authService, sharedLinkService, configRepository, logger) {
        this.authService = authService;
        this.sharedLinkService = sharedLinkService;
        this.configRepository = configRepository;
        this.logger = logger;
        this.logger.setContext(ApiService_1.name);
    }
    ssr(excludePaths) {
        const { resourcePaths } = this.configRepository.getEnv();
        let index = '';
        try {
            index = (0, node_fs_1.readFileSync)(resourcePaths.web.indexHtml).toString();
        }
        catch {
            this.logger.warn(`Unable to open ${resourcePaths.web.indexHtml}, skipping SSR.`);
        }
        return async (request, res, next) => {
            const method = request.method.toLowerCase();
            if (request.url.startsWith('/api') ||
                (method !== 'get' && method !== 'head') ||
                excludePaths.some((item) => request.url.startsWith(item))) {
                return next();
            }
            const responseType = request.accepts('text/html');
            if (!responseType) {
                throw new common_1.NotAcceptableException(`The route ${request.path} was requested as ${request.header('accept')}, but only returns text/html`);
            }
            let status = 200;
            let html = index;
            const defaultDomain = request.host ? `${request.protocol}://${request.host}` : undefined;
            let meta = null;
            const shareKey = request.url.match(/^\/share\/(.+)$/);
            if (shareKey) {
                try {
                    const key = shareKey[1];
                    const auth = await this.authService.validateSharedLinkKey(key);
                    meta = await this.sharedLinkService.getMetadataTags(auth, defaultDomain);
                }
                catch {
                    status = 404;
                }
            }
            const shareSlug = request.url.match(/^\/s\/(.+)$/);
            if (shareSlug) {
                try {
                    const slug = shareSlug[1];
                    const auth = await this.authService.validateSharedLinkSlug(slug);
                    meta = await this.sharedLinkService.getMetadataTags(auth, defaultDomain);
                }
                catch {
                    status = 404;
                }
            }
            if (meta) {
                html = (0, exports.render)(index, meta);
            }
            res.status(status).type(responseType).header('Cache-Control', 'no-store').send(html);
        };
    }
};
exports.ApiService = ApiService;
exports.ApiService = ApiService = ApiService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [auth_service_1.AuthService,
        shared_link_service_1.SharedLinkService,
        config_repository_1.ConfigRepository,
        logging_repository_1.LoggingRepository])
], ApiService);
//# sourceMappingURL=api.service.js.map