mirror of
https://github.com/zadam/trilium.git
synced 2025-11-15 09:45:52 +01:00
Merge remote-tracking branch 'origin/main' into feature/table_view
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
<h2>Steps</h2>
|
||||
<ul>
|
||||
<li>SSH into your server</li>
|
||||
<li>use <code>wget</code> (or <code>curl</code>) to download latest <code>TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz</code> (copy
|
||||
<li>use <code>wget</code> (or <code>curl</code>) to download latest <code>TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code> (copy
|
||||
link from <a href="https://github.com/TriliumNext/Notes/releases">release page</a>,
|
||||
notice <code>-Server</code> suffix) on your server.</li>
|
||||
<li>unpack the archive, e.g. using <code>tar -xf -d TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz</code>
|
||||
<li>unpack the archive, e.g. using <code>tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code>
|
||||
</li>
|
||||
<li><code>cd trilium-linux-x64-server</code>
|
||||
</li>
|
||||
@@ -27,7 +27,7 @@
|
||||
<h2>Configure Trilium to auto-run on boot with systemd</h2>
|
||||
<ul>
|
||||
<li>After downloading, extract and move Trilium:</li>
|
||||
</ul><pre><code class="language-text-x-trilium-auto">tar -xvf TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz
|
||||
</ul><pre><code class="language-text-x-trilium-auto">tar -xvf TriliumNotes-Server-[VERSION]-linux-x64.tar.xz
|
||||
sudo mv trilium-linux-x64-server /opt/trilium</code></pre>
|
||||
<ul>
|
||||
<li>Create the service:</li>
|
||||
|
||||
22
apps/server/src/becca/entities/brevision.spec.ts
Normal file
22
apps/server/src/becca/entities/brevision.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import BRevision from "./brevision.js";
|
||||
|
||||
describe("Revision", () => {
|
||||
it("handles note with empty title properly", () => {
|
||||
const revision = new BRevision({
|
||||
revisionId: "4omM5OvlLhOw",
|
||||
noteId: "WHMg7iFCRG3Z",
|
||||
type: "text",
|
||||
mime: "text/html",
|
||||
isProtected: false,
|
||||
title: "",
|
||||
blobId: "",
|
||||
dateLastEdited: "2025-06-27 14:10:39.688+0300",
|
||||
dateCreated: "2025-06-27 14:10:39.688+0300",
|
||||
utcDateLastEdited: "2025-06-27 14:10:39.688+0300",
|
||||
utcDateCreated: "2025-06-27 14:10:39.688+0300",
|
||||
utcDateModified: "2025-06-27 14:10:39.688+0300"
|
||||
});
|
||||
const pojo = revision.getPojo();
|
||||
expect(pojo.title).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -192,7 +192,7 @@ class BRevision extends AbstractBeccaEntity<BRevision> {
|
||||
type: this.type,
|
||||
mime: this.mime,
|
||||
isProtected: this.isProtected,
|
||||
title: this.title || undefined,
|
||||
title: this.title,
|
||||
blobId: this.blobId,
|
||||
dateLastEdited: this.dateLastEdited,
|
||||
dateCreated: this.dateCreated,
|
||||
@@ -211,10 +211,10 @@ class BRevision extends AbstractBeccaEntity<BRevision> {
|
||||
|
||||
if (pojo.isProtected) {
|
||||
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||
pojo.title = protectedSessionService.encrypt(this.title) || undefined;
|
||||
pojo.title = protectedSessionService.encrypt(this.title) ?? "";
|
||||
} else {
|
||||
// updating protected note outside of protected session means we will keep original ciphertexts
|
||||
delete pojo.title;
|
||||
pojo.title = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@ import type Becca from "../becca/becca-interface.js";
|
||||
import type { NoteParams } from "./note-interface.js";
|
||||
import type { ApiParams } from "./backend_script_api_interface.js";
|
||||
|
||||
// Dayjs plugins
|
||||
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
|
||||
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
|
||||
import isBetween from "dayjs/plugin/isBetween";
|
||||
import advancedFormat from "dayjs/plugin/advancedFormat.js";
|
||||
|
||||
dayjs.extend(isSameOrBefore);
|
||||
dayjs.extend(isSameOrAfter);
|
||||
dayjs.extend(isBetween);
|
||||
dayjs.extend(advancedFormat);
|
||||
|
||||
/**
|
||||
* A whole number
|
||||
* @typedef {number} int
|
||||
|
||||
114
apps/server/src/services/script.spec.ts
Normal file
114
apps/server/src/services/script.spec.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import becca from "../becca/becca.js";
|
||||
import { note, NoteBuilder } from "../test/becca_mocking.js";
|
||||
import cls from "./cls.js";
|
||||
import { executeBundle, getScriptBundle } from "./script.js";
|
||||
import BBranch from "../becca/entities/bbranch.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
|
||||
|
||||
describe("Script", () => {
|
||||
let rootNote!: NoteBuilder;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
becca.reset();
|
||||
|
||||
rootNote = new NoteBuilder(
|
||||
new BNote({
|
||||
noteId: "root",
|
||||
title: "root",
|
||||
type: "text"
|
||||
})
|
||||
);
|
||||
new BBranch({
|
||||
branchId: "none_root",
|
||||
noteId: "root",
|
||||
parentNoteId: "none",
|
||||
notePosition: 10
|
||||
});
|
||||
|
||||
vi.mock("./sql.js", () => {
|
||||
return {
|
||||
default: {
|
||||
transactional: (cb: Function) => {
|
||||
cb();
|
||||
},
|
||||
execute: () => {},
|
||||
replace: () => {},
|
||||
getMap: () => {}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./sql_init.js", () => {
|
||||
return {
|
||||
dbReady: () => {
|
||||
console.log("Hello world");
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
it("returns result from script", () => {
|
||||
cls.init(() => {
|
||||
const result = executeBundle({
|
||||
script: `return "world";`,
|
||||
html: "",
|
||||
});
|
||||
expect(result).toBe("world");
|
||||
});
|
||||
});
|
||||
|
||||
describe("dayjs", () => {
|
||||
const scriptNote = note("dayjs", {
|
||||
type: "code",
|
||||
mime: "application/javascript;env=backend",
|
||||
});
|
||||
|
||||
it("dayjs is available", () => {
|
||||
cls.init(() => {
|
||||
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs().format("YYYY-MM-DD");`);
|
||||
expect(bundle).toBeDefined();
|
||||
const result = executeBundle(bundle!);
|
||||
expect(result).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
||||
});
|
||||
});
|
||||
|
||||
it("dayjs is-same-or-before", () => {
|
||||
cls.init(() => {
|
||||
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-01").isSameOrBefore(api.dayjs("2023-10-02"));`);
|
||||
expect(bundle).toBeDefined();
|
||||
const result = executeBundle(bundle!);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("dayjs is-same-or-after", () => {
|
||||
cls.init(() => {
|
||||
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-02").isSameOrAfter(api.dayjs("2023-10-01"));`);
|
||||
expect(bundle).toBeDefined();
|
||||
const result = executeBundle(bundle!);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("dayjs is-between", () => {
|
||||
cls.init(() => {
|
||||
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-02").isBetween(api.dayjs("2023-10-01"), api.dayjs("2023-10-03"));`);
|
||||
expect(bundle).toBeDefined();
|
||||
const result = executeBundle(bundle!);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// advanced format
|
||||
it("dayjs advanced format", () => {
|
||||
cls.init(() => {
|
||||
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-01").format("Q");`);
|
||||
expect(bundle).toBeDefined();
|
||||
const result = executeBundle(bundle!);
|
||||
expect(result).not.toBe("Q");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -39,7 +39,7 @@ function executeNoteNoException(note: BNote, apiParams: ApiParams) {
|
||||
}
|
||||
}
|
||||
|
||||
function executeBundle(bundle: Bundle, apiParams: ApiParams = {}) {
|
||||
export function executeBundle(bundle: Bundle, apiParams: ApiParams = {}) {
|
||||
if (!apiParams.startNote) {
|
||||
// this is the default case, the only exception is when we want to preserve frontend startNote
|
||||
apiParams.startNote = bundle.note;
|
||||
@@ -140,7 +140,7 @@ function getScriptBundleForFrontend(note: BNote, script?: string, params?: Scrip
|
||||
return bundle;
|
||||
}
|
||||
|
||||
function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string | null = null, includedNoteIds: string[] = [], overrideContent: string | null = null): Bundle | undefined {
|
||||
export function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string | null = null, includedNoteIds: string[] = [], overrideContent: string | null = null): Bundle | undefined {
|
||||
if (!note.isContentAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user