mirror of
https://github.com/zadam/trilium.git
synced 2026-01-17 12:04:24 +01:00
Build edit-docs as standalone package using makeApp
Changed edit-docs from a simple wrapper script to a properly built Nix package using makeApp, similar to how desktop and server are built. Changes: - Added build script to apps/edit-docs/package.json - Created apps/edit-docs/scripts/build.ts based on desktop's build script - Added edit-docs:build task to root package.json - Changed flake.nix to use makeApp which: - Builds edit-docs with all dependencies bundled - Creates a standalone trilium-edit-docs executable - Can be installed with 'nix profile install' and run from any directory This makes edit-docs truly reusable - it can now be installed and run from any project without requiring the Trilium source tree.
This commit is contained in:
parent
fb4d63b049
commit
0273c64bbf
11
README.md
11
README.md
@ -165,6 +165,17 @@ pnpm install
|
||||
pnpm edit-docs:edit-docs
|
||||
```
|
||||
|
||||
Alternatively, if you have Nix installed:
|
||||
```shell
|
||||
# Run directly
|
||||
nix run .#edit-docs
|
||||
|
||||
# Or install to your profile
|
||||
nix profile install .#edit-docs
|
||||
trilium-edit-docs
|
||||
```
|
||||
|
||||
|
||||
### Building the Executable
|
||||
Download the repository, install dependencies using `pnpm` and then build the desktop app for Windows:
|
||||
```shell
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
"fs-extra": "11.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsx scripts/build.ts",
|
||||
"test-build": "vitest --config vitest.build.config.mts",
|
||||
"edit-docs": "cross-env TRILIUM_PORT=37741 TRILIUM_DATA_DIR=data TRILIUM_INTEGRATION_TEST=memory-no-store tsx ../../scripts/electron-start.mts src/edit-docs.ts",
|
||||
"edit-demo": "cross-env TRILIUM_PORT=37744 TRILIUM_DATA_DIR=data TRILIUM_INTEGRATION_TEST=memory-no-store DOCS_ROOT=../../../docs USER_GUIDE_ROOT=\"../../server/src/assets/doc_notes/en/User Guide\" tsx ../../scripts/electron-start.mts src/edit-demo.ts"
|
||||
}
|
||||
|
||||
40
apps/edit-docs/scripts/build.ts
Normal file
40
apps/edit-docs/scripts/build.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { writeFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import BuildHelper from "../../../scripts/build-utils";
|
||||
import originalPackageJson from "../package.json" with { type: "json" };
|
||||
|
||||
const build = new BuildHelper("apps/edit-docs");
|
||||
|
||||
async function main() {
|
||||
await build.buildBackend(["src/edit-docs.ts", "src/utils.ts"]);
|
||||
|
||||
// Copy assets from server (needed for DB initialization)
|
||||
build.copy("/apps/server/src/assets", "assets/");
|
||||
build.triggerBuildAndCopyTo("packages/share-theme", "share-theme/assets/");
|
||||
build.copy("/packages/share-theme/src/templates", "share-theme/templates/");
|
||||
build.copy("/node_modules/ckeditor5/dist/ckeditor5-content.css", "ckeditor5-content.css");
|
||||
build.buildFrontend();
|
||||
|
||||
// Copy node modules dependencies
|
||||
build.copyNodeModules(["better-sqlite3", "bindings", "file-uri-to-path", "@electron/remote"]);
|
||||
|
||||
generatePackageJson();
|
||||
}
|
||||
|
||||
function generatePackageJson() {
|
||||
const { version, author, license, description, dependencies, devDependencies } = originalPackageJson;
|
||||
const packageJson = {
|
||||
name: "trilium-edit-docs",
|
||||
main: "edit-docs.cjs",
|
||||
version,
|
||||
author,
|
||||
license,
|
||||
description,
|
||||
dependencies: {"better-sqlite3": dependencies["better-sqlite3"]},
|
||||
devDependencies: {electron: devDependencies.electron},
|
||||
};
|
||||
writeFileSync(join(build.outDir, "package.json"), JSON.stringify(packageJson, null, "\t"), "utf-8");
|
||||
}
|
||||
|
||||
main();
|
||||
48
apps/edit-docs/spec/build-checks/artifacts.spec.ts
Normal file
48
apps/edit-docs/spec/build-checks/artifacts.spec.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { globSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { it, describe, expect } from "vitest";
|
||||
|
||||
describe("Check artifacts are present", () => {
|
||||
const distPath = join(__dirname, "../../dist");
|
||||
|
||||
it("has the necessary node modules", async () => {
|
||||
const paths = [
|
||||
"node_modules/better-sqlite3",
|
||||
"node_modules/bindings",
|
||||
"node_modules/file-uri-to-path",
|
||||
"node_modules/@electron/remote"
|
||||
];
|
||||
|
||||
ensurePathsExist(paths);
|
||||
});
|
||||
|
||||
it("includes the client", async () => {
|
||||
const paths = [
|
||||
"public/assets",
|
||||
"public/fonts",
|
||||
"public/node_modules",
|
||||
"public/src",
|
||||
"public/stylesheets",
|
||||
"public/translations"
|
||||
];
|
||||
|
||||
ensurePathsExist(paths);
|
||||
});
|
||||
|
||||
it("includes necessary assets", async () => {
|
||||
const paths = [
|
||||
"assets",
|
||||
"share-theme",
|
||||
"ckeditor5-content.css"
|
||||
];
|
||||
|
||||
ensurePathsExist(paths);
|
||||
});
|
||||
|
||||
function ensurePathsExist(paths: string[]) {
|
||||
for (const path of paths) {
|
||||
const result = globSync(join(distPath, path, "**"));
|
||||
expect(result, path).not.toHaveLength(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -36,6 +36,10 @@ function parseArgs() {
|
||||
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;
|
||||
@ -86,9 +90,15 @@ let NOTE_MAPPINGS: NoteMapping[];
|
||||
|
||||
// Load configuration from edit-docs-config.yaml
|
||||
async function loadConfig() {
|
||||
const CONFIG_PATH = configPath
|
||||
let CONFIG_PATH = configPath
|
||||
? path.resolve(configPath)
|
||||
: path.join(__dirname, "../../../edit-docs-config.yaml");
|
||||
: path.join(process.cwd(), "edit-docs-config.yaml");
|
||||
|
||||
const exists = await fs.access(CONFIG_PATH).then(() => true).catch(() => false);
|
||||
if (!exists && !configPath) {
|
||||
// Fallback to project root if running from within a subproject
|
||||
CONFIG_PATH = path.join(__dirname, "../../../edit-docs-config.yaml");
|
||||
}
|
||||
|
||||
const configContent = await fs.readFile(CONFIG_PATH, "utf-8");
|
||||
const config = yaml.load(configContent) as Config;
|
||||
@ -106,12 +116,18 @@ async function main() {
|
||||
await loadConfig();
|
||||
const initializedPromise = startElectron(() => {
|
||||
// Wait for the import to be finished and the application to be loaded before we listen to changes.
|
||||
setTimeout(() => registerHandlers(), 10_000);
|
||||
setTimeout(() => {
|
||||
registerHandlers();
|
||||
}, 10_000);
|
||||
});
|
||||
|
||||
await initializeTranslations();
|
||||
await initializeDatabase(true);
|
||||
|
||||
// Wait for becca to be loaded before importing data
|
||||
const beccaLoader = await import("@triliumnext/server/src/becca/becca_loader.js");
|
||||
await beccaLoader.beccaLoaded;
|
||||
|
||||
cls.init(async () => {
|
||||
for (const mapping of NOTE_MAPPINGS) {
|
||||
if (!mapping.exportOnly) {
|
||||
@ -248,7 +264,6 @@ async function registerHandlers() {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Got entity changed", e.entityName, e.entity.title);
|
||||
debouncer();
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,18 +7,21 @@ import type { WriteStream } from "fs";
|
||||
import fs from "fs/promises";
|
||||
import fsExtra from "fs-extra";
|
||||
import path from "path";
|
||||
import { resolve } from "path";
|
||||
|
||||
import { deferred, DeferredPromise } from "../../../packages/commons/src";
|
||||
import { deferred, type DeferredPromise } from "../../../packages/commons/src/index.js";
|
||||
|
||||
export function initializeDatabase(skipDemoDb: boolean) {
|
||||
return new Promise<void>(async (resolve) => {
|
||||
const sqlInit = (await import("@triliumnext/server/src/services/sql_init.js")).default;
|
||||
cls.init(async () => {
|
||||
if (!sqlInit.isDbInitialized()) {
|
||||
await sqlInit.createInitialDatabase(skipDemoDb);
|
||||
}
|
||||
resolve();
|
||||
export function initializeDatabase(skipDemoDb: boolean): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
import("@triliumnext/server/src/services/sql_init.js").then((m) => {
|
||||
const sqlInit = m.default;
|
||||
cls.init(async () => {
|
||||
if (!sqlInit.isDbInitialized()) {
|
||||
sqlInit.createInitialDatabase(skipDemoDb).then(() => resolve());
|
||||
} else {
|
||||
sqlInit.dbReady.resolve();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -78,7 +81,6 @@ async function createImportZip(path: string) {
|
||||
zlib: { level: 0 }
|
||||
});
|
||||
|
||||
console.log("Archive path is ", resolve(path));
|
||||
archive.directory(path, "/");
|
||||
|
||||
const outputStream = fsExtra.createWriteStream(inputFile);
|
||||
@ -93,9 +95,11 @@ async function createImportZip(path: string) {
|
||||
}
|
||||
|
||||
function waitForEnd(archive: Archiver, stream: WriteStream) {
|
||||
return new Promise<void>(async (res, rej) => {
|
||||
stream.on("finish", () => res());
|
||||
await archive.finalize();
|
||||
return new Promise<void>((res, rej) => {
|
||||
stream.on("finish", res);
|
||||
stream.on("error", rej);
|
||||
archive.on("error", rej);
|
||||
archive.finalize().catch(rej);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
17
apps/edit-docs/vitest.build.config.mts
Normal file
17
apps/edit-docs/vitest.build.config.mts
Normal file
@ -0,0 +1,17 @@
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/apps/edit-docs',
|
||||
plugins: [],
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: "node",
|
||||
include: ['spec/build-checks/**'],
|
||||
reporters: [
|
||||
"verbose"
|
||||
]
|
||||
},
|
||||
}));
|
||||
25
flake.nix
25
flake.nix
@ -112,7 +112,7 @@
|
||||
nodejs.python
|
||||
removeReferencesTo
|
||||
]
|
||||
++ lib.optionals (app == "desktop") [
|
||||
++ lib.optionals (app == "desktop" || app == "edit-docs") [
|
||||
copyDesktopItems
|
||||
# required for NIXOS_OZONE_WL expansion
|
||||
# https://github.com/NixOS/nixpkgs/issues/172583
|
||||
@ -252,10 +252,33 @@
|
||||
--add-flags $out/opt/trilium-server/main.cjs
|
||||
'';
|
||||
};
|
||||
|
||||
edit-docs = makeApp {
|
||||
app = "edit-docs";
|
||||
preBuildCommands = ''
|
||||
export npm_config_nodedir=${electron.headers}
|
||||
pnpm postinstall
|
||||
'';
|
||||
buildTask = "edit-docs:build";
|
||||
mainProgram = "trilium-edit-docs";
|
||||
installCommands = ''
|
||||
#remove-references-to -t ${electron.headers} apps/edit-docs/dist/node_modules/better-sqlite3/build/config.gypi
|
||||
#remove-references-to -t ${nodejs.python} apps/edit-docs/dist/node_modules/better-sqlite3/build/config.gypi
|
||||
|
||||
mkdir -p $out/{bin,opt/trilium-edit-docs}
|
||||
cp --archive apps/edit-docs/dist/* $out/opt/trilium-edit-docs
|
||||
makeShellWrapper ${lib.getExe electron} $out/bin/trilium-edit-docs \
|
||||
--set-default ELECTRON_IS_DEV 0 \
|
||||
--set TRILIUM_RESOURCE_DIR $out/opt/trilium-edit-docs \
|
||||
--add-flags $out/opt/trilium-edit-docs/edit-docs.cjs
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
packages.desktop = desktop;
|
||||
packages.server = server;
|
||||
packages.edit-docs = edit-docs;
|
||||
|
||||
packages.default = desktop;
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
"desktop:start": "pnpm run --filter desktop dev",
|
||||
"desktop:build": "pnpm run --filter desktop build",
|
||||
"desktop:start-prod": "pnpm run --filter desktop start-prod",
|
||||
"edit-docs:edit-docs": "pnpm run --filter edit-docs edit-docs",
|
||||
"edit-docs:build": "pnpm run --filter edit-docs build",
|
||||
"website:start": "pnpm run --filter website dev",
|
||||
"website:build": "pnpm run --filter website build",
|
||||
"electron:build": "pnpm desktop:build",
|
||||
@ -28,7 +30,6 @@
|
||||
"chore:update-version": "tsx ./scripts/update-version.ts",
|
||||
"docs:build": "pnpm run --filter build-docs start",
|
||||
"docs:preview": "pnpm http-server site -p 9000",
|
||||
"edit-docs:edit-docs": "pnpm run --filter edit-docs edit-docs",
|
||||
"edit-docs:edit-demo": "pnpm run --filter edit-docs edit-demo",
|
||||
"test:all": "pnpm test:parallel && pnpm test:sequential",
|
||||
"test:parallel": "pnpm --filter=!server --filter=!ckeditor5-mermaid --filter=!ckeditor5-math --parallel test",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user