mirror of
https://github.com/zadam/trilium.git
synced 2026-05-06 16:05:58 +02:00
fix(server): unable to export as share
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { type ExportFormat, type ZipExportProviderData, ZipExportProvider } from "@triliumnext/core";
|
||||
|
||||
export async function standaloneZipExportProviderFactory(format: ExportFormat, data: ZipExportProviderData): Promise<ZipExportProvider> {
|
||||
switch (format) {
|
||||
case "html": {
|
||||
const { default: HtmlExportProvider } = await import("@triliumnext/core/src/services/export/zip/html.js");
|
||||
return new HtmlExportProvider(data);
|
||||
}
|
||||
case "markdown": {
|
||||
const { default: MarkdownExportProvider } = await import("@triliumnext/core/src/services/export/zip/markdown.js");
|
||||
return new MarkdownExportProvider(data);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported export format: '${format}'`);
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,7 @@ async function initialize(): Promise<void> {
|
||||
executionContext: new BrowserExecutionContext(),
|
||||
crypto: new BrowserCryptoProvider(),
|
||||
zip: new BrowserZipProvider(),
|
||||
zipExportProviderFactory: (await import("./lightweight/zip_export_provider_factory.js")).standaloneZipExportProviderFactory,
|
||||
messaging: messagingProvider!,
|
||||
request: new FetchRequestProvider(),
|
||||
platform: new StandalonePlatformProvider(queryString),
|
||||
|
||||
@@ -135,6 +135,7 @@ async function main() {
|
||||
},
|
||||
crypto: new NodejsCryptoProvider(),
|
||||
zip: new NodejsZipProvider(),
|
||||
zipExportProviderFactory: (await import("@triliumnext/server/src/services/export/zip/factory.js")).serverZipExportProviderFactory,
|
||||
request: new NodeRequestProvider(),
|
||||
executionContext: new ClsHookedExecutionContext(),
|
||||
messaging: new WebSocketMessagingProvider(),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { beforeAll } from "vitest";
|
||||
import { readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { initializeCore } from "@triliumnext/core";
|
||||
import { serverZipExportProviderFactory } from "../src/services/export/zip/factory.js";
|
||||
import ClsHookedExecutionContext from "../src/cls_provider.js";
|
||||
import NodejsCryptoProvider from "../src/crypto_provider.js";
|
||||
import NodejsZipProvider from "../src/zip_provider.js";
|
||||
@@ -29,6 +30,7 @@ beforeAll(async () => {
|
||||
},
|
||||
crypto: new NodejsCryptoProvider(),
|
||||
zip: new NodejsZipProvider(),
|
||||
zipExportProviderFactory: serverZipExportProviderFactory,
|
||||
executionContext: new ClsHookedExecutionContext(),
|
||||
schema: readFileSync(require.resolve("@triliumnext/core/src/assets/schema.sql"), "utf-8"),
|
||||
platform: new ServerPlatformProvider(),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* are loaded later and will result in an empty string.
|
||||
*/
|
||||
|
||||
import { getLog,initializeCore, sql_init } from "@triliumnext/core";
|
||||
import { getLog, initializeCore, sql_init } from "@triliumnext/core";
|
||||
import fs from "fs";
|
||||
import { t } from "i18next";
|
||||
import path from "path";
|
||||
@@ -53,6 +53,7 @@ async function startApplication() {
|
||||
},
|
||||
crypto: new NodejsCryptoProvider(),
|
||||
zip: new NodejsZipProvider(),
|
||||
zipExportProviderFactory: (await import("./services/export/zip/factory.js")).serverZipExportProviderFactory,
|
||||
request: new NodeRequestProvider(),
|
||||
executionContext: new ClsHookedExecutionContext(),
|
||||
messaging: new WebSocketMessagingProvider(),
|
||||
|
||||
20
apps/server/src/services/export/zip/factory.ts
Normal file
20
apps/server/src/services/export/zip/factory.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { type ExportFormat, type ZipExportProviderData, ZipExportProvider } from "@triliumnext/core";
|
||||
|
||||
export async function serverZipExportProviderFactory(format: ExportFormat, data: ZipExportProviderData): Promise<ZipExportProvider> {
|
||||
switch (format) {
|
||||
case "html": {
|
||||
const { default: HtmlExportProvider } = await import("@triliumnext/core/src/services/export/zip/html.js");
|
||||
return new HtmlExportProvider(data);
|
||||
}
|
||||
case "markdown": {
|
||||
const { default: MarkdownExportProvider } = await import("@triliumnext/core/src/services/export/zip/markdown.js");
|
||||
return new MarkdownExportProvider(data);
|
||||
}
|
||||
case "share": {
|
||||
const { default: ShareThemeExportProvider } = await import("./share_theme.js");
|
||||
return new ShareThemeExportProvider(data);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported export format: '${format}'`);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { renderSpreadsheetToHtml } from "@triliumnext/commons";
|
||||
import { sanitize } from "@triliumnext/core";
|
||||
import { icon_packs as iconPackService } from "@triliumnext/core";
|
||||
import { icon_packs as iconPackService, sanitize, utils } from "@triliumnext/core";
|
||||
import { highlightAuto } from "@triliumnext/highlightjs";
|
||||
import ejs from "ejs";
|
||||
import escapeHtml from "escape-html";
|
||||
@@ -16,7 +15,7 @@ import BNote from "../becca/entities/bnote.js";
|
||||
import assetPath, { assetUrlFragment } from "../services/asset_path.js";
|
||||
import log from "../services/log.js";
|
||||
import options from "../services/options.js";
|
||||
import utils, { getResourceDir, isDev, safeExtractMessageAndStackFromError } from "../services/utils.js";
|
||||
import { getResourceDir, isDev } from "../services/utils.js";
|
||||
import SAttachment from "./shaca/entities/sattachment.js";
|
||||
import SBranch from "./shaca/entities/sbranch.js";
|
||||
import type SNote from "./shaca/entities/snote.js";
|
||||
@@ -224,7 +223,7 @@ function renderNoteContentInternal(note: SNote | BNote, renderArgs: RenderArgs)
|
||||
return ejs.render(content, opts, { includer });
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
const [errMessage, errStack] = safeExtractMessageAndStackFromError(e);
|
||||
const [errMessage, errStack] = utils.safeExtractMessageAndStackFromError(e);
|
||||
log.error(`Rendering user provided share template (${templateId}) threw exception ${errMessage} with stacktrace: ${errStack}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { initSchema, initDemoArchive } from "./services/sql_init";
|
||||
import appInfo from "./services/app_info";
|
||||
import { type PlatformProvider, initPlatform } from "./services/platform";
|
||||
import { type ZipProvider, initZipProvider } from "./services/zip_provider";
|
||||
import { type ZipExportProviderFactory, initZipExportProviderFactory } from "./services/export/zip_export_provider_factory";
|
||||
import markdown from "./services/import/markdown";
|
||||
|
||||
export { getLog } from "./services/log";
|
||||
@@ -104,8 +105,9 @@ export * as routeHelpers from "./routes/helpers";
|
||||
export { getZipProvider, type ZipArchive, type ZipProvider } from "./services/zip_provider";
|
||||
export { default as zipImportService } from "./services/import/zip";
|
||||
export { default as zipExportService } from "./services/export/zip";
|
||||
export { type AdvancedExportOptions } from "./services/export/zip/abstract_provider";
|
||||
export { type AdvancedExportOptions, type ZipExportProviderData } from "./services/export/zip/abstract_provider";
|
||||
export { ZipExportProvider } from "./services/export/zip/abstract_provider";
|
||||
export { type ZipExportProviderFactory } from "./services/export/zip_export_provider_factory";
|
||||
export { type ExportFormat } from "./meta";
|
||||
|
||||
export * as becca_easy_mocking from "./test/becca_easy_mocking";
|
||||
@@ -113,7 +115,7 @@ export * as becca_mocking from "./test/becca_mocking";
|
||||
|
||||
export { default as markdownImportService } from "./services/import/markdown";
|
||||
|
||||
export async function initializeCore({ dbConfig, executionContext, crypto, zip, translations, messaging, request, schema, extraAppInfo, platform, getDemoArchive }: {
|
||||
export async function initializeCore({ dbConfig, executionContext, crypto, zip, zipExportProviderFactory, translations, messaging, request, schema, extraAppInfo, platform, getDemoArchive }: {
|
||||
dbConfig: SqlServiceParams,
|
||||
executionContext: ExecutionContext,
|
||||
crypto: CryptoProvider,
|
||||
@@ -121,6 +123,7 @@ export async function initializeCore({ dbConfig, executionContext, crypto, zip,
|
||||
translations: TranslationProvider,
|
||||
platform: PlatformProvider,
|
||||
schema: string,
|
||||
zipExportProviderFactory: ZipExportProviderFactory,
|
||||
messaging?: MessagingProvider,
|
||||
request?: RequestProvider,
|
||||
getDemoArchive?: () => Promise<Uint8Array | null>,
|
||||
@@ -134,6 +137,7 @@ export async function initializeCore({ dbConfig, executionContext, crypto, zip,
|
||||
await initTranslations(translations);
|
||||
initCrypto(crypto);
|
||||
initZipProvider(zip);
|
||||
initZipExportProviderFactory(zipExportProviderFactory);
|
||||
initContext(executionContext);
|
||||
initSql(new SqlService(dbConfig, getLog()));
|
||||
initSchema(schema);
|
||||
|
||||
@@ -11,27 +11,22 @@ import protectedSessionService from "../protected_session.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import { getZipProvider } from "../zip_provider.js";
|
||||
import { getContentDisposition } from "../utils/index"
|
||||
import { AdvancedExportOptions, ZipExportProvider, ZipExportProviderData } from "./zip/abstract_provider.js";
|
||||
import HtmlExportProvider from "./zip/html.js";
|
||||
import MarkdownExportProvider from "./zip/markdown.js";
|
||||
import { AdvancedExportOptions, ZipExportProviderData } from "./zip/abstract_provider.js";
|
||||
import { getZipExportProviderFactory } from "./zip_export_provider_factory.js";
|
||||
import { AttachmentMeta, AttributeMeta, ExportFormat, NoteMeta, NoteMetaFile } from "../../meta";
|
||||
import { ValidationError } from "../../errors";
|
||||
import { extname } from "../utils/path";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async function exportToZip(taskContext: TaskContext<"export">, branch: BBranch, format: ExportFormat, res: Record<string, any>, setHeaders = true, zipExportOptions?: AdvancedExportOptions) {
|
||||
if (!["html", "markdown", "share"].includes(format)) {
|
||||
throw new ValidationError(`Only 'html', 'markdown' and 'share' allowed as export format, '${format}' given`);
|
||||
}
|
||||
|
||||
const archive = getZipProvider().createZipArchive();
|
||||
const rewriteFn = (zipExportOptions?.customRewriteLinks ? zipExportOptions?.customRewriteLinks(rewriteLinks, getNoteTargetUrl) : rewriteLinks);
|
||||
const provider = buildProvider();
|
||||
const provider = await buildProvider();
|
||||
const log = getLog();
|
||||
|
||||
const noteIdToMeta: Record<string, NoteMeta> = {};
|
||||
|
||||
function buildProvider(): ZipExportProvider {
|
||||
async function buildProvider() {
|
||||
const providerData: ZipExportProviderData = {
|
||||
getNoteTargetUrl,
|
||||
archive,
|
||||
@@ -40,17 +35,7 @@ async function exportToZip(taskContext: TaskContext<"export">, branch: BBranch,
|
||||
zipExportOptions
|
||||
};
|
||||
|
||||
switch (format) {
|
||||
case "html":
|
||||
return new HtmlExportProvider(providerData);
|
||||
case "markdown":
|
||||
return new MarkdownExportProvider(providerData);
|
||||
case "share":
|
||||
// TODO: Reintroduce share format.
|
||||
// return new ShareThemeExportProvider(providerData);
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
return getZipExportProviderFactory()(format, providerData);
|
||||
}
|
||||
|
||||
function getUniqueFilename(existingFileNames: Record<string, number>, fileName: string) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { ExportFormat } from "../../meta.js";
|
||||
import type { ZipExportProvider, ZipExportProviderData } from "./zip/abstract_provider.js";
|
||||
|
||||
export type ZipExportProviderFactory = (format: ExportFormat, data: ZipExportProviderData) => Promise<ZipExportProvider>;
|
||||
|
||||
let factory: ZipExportProviderFactory | null = null;
|
||||
|
||||
export function initZipExportProviderFactory(f: ZipExportProviderFactory) {
|
||||
factory = f;
|
||||
}
|
||||
|
||||
export function getZipExportProviderFactory(): ZipExportProviderFactory {
|
||||
if (!factory) throw new Error("ZipExportProviderFactory not initialized.");
|
||||
return factory;
|
||||
}
|
||||
Reference in New Issue
Block a user