feat(standalone): add support for environment variables

This commit is contained in:
Elian Doran
2026-03-26 21:52:58 +02:00
parent c0593707f2
commit a2cace6c0f
9 changed files with 50 additions and 10 deletions

View File

@@ -4,7 +4,7 @@
*/
import { BootstrapDefinition } from '@triliumnext/commons';
import { entity_changes, getContext, getSharedBootstrapItems, getSql, routes, sql_init } from '@triliumnext/core';
import { entity_changes, getContext, getPlatform, getSharedBootstrapItems, getSql, routes, sql_init } from '@triliumnext/core';
import packageJson from '../../package.json' with { type: 'json' };
import { type BrowserRequest, BrowserRouter } from './browser_router';
@@ -255,9 +255,7 @@ function bootstrapRoute(): BootstrapDefinition {
device: false as const, // Let the client detect device type.
appPath: assetPath,
instanceName: "standalone",
// TODO: Fill properly
TRILIUM_SAFE_MODE: false
TRILIUM_SAFE_MODE: !!getPlatform().getEnv("TRILIUM_SAFE_MODE")
};
if (!isDbInitialized) {

View File

@@ -1,6 +1,24 @@
import type { PlatformProvider } from "@triliumnext/core";
/** Maps URL query parameter names to TRILIUM_ environment variable names. */
const QUERY_TO_ENV: Record<string, string> = {
"safeMode": "TRILIUM_SAFE_MODE",
"startNoteId": "TRILIUM_START_NOTE_ID",
};
export default class StandalonePlatformProvider implements PlatformProvider {
private envMap: Record<string, string> = {};
constructor(queryString: string) {
const params = new URLSearchParams(queryString);
for (const [queryKey, envKey] of Object.entries(QUERY_TO_ENV)) {
if (params.has(queryKey)) {
this.envMap[envKey] = params.get(queryKey) || "true";
}
}
}
crash(message: string): void {
console.error("[Standalone] FATAL:", message);
self.postMessage({
@@ -8,4 +26,8 @@ export default class StandalonePlatformProvider implements PlatformProvider {
message
});
}
getEnv(key: string): string | undefined {
return this.envMap[key];
}
}

View File

@@ -9,6 +9,7 @@ function showFatalErrorDialog(message: string) {
export function startLocalServerWorker() {
if (localWorker) return localWorker;
localWorker = new LocalServerWorker();
localWorker.postMessage({ type: "INIT", queryString: location.search });
// Handle worker errors during initialization
localWorker.onerror = (event) => {

View File

@@ -69,6 +69,7 @@ let coreModule: typeof import("@triliumnext/core") | null = null;
let router: BrowserRouter | null = null;
let initPromise: Promise<void> | null = null;
let initError: Error | null = null;
let queryString = "";
/**
* Load all required modules using dynamic imports.
@@ -153,7 +154,7 @@ async function initialize(): Promise<void> {
crypto: new BrowserCryptoProvider(),
messaging: messagingProvider!,
request: new FetchRequestProvider(),
platform: new StandalonePlatformProvider(),
platform: new StandalonePlatformProvider(queryString),
translations: translationProvider,
schema: schemaModule.default,
dbConfig: {
@@ -241,7 +242,14 @@ initialize().catch(err => {
self.onmessage = async (event) => {
const msg = event.data;
if (!msg || msg.type !== "LOCAL_REQUEST") return;
if (!msg) return;
if (msg.type === "INIT") {
queryString = msg.queryString || "";
return;
}
if (msg.type !== "LOCAL_REQUEST") return;
const { id, request } = msg;

View File

@@ -6,4 +6,8 @@ export default class DesktopPlatformProvider implements PlatformProvider {
electron.dialog.showErrorBox(t("modals.error_title"), message);
electron.app.exit(1);
}
getEnv(key: string): string | undefined {
return process.env[key];
}
}

View File

@@ -5,4 +5,8 @@ export default class ServerPlatformProvider implements PlatformProvider {
getLog().error(message);
process.exit(1);
}
getEnv(key: string): string | undefined {
return process.env[key];
}
}

View File

@@ -24,7 +24,7 @@ async function migrate() {
}
// backup before attempting migration
if (!process.env.TRILIUM_INTEGRATION_TEST) {
if (!getPlatform().getEnv("TRILIUM_INTEGRATION_TEST")) {
await backupService.backupNow(
// creating a special backup for version 0.60.4, the changes in 0.61 are major.
currentDbVersion === 214 ? `before-migration-v060` : "before-migration"
@@ -123,7 +123,7 @@ function isDbUpToDate() {
async function migrateIfNecessary() {
const currentDbVersion = getDbVersion();
if (currentDbVersion > appInfo.dbVersion && process.env.TRILIUM_IGNORE_DB_VERSION !== "true") {
if (currentDbVersion > appInfo.dbVersion && getPlatform().getEnv("TRILIUM_IGNORE_DB_VERSION") !== "true") {
getPlatform().crash(t("migration.wrong_db_version", { version: currentDbVersion, targetVersion: appInfo.dbVersion }));
}

View File

@@ -1,6 +1,7 @@
import { type KeyboardShortcutWithRequiredActionName, type OptionMap, type OptionNames, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
import appInfo from "./app_info.js";
import { getPlatform } from "./platform.js";
import dateUtils from "./utils/date.js";
import keyboardActions from "./keyboard_actions.js";
import { getLog } from "./log.js";
@@ -237,12 +238,12 @@ export function initStartupOptions() {
}
}
if (process.env.TRILIUM_START_NOTE_ID || process.env.TRILIUM_SAFE_MODE) {
if (getPlatform().getEnv("TRILIUM_START_NOTE_ID") || getPlatform().getEnv("TRILIUM_SAFE_MODE")) {
optionService.setOption(
"openNoteContexts",
JSON.stringify([
{
notePath: process.env.TRILIUM_START_NOTE_ID || "root",
notePath: getPlatform().getEnv("TRILIUM_START_NOTE_ID") || "root",
active: true
}
])

View File

@@ -3,6 +3,8 @@
*/
export interface PlatformProvider {
crash(message: string): void;
/** Returns the value of an environment variable, or undefined if not set. */
getEnv(key: string): string | undefined;
}
let platformProvider: PlatformProvider | null = null;