mirror of
https://github.com/zadam/trilium.git
synced 2026-02-07 22:34:24 +01:00
Merge 07f273fda40b138c0262d8c1aea172948af62855 into fe02871e9120be7253972c2f8d940bbbb1542ebd
This commit is contained in:
commit
56e07cc9cb
@ -1,10 +1,15 @@
|
||||
{
|
||||
"name": "build-docs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"description": "Build documentation from Trilium notes",
|
||||
"main": "src/main.ts",
|
||||
"bin": {
|
||||
"trilium-build-docs": "dist/cli.js"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "tsx ."
|
||||
"start": "tsx .",
|
||||
"cli": "tsx src/cli.ts",
|
||||
"build": "tsx scripts/build.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Elian Doran <contact@eliandoran.me>",
|
||||
@ -14,6 +19,7 @@
|
||||
"@redocly/cli": "2.15.1",
|
||||
"archiver": "7.0.1",
|
||||
"fs-extra": "11.3.3",
|
||||
"js-yaml": "4.1.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"typedoc": "0.28.16",
|
||||
|
||||
23
apps/build-docs/scripts/build.ts
Normal file
23
apps/build-docs/scripts/build.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import BuildHelper from "../../../scripts/build-utils";
|
||||
|
||||
const build = new BuildHelper("apps/build-docs");
|
||||
|
||||
async function main() {
|
||||
// Build the CLI and other TypeScript files
|
||||
await build.buildBackend([
|
||||
"src/cli.ts",
|
||||
"src/main.ts",
|
||||
"src/build-docs.ts",
|
||||
"src/swagger.ts",
|
||||
"src/script-api.ts",
|
||||
"src/context.ts"
|
||||
]);
|
||||
|
||||
// Copy HTML template
|
||||
build.copy("src/index.html", "index.html");
|
||||
|
||||
// Copy node modules dependencies if needed
|
||||
build.copyNodeModules([ "better-sqlite3", "bindings", "file-uri-to-path" ]);
|
||||
}
|
||||
|
||||
main();
|
||||
@ -13,8 +13,12 @@
|
||||
* Make sure to keep in line with backend's `script_context.ts`.
|
||||
*/
|
||||
|
||||
export type { default as AbstractBeccaEntity } from "../../server/src/becca/entities/abstract_becca_entity.js";
|
||||
export type { default as BAttachment } from "../../server/src/becca/entities/battachment.js";
|
||||
export type {
|
||||
default as AbstractBeccaEntity
|
||||
} from "../../server/src/becca/entities/abstract_becca_entity.js";
|
||||
export type {
|
||||
default as BAttachment
|
||||
} from "../../server/src/becca/entities/battachment.js";
|
||||
export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js";
|
||||
export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js";
|
||||
export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js";
|
||||
@ -31,6 +35,7 @@ export type { Api };
|
||||
const fakeNote = new BNote();
|
||||
|
||||
/**
|
||||
* The `api` global variable allows access to the backend script API, which is documented in {@link Api}.
|
||||
* The `api` global variable allows access to the backend script API,
|
||||
* which is documented in {@link Api}.
|
||||
*/
|
||||
export const api: Api = new BackendScriptApi(fakeNote, {});
|
||||
|
||||
@ -1,19 +1,90 @@
|
||||
process.env.TRILIUM_INTEGRATION_TEST = "memory-no-store";
|
||||
process.env.TRILIUM_RESOURCE_DIR = "../server/src";
|
||||
// Only set TRILIUM_RESOURCE_DIR if not already set (e.g., by Nix wrapper)
|
||||
if (!process.env.TRILIUM_RESOURCE_DIR) {
|
||||
process.env.TRILIUM_RESOURCE_DIR = "../server/src";
|
||||
}
|
||||
process.env.NODE_ENV = "development";
|
||||
|
||||
import cls from "@triliumnext/server/src/services/cls.js";
|
||||
import { dirname, join, resolve } from "path";
|
||||
import archiver from "archiver";
|
||||
import { execSync } from "child_process";
|
||||
import { WriteStream } from "fs";
|
||||
import * as fs from "fs/promises";
|
||||
import * as fsExtra from "fs-extra";
|
||||
import archiver from "archiver";
|
||||
import { WriteStream } from "fs";
|
||||
import { execSync } from "child_process";
|
||||
import yaml from "js-yaml";
|
||||
import { dirname, join, resolve } from "path";
|
||||
|
||||
import BuildContext from "./context.js";
|
||||
|
||||
interface NoteMapping {
|
||||
rootNoteId: string;
|
||||
path: string;
|
||||
format: "markdown" | "html" | "share";
|
||||
ignoredFiles?: string[];
|
||||
exportOnly?: boolean;
|
||||
}
|
||||
|
||||
interface Config {
|
||||
baseUrl: string;
|
||||
noteMappings: NoteMapping[];
|
||||
}
|
||||
|
||||
const DOCS_ROOT = "../../../docs";
|
||||
const OUTPUT_DIR = "../../site";
|
||||
|
||||
// Load configuration from edit-docs-config.yaml
|
||||
async function loadConfig(configPath?: string): Promise<Config | null> {
|
||||
const pathsToTry = configPath
|
||||
? [resolve(configPath)]
|
||||
: [
|
||||
join(process.cwd(), "edit-docs-config.yaml"),
|
||||
join(__dirname, "../../../edit-docs-config.yaml")
|
||||
];
|
||||
|
||||
for (const path of pathsToTry) {
|
||||
try {
|
||||
const configContent = await fs.readFile(path, "utf-8");
|
||||
const config = yaml.load(configContent) as Config;
|
||||
|
||||
// Resolve all paths relative to the config file's directory
|
||||
const CONFIG_DIR = dirname(path);
|
||||
config.noteMappings = config.noteMappings.map((mapping) => ({
|
||||
...mapping,
|
||||
path: resolve(CONFIG_DIR, mapping.path)
|
||||
}));
|
||||
|
||||
return config;
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") {
|
||||
throw error; // rethrow unexpected errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null; // No config file found
|
||||
}
|
||||
|
||||
async function exportDocs(
|
||||
noteId: string,
|
||||
format: "markdown" | "html" | "share",
|
||||
outputPath: string,
|
||||
ignoredFiles?: string[]
|
||||
) {
|
||||
const zipFilePath = `output-${noteId}.zip`;
|
||||
try {
|
||||
const { exportToZipFile } = (await import("@triliumnext/server/src/services/export/zip.js"))
|
||||
.default;
|
||||
await exportToZipFile(noteId, format, zipFilePath, {});
|
||||
|
||||
const ignoredSet = ignoredFiles ? new Set(ignoredFiles) : undefined;
|
||||
await extractZip(zipFilePath, outputPath, ignoredSet);
|
||||
} finally {
|
||||
if (await fsExtra.exists(zipFilePath)) {
|
||||
await fsExtra.rm(zipFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function importAndExportDocs(sourcePath: string, outputSubDir: string) {
|
||||
const note = await importData(sourcePath);
|
||||
|
||||
@ -21,15 +92,18 @@ async function importAndExportDocs(sourcePath: string, outputSubDir: string) {
|
||||
const zipName = outputSubDir || "user-guide";
|
||||
const zipFilePath = `output-${zipName}.zip`;
|
||||
try {
|
||||
const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js")).default;
|
||||
const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js"))
|
||||
.default;
|
||||
const branch = note.getParentBranches()[0];
|
||||
const taskContext = new (await import("@triliumnext/server/src/services/task_context.js")).default(
|
||||
"no-progress-reporting",
|
||||
"export",
|
||||
null
|
||||
);
|
||||
const taskContext = new (await import("@triliumnext/server/src/services/task_context.js"))
|
||||
.default(
|
||||
"no-progress-reporting",
|
||||
"export",
|
||||
null
|
||||
);
|
||||
const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
|
||||
await exportToZip(taskContext, branch, "share", fileOutputStream);
|
||||
const { waitForStreamToFinish } = await import("@triliumnext/server/src/services/utils.js");
|
||||
await waitForStreamToFinish(fileOutputStream);
|
||||
|
||||
// Output to root directory if outputSubDir is empty, otherwise to subdirectory
|
||||
@ -42,7 +116,7 @@ async function importAndExportDocs(sourcePath: string, outputSubDir: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function buildDocsInner() {
|
||||
async function buildDocsInner(config?: Config) {
|
||||
const i18n = await import("@triliumnext/server/src/services/i18n.js");
|
||||
await i18n.initializeTranslations();
|
||||
|
||||
@ -53,18 +127,49 @@ async function buildDocsInner() {
|
||||
const beccaLoader = await import("../../server/src/becca/becca_loader.js");
|
||||
await beccaLoader.beccaLoaded;
|
||||
|
||||
// Build User Guide
|
||||
console.log("Building User Guide...");
|
||||
await importAndExportDocs(join(__dirname, DOCS_ROOT, "User Guide"), "user-guide");
|
||||
if (config) {
|
||||
// Config-based build (reads from edit-docs-config.yaml)
|
||||
console.log("Building documentation from config file...");
|
||||
|
||||
// Build Developer Guide
|
||||
console.log("Building Developer Guide...");
|
||||
await importAndExportDocs(join(__dirname, DOCS_ROOT, "Developer Guide"), "developer-guide");
|
||||
// Import all non-export-only mappings
|
||||
for (const mapping of config.noteMappings) {
|
||||
if (!mapping.exportOnly) {
|
||||
console.log(`Importing from ${mapping.path}...`);
|
||||
await importData(mapping.path);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy favicon.
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "user-guide", "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "developer-guide", "favicon.ico"));
|
||||
// Export all mappings
|
||||
for (const mapping of config.noteMappings) {
|
||||
if (mapping.exportOnly) {
|
||||
console.log(`Exporting ${mapping.format} to ${mapping.path}...`);
|
||||
await exportDocs(
|
||||
mapping.rootNoteId,
|
||||
mapping.format,
|
||||
mapping.path,
|
||||
mapping.ignoredFiles
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Legacy hardcoded build (for backward compatibility)
|
||||
console.log("Building User Guide...");
|
||||
await importAndExportDocs(join(__dirname, DOCS_ROOT, "User Guide"), "user-guide");
|
||||
|
||||
console.log("Building Developer Guide...");
|
||||
await importAndExportDocs(
|
||||
join(__dirname, DOCS_ROOT, "Developer Guide"),
|
||||
"developer-guide"
|
||||
);
|
||||
|
||||
// Copy favicon.
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico",
|
||||
join(OUTPUT_DIR, "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico",
|
||||
join(OUTPUT_DIR, "user-guide", "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico",
|
||||
join(OUTPUT_DIR, "developer-guide", "favicon.ico"));
|
||||
}
|
||||
|
||||
console.log("Documentation built successfully!");
|
||||
}
|
||||
@ -91,12 +196,13 @@ async function createImportZip(path: string) {
|
||||
zlib: { level: 0 }
|
||||
});
|
||||
|
||||
console.log("Archive path is ", resolve(path))
|
||||
console.log("Archive path is ", resolve(path));
|
||||
archive.directory(path, "/");
|
||||
|
||||
const outputStream = fsExtra.createWriteStream(inputFile);
|
||||
archive.pipe(outputStream);
|
||||
archive.finalize();
|
||||
const { waitForStreamToFinish } = await import("@triliumnext/server/src/services/utils.js");
|
||||
await waitForStreamToFinish(outputStream);
|
||||
|
||||
try {
|
||||
@ -106,15 +212,15 @@ async function createImportZip(path: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function waitForStreamToFinish(stream: WriteStream) {
|
||||
return new Promise<void>((res, rej) => {
|
||||
stream.on("finish", () => res());
|
||||
stream.on("error", (err) => rej(err));
|
||||
});
|
||||
}
|
||||
|
||||
export async function extractZip(zipFilePath: string, outputPath: string, ignoredFiles?: Set<string>) {
|
||||
const { readZipFile, readContent } = (await import("@triliumnext/server/src/services/import/zip.js"));
|
||||
export async function extractZip(
|
||||
zipFilePath: string,
|
||||
outputPath: string,
|
||||
ignoredFiles?: Set<string>
|
||||
) {
|
||||
const { readZipFile, readContent } = (await import(
|
||||
"@triliumnext/server/src/services/import/zip.js"
|
||||
));
|
||||
await readZipFile(await fs.readFile(zipFilePath), async (zip, entry) => {
|
||||
// We ignore directories since they can appear out of order anyway.
|
||||
if (!entry.fileName.endsWith("/") && !ignoredFiles?.has(entry.fileName)) {
|
||||
@ -129,6 +235,27 @@ export async function extractZip(zipFilePath: string, outputPath: string, ignore
|
||||
});
|
||||
}
|
||||
|
||||
export async function buildDocsFromConfig(configPath?: string, gitRootDir?: string) {
|
||||
const config = await loadConfig(configPath);
|
||||
|
||||
if (gitRootDir) {
|
||||
// Build the share theme if we have a gitRootDir (for Trilium project)
|
||||
execSync(`pnpm run --filter share-theme build`, {
|
||||
stdio: "inherit",
|
||||
cwd: gitRootDir
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger the actual build.
|
||||
await new Promise((res, rej) => {
|
||||
cls.init(() => {
|
||||
buildDocsInner(config ?? undefined)
|
||||
.catch(rej)
|
||||
.then(res);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export default async function buildDocs({ gitRootDir }: BuildContext) {
|
||||
// Build the share theme.
|
||||
execSync(`pnpm run --filter share-theme build`, {
|
||||
|
||||
89
apps/build-docs/src/cli.ts
Normal file
89
apps/build-docs/src/cli.ts
Normal file
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import packageJson from "../package.json" with { type: "json" };
|
||||
import { buildDocsFromConfig } from "./build-docs.js";
|
||||
|
||||
// Parse command-line arguments
|
||||
function parseArgs() {
|
||||
const args = process.argv.slice(2);
|
||||
let configPath: string | undefined;
|
||||
let showHelp = false;
|
||||
let showVersion = false;
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === "--config" || args[i] === "-c") {
|
||||
configPath = args[i + 1];
|
||||
if (!configPath) {
|
||||
console.error("Error: --config/-c requires a path argument");
|
||||
process.exit(1);
|
||||
}
|
||||
i++; // Skip the next argument as it's the value
|
||||
} else if (args[i] === "--help" || args[i] === "-h") {
|
||||
showHelp = true;
|
||||
} else if (args[i] === "--version" || args[i] === "-v") {
|
||||
showVersion = true;
|
||||
}
|
||||
}
|
||||
|
||||
return { configPath, showHelp, showVersion };
|
||||
}
|
||||
|
||||
function getVersion(): string {
|
||||
return packageJson.version;
|
||||
}
|
||||
|
||||
function printHelp() {
|
||||
const version = getVersion();
|
||||
console.log(`
|
||||
Usage: trilium-build-docs [options]
|
||||
|
||||
Options:
|
||||
-c, --config <path> Path to the configuration file
|
||||
(default: edit-docs-config.yaml in current directory)
|
||||
-h, --help Display this help message
|
||||
-v, --version Display version information
|
||||
|
||||
Description:
|
||||
Builds documentation from Trilium note structure and exports to various formats.
|
||||
Configuration file should be in YAML format with the following structure:
|
||||
|
||||
baseUrl: "https://example.com"
|
||||
noteMappings:
|
||||
- rootNoteId: "noteId123"
|
||||
path: "docs"
|
||||
format: "markdown"
|
||||
- rootNoteId: "noteId456"
|
||||
path: "public/docs"
|
||||
format: "share"
|
||||
exportOnly: true
|
||||
|
||||
Version: ${version}
|
||||
`);
|
||||
}
|
||||
|
||||
function printVersion() {
|
||||
const version = getVersion();
|
||||
console.log(version);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { configPath, showHelp, showVersion } = parseArgs();
|
||||
|
||||
if (showHelp) {
|
||||
printHelp();
|
||||
process.exit(0);
|
||||
} else if (showVersion) {
|
||||
printVersion();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
await buildDocsFromConfig(configPath);
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error("Error building documentation:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@ -13,16 +13,19 @@
|
||||
* Make sure to keep in line with frontend's `script_context.ts`.
|
||||
*/
|
||||
|
||||
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
|
||||
export type { default as FAttachment } from "../../client/src/entities/fattachment.js";
|
||||
export type { default as FAttribute } from "../../client/src/entities/fattribute.js";
|
||||
export type { default as FBranch } from "../../client/src/entities/fbranch.js";
|
||||
export type { default as FNote } from "../../client/src/entities/fnote.js";
|
||||
export type { Api } from "../../client/src/services/frontend_script_api.js";
|
||||
export type { default as NoteContextAwareWidget } from "../../client/src/widgets/note_context_aware_widget.js";
|
||||
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
|
||||
export type {
|
||||
default as NoteContextAwareWidget
|
||||
} from "../../client/src/widgets/note_context_aware_widget.js";
|
||||
export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js";
|
||||
|
||||
import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js";
|
||||
|
||||
//@ts-expect-error
|
||||
|
||||
// @ts-expect-error - FrontendScriptApi is not directly exportable as Api without this simulation.
|
||||
export const api: Api = new FrontendScriptApi();
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { join } from "path";
|
||||
import BuildContext from "./context";
|
||||
import buildSwagger from "./swagger";
|
||||
import { cpSync, existsSync, mkdirSync, rmSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import buildDocs from "./build-docs";
|
||||
import BuildContext from "./context";
|
||||
import buildScriptApi from "./script-api";
|
||||
import buildSwagger from "./swagger";
|
||||
|
||||
const context: BuildContext = {
|
||||
gitRootDir: join(__dirname, "../../../"),
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { execSync } from "child_process";
|
||||
import BuildContext from "./context";
|
||||
import { join } from "path";
|
||||
|
||||
import BuildContext from "./context";
|
||||
|
||||
export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) {
|
||||
// Generate types
|
||||
execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir });
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import BuildContext from "./context";
|
||||
import { join } from "path";
|
||||
import { execSync } from "child_process";
|
||||
import { mkdirSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import BuildContext from "./context";
|
||||
|
||||
interface BuildInfo {
|
||||
specPath: string;
|
||||
@ -27,6 +28,9 @@ export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) {
|
||||
const absSpecPath = join(gitRootDir, specPath);
|
||||
const targetDir = join(baseDir, outDir);
|
||||
mkdirSync(targetDir, { recursive: true });
|
||||
execSync(`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, { stdio: "inherit" });
|
||||
execSync(
|
||||
`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"include": [],
|
||||
"include": [
|
||||
"scripts/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../server"
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"entryPoints": [
|
||||
"src/backend_script_entrypoint.ts"
|
||||
],
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"plugin": [
|
||||
"typedoc-plugin-missing-exports"
|
||||
]
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"entryPoints": [
|
||||
"src/frontend_script_entrypoint.ts"
|
||||
],
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"plugin": [
|
||||
"typedoc-plugin-missing-exports"
|
||||
]
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import dateUtils from "../date_utils.js";
|
||||
import path from "path";
|
||||
import packageInfo from "../../../package.json" with { type: "json" };
|
||||
import { getContentDisposition } from "../utils.js";
|
||||
import { getContentDisposition, waitForStreamToFinish } from "../utils.js";
|
||||
import protectedSessionService from "../protected_session.js";
|
||||
import sanitize from "sanitize-filename";
|
||||
import fs from "fs";
|
||||
@ -468,6 +468,7 @@ async function exportToZip(taskContext: TaskContext<"export">, branch: BBranch,
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
|
||||
async function exportToZipFile(noteId: string, format: ExportFormat, zipFilePath: string, zipExportOptions?: AdvancedExportOptions) {
|
||||
const fileOutputStream = fs.createWriteStream(zipFilePath);
|
||||
const taskContext = new TaskContext("no-progress-reporting", "export", null);
|
||||
@ -479,6 +480,7 @@ async function exportToZipFile(noteId: string, format: ExportFormat, zipFilePath
|
||||
}
|
||||
|
||||
await exportToZip(taskContext, note.getParentBranches()[0], format, fileOutputStream, false, zipExportOptions);
|
||||
await waitForStreamToFinish(fileOutputStream);
|
||||
|
||||
log.info(`Exported '${noteId}' with format '${format}' to '${zipFilePath}'`);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
|
||||
|
||||
import chardet from "chardet";
|
||||
import crypto from "crypto";
|
||||
import escape from "escape-html";
|
||||
@ -516,6 +515,13 @@ function slugify(text: string) {
|
||||
.replace(/(^-|-$)+/g, ""); // trim dashes
|
||||
}
|
||||
|
||||
export function waitForStreamToFinish(stream: any): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on("finish", () => resolve());
|
||||
stream.on("error", (err) => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
compareVersions,
|
||||
constantTimeCompare,
|
||||
@ -556,5 +562,6 @@ export default {
|
||||
toBase64,
|
||||
toMap,
|
||||
toObject,
|
||||
unescapeHtml
|
||||
unescapeHtml,
|
||||
waitForStreamToFinish
|
||||
};
|
||||
|
||||
42
flake.nix
42
flake.nix
@ -113,7 +113,7 @@
|
||||
[
|
||||
moreutils # sponge
|
||||
nodejs.python
|
||||
removeReferencesTo
|
||||
removeReferencesTo
|
||||
]
|
||||
++ lib.optionals (app == "desktop" || app == "edit-docs") [
|
||||
copyDesktopItems
|
||||
@ -126,7 +126,7 @@
|
||||
which
|
||||
electron
|
||||
]
|
||||
++ lib.optionals (app == "server") [
|
||||
++ lib.optionals (app == "server" || app == "build-docs") [
|
||||
makeBinaryWrapper
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
@ -153,7 +153,7 @@
|
||||
|
||||
# This file is a symlink into /build which is not allowed.
|
||||
postFixup = ''
|
||||
rm $out/opt/trilium*/node_modules/better-sqlite3/node_modules/.bin/prebuild-install || true
|
||||
find $out/opt -name prebuild-install -path "*/better-sqlite3/node_modules/.bin/*" -delete || true
|
||||
'';
|
||||
|
||||
components = [
|
||||
@ -169,6 +169,7 @@
|
||||
"packages/highlightjs"
|
||||
"packages/turndown-plugin-gfm"
|
||||
|
||||
"apps/build-docs"
|
||||
"apps/client"
|
||||
"apps/db-compare"
|
||||
"apps/desktop"
|
||||
@ -277,11 +278,46 @@
|
||||
'';
|
||||
};
|
||||
|
||||
build-docs = makeApp {
|
||||
app = "build-docs";
|
||||
preBuildCommands = ''
|
||||
pushd apps/server
|
||||
pnpm rebuild || true
|
||||
popd
|
||||
'';
|
||||
buildTask = "client:build && pnpm run server:build && pnpm run --filter build-docs build";
|
||||
mainProgram = "trilium-build-docs";
|
||||
installCommands = ''
|
||||
mkdir -p $out/{bin,opt/trilium-build-docs}
|
||||
|
||||
# Copy build-docs dist
|
||||
cp --archive apps/build-docs/dist/* $out/opt/trilium-build-docs
|
||||
|
||||
# Copy server dist (needed for runtime)
|
||||
mkdir -p $out/opt/trilium-build-docs/server
|
||||
cp --archive apps/server/dist/* $out/opt/trilium-build-docs/server/
|
||||
|
||||
# Copy client dist (needed for runtime)
|
||||
mkdir -p $out/opt/trilium-build-docs/client
|
||||
cp --archive apps/client/dist/* $out/opt/trilium-build-docs/client/
|
||||
|
||||
# Copy share-theme (needed for exports)
|
||||
mkdir -p $out/opt/trilium-build-docs/packages/share-theme
|
||||
cp --archive packages/share-theme/dist/* $out/opt/trilium-build-docs/packages/share-theme/
|
||||
|
||||
# Create wrapper script
|
||||
makeWrapper ${lib.getExe nodejs} $out/bin/trilium-build-docs \
|
||||
--add-flags $out/opt/trilium-build-docs/cli.cjs \
|
||||
--set TRILIUM_RESOURCE_DIR $out/opt/trilium-build-docs/server
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
packages.desktop = desktop;
|
||||
packages.server = server;
|
||||
packages.edit-docs = edit-docs;
|
||||
packages.build-docs = build-docs;
|
||||
|
||||
packages.default = desktop;
|
||||
|
||||
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@ -164,6 +164,9 @@ importers:
|
||||
fs-extra:
|
||||
specifier: 11.3.3
|
||||
version: 11.3.3
|
||||
js-yaml:
|
||||
specifier: 4.1.1
|
||||
version: 4.1.1
|
||||
react:
|
||||
specifier: 19.2.4
|
||||
version: 19.2.4
|
||||
@ -16525,8 +16528,6 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-ui': 47.4.0
|
||||
'@ckeditor/ckeditor5-utils': 47.4.0
|
||||
ckeditor5: 47.4.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-markdown-gfm@47.4.0':
|
||||
dependencies:
|
||||
@ -16937,6 +16938,7 @@ snapshots:
|
||||
ckeditor5: 47.4.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@ckeditor/ckeditor5-utils@47.4.0':
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user