mirror of
https://github.com/zadam/trilium.git
synced 2025-10-27 08:16:40 +01:00
Compare commits
80 Commits
kev/share-
...
feat/clean
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64f191b83b | ||
|
|
31c8e96d70 | ||
|
|
1191421388 | ||
|
|
831a184c2a | ||
|
|
c671f91bca | ||
|
|
fa436c7ce6 | ||
|
|
d1367286c9 | ||
|
|
d10b0fa823 | ||
|
|
545c8648b7 | ||
|
|
d6e9acc149 | ||
|
|
26e14aff7b | ||
|
|
280ec5b406 | ||
|
|
26081ffd36 | ||
|
|
f106cbf6c0 | ||
|
|
f3877a52ab | ||
|
|
5becf60a63 | ||
|
|
2ea96dc8f8 | ||
|
|
e48724662e | ||
|
|
745ce7de76 | ||
|
|
997217861c | ||
|
|
44f8e8b833 | ||
|
|
99e2b63ff0 | ||
|
|
0139d90ac7 | ||
|
|
5b7484c27c | ||
|
|
71e64be44c | ||
|
|
639651329a | ||
|
|
a7a0d3584a | ||
|
|
f765441f1e | ||
|
|
10cd5bf130 | ||
|
|
d93c5dfeea | ||
|
|
b58aac1298 | ||
|
|
d662718a4a | ||
|
|
bebd3d430b | ||
|
|
2fca995725 | ||
|
|
caa1ea12f1 | ||
|
|
f25e4ea391 | ||
|
|
05b433edb5 | ||
|
|
b8851565eb | ||
|
|
888d0d1084 | ||
|
|
0a25d4db0d | ||
|
|
d483b6e840 | ||
|
|
979fbe2e76 | ||
|
|
ea5564c6e6 | ||
|
|
6ab8750726 | ||
|
|
923eabd750 | ||
|
|
c52d6a6384 | ||
|
|
519b9648c6 | ||
|
|
b25fd6ca3a | ||
|
|
2bd8c215ff | ||
|
|
34e7901de9 | ||
|
|
30a191cedf | ||
|
|
128d8907c3 | ||
|
|
3b1d7d045e | ||
|
|
0ae9a29e0d | ||
|
|
f4b5ed73ad | ||
|
|
43166dbeb5 | ||
|
|
00b5aef890 | ||
|
|
1b7266f083 | ||
|
|
d1d4b47111 | ||
|
|
c90364bd76 | ||
|
|
6dc687ef43 | ||
|
|
0e31aab1ab | ||
|
|
b0030f89b7 | ||
|
|
9f0a0238cc | ||
|
|
dabdfaddec | ||
|
|
a8901e6dc8 | ||
|
|
ab901a5d32 | ||
|
|
56fc2d9b30 | ||
|
|
df45fa2e1e | ||
|
|
9a11fc13d7 | ||
|
|
d72a0d3c69 | ||
|
|
0be508ed70 | ||
|
|
37f3a9b19d | ||
|
|
81d2fbc057 | ||
|
|
1aecf66cbe | ||
|
|
fbe7d64e00 | ||
|
|
c9d151289c | ||
|
|
bba2f6db64 | ||
|
|
6725f81a00 | ||
|
|
8487c8cd03 |
@@ -35,7 +35,7 @@
|
|||||||
"chore:generate-openapi": "tsx bin/generate-openapi.js"
|
"chore:generate-openapi": "tsx bin/generate-openapi.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "1.55.1",
|
"@playwright/test": "1.56.0",
|
||||||
"@stylistic/eslint-plugin": "5.4.0",
|
"@stylistic/eslint-plugin": "5.4.0",
|
||||||
"@types/express": "5.0.3",
|
"@types/express": "5.0.3",
|
||||||
"@types/node": "22.18.8",
|
"@types/node": "22.18.8",
|
||||||
|
|||||||
@@ -3,16 +3,7 @@ import linkContextMenuService from "../menus/link_context_menu.js";
|
|||||||
import appContext, { type NoteCommandData } from "../components/app_context.js";
|
import appContext, { type NoteCommandData } from "../components/app_context.js";
|
||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
|
import { ALLOWED_PROTOCOLS } from "@triliumnext/commons";
|
||||||
// Be consistent with `allowedSchemes` in `src\services\html_sanitizer.ts`
|
|
||||||
// TODO: Deduplicate with server once we can.
|
|
||||||
export const ALLOWED_PROTOCOLS = [
|
|
||||||
'http', 'https', 'ftp', 'ftps', 'mailto', 'data', 'evernote', 'file', 'facetime', 'gemini', 'git',
|
|
||||||
'gopher', 'imap', 'irc', 'irc6', 'jabber', 'jar', 'lastfm', 'ldap', 'ldaps', 'magnet', 'message',
|
|
||||||
'mumble', 'nfs', 'onenote', 'pop', 'rmi', 's3', 'sftp', 'skype', 'sms', 'spotify', 'steam', 'svn', 'udp',
|
|
||||||
'view-source', 'vlc', 'vnc', 'ws', 'wss', 'xmpp', 'jdbc', 'slack', 'tel', 'smb', 'zotero', 'geo',
|
|
||||||
'mid'
|
|
||||||
];
|
|
||||||
|
|
||||||
function getNotePathFromUrl(url: string) {
|
function getNotePathFromUrl(url: string) {
|
||||||
const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url);
|
const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url);
|
||||||
|
|||||||
@@ -1743,9 +1743,17 @@
|
|||||||
"show_login_link": "在共享主题中显示登录链接",
|
"show_login_link": "在共享主题中显示登录链接",
|
||||||
"show_login_link_description": "在共享页面底部添加登录链接",
|
"show_login_link_description": "在共享页面底部添加登录链接",
|
||||||
"check_share_root": "检查共享根状态",
|
"check_share_root": "检查共享根状态",
|
||||||
|
"check_share_root_error": "检查共享根状态时发生意外错误,请检查日志以获取更多信息。",
|
||||||
|
"share_note_title": "'{{noteTitle}}'",
|
||||||
"share_root_found": "共享根笔记 '{{noteTitle}}' 已准备好",
|
"share_root_found": "共享根笔记 '{{noteTitle}}' 已准备好",
|
||||||
"share_root_not_found": "未找到带有 #shareRoot 标签的笔记",
|
"share_root_not_found": "未找到带有 #shareRoot 标签的笔记",
|
||||||
"share_root_not_shared": "笔记 '{{noteTitle}}' 具有 #shareRoot 标签,但未共享"
|
"share_root_not_shared": "笔记 '{{noteTitle}}' 具有 #shareRoot 标签,但未共享",
|
||||||
|
"share_root_multiple_found": "找到多个具有 #shareRoot 标签的共享笔记:{{- foundNoteTitles}}。将使用笔记 {{- activeNoteTitle}} 作为共享根笔记。",
|
||||||
|
"share_path": "共享路径",
|
||||||
|
"share_path_description": "共享笔记的 URL 前缀(例如 '/share' --> '/share/noteId' 或 '/custom-path' --> '/custom-path/noteId')。支持多级嵌套(例如 '/custom-path/sub-path' --> '/custom-path/sub-path/noteId')。刷新页面以应用更改。",
|
||||||
|
"share_path_placeholder": "/share 或 /custom-path",
|
||||||
|
"share_subtree": "共享子树",
|
||||||
|
"share_subtree_description": "共享整个子树,而不是仅共享笔记"
|
||||||
},
|
},
|
||||||
"time_selector": {
|
"time_selector": {
|
||||||
"invalid_input": "输入的时间值不是有效数字。",
|
"invalid_input": "输入的时间值不是有效数字。",
|
||||||
|
|||||||
@@ -1907,9 +1907,17 @@
|
|||||||
"show_login_link": "Show Login link in Share theme",
|
"show_login_link": "Show Login link in Share theme",
|
||||||
"show_login_link_description": "Add a login link to the Share page footer",
|
"show_login_link_description": "Add a login link to the Share page footer",
|
||||||
"check_share_root": "Check Share Root Status",
|
"check_share_root": "Check Share Root Status",
|
||||||
|
"check_share_root_error": "An unexpected error happened while checking the Share Root Status, please check the logs for more information.",
|
||||||
|
"share_note_title": "'{{noteTitle}}'",
|
||||||
"share_root_found": "Share root note '{{noteTitle}}' is ready",
|
"share_root_found": "Share root note '{{noteTitle}}' is ready",
|
||||||
"share_root_not_found": "No note with #shareRoot label found",
|
"share_root_not_found": "No note with #shareRoot label found",
|
||||||
"share_root_not_shared": "Note '{{noteTitle}}' has #shareRoot label but is not shared"
|
"share_root_not_shared": "Note '{{noteTitle}}' has #shareRoot label but is not Shared",
|
||||||
|
"share_root_multiple_found": "Found multiple shared notes with a #shareRoot label: {{- foundNoteTitles}}. The note {{- activeNoteTitle}} will be used as shared root note.",
|
||||||
|
"share_path": "Share path",
|
||||||
|
"share_path_description": "The url prefix for shared notes (e.g. '/share' --> '/share/noteId' or '/custom-path' --> '/custom-path/noteId'). Multiple levels of nesting are supported (e.g. '/custom-path/sub-path' --> '/custom-path/sub-path/noteId'). Refresh the page to apply the changes.",
|
||||||
|
"share_path_placeholder": "/share or /custom-path",
|
||||||
|
"share_subtree": "Share subtree",
|
||||||
|
"share_subtree_description": "Share the entire subtree, not just the note"
|
||||||
},
|
},
|
||||||
"time_selector": {
|
"time_selector": {
|
||||||
"invalid_input": "The entered time value is not a valid number.",
|
"invalid_input": "The entered time value is not a valid number.",
|
||||||
|
|||||||
@@ -251,12 +251,12 @@
|
|||||||
"help": {
|
"help": {
|
||||||
"title": "チートシート",
|
"title": "チートシート",
|
||||||
"noteNavigation": "ノートナビゲーション",
|
"noteNavigation": "ノートナビゲーション",
|
||||||
"collapseExpand": "ノードの格納/展開",
|
"collapseExpand": "ノードを折りたたむ / 展開",
|
||||||
"goBackForwards": "履歴を戻る/進む",
|
"goBackForwards": "履歴を戻る/進む",
|
||||||
"scrollToActiveNote": "アクティブノートまでスクロール",
|
"scrollToActiveNote": "アクティブノートまでスクロール",
|
||||||
"jumpToParentNote": "親ノートへ移動",
|
"jumpToParentNote": "親ノートへ移動",
|
||||||
"collapseWholeTree": "すべてのノートツリーを格納",
|
"collapseWholeTree": "すべてのノートツリーを折りたたむ",
|
||||||
"collapseSubTree": "サブツリーを格納",
|
"collapseSubTree": "サブツリーを折りたたむ",
|
||||||
"tabShortcuts": "タブショートカット",
|
"tabShortcuts": "タブショートカット",
|
||||||
"newTabNoteLink": "ノートのリンクをクリックすると、新しいタブで開く",
|
"newTabNoteLink": "ノートのリンクをクリックすると、新しいタブで開く",
|
||||||
"newTabWithActivationNoteLink": "ノートのリンクをクリックすると、新しいタブで開き、アクティブにします",
|
"newTabWithActivationNoteLink": "ノートのリンクをクリックすると、新しいタブで開き、アクティブにします",
|
||||||
@@ -515,9 +515,9 @@
|
|||||||
"book_properties": {
|
"book_properties": {
|
||||||
"grid": "グリッド",
|
"grid": "グリッド",
|
||||||
"list": "リスト",
|
"list": "リスト",
|
||||||
"collapse_all_notes": "すべてのノートを格納",
|
"collapse_all_notes": "すべてのノートを折りたたむ",
|
||||||
"expand_all_children": "すべての子を展開",
|
"expand_all_children": "すべての子を展開",
|
||||||
"collapse": "格納",
|
"collapse": "折りたたむ",
|
||||||
"expand": "展開",
|
"expand": "展開",
|
||||||
"book_properties": "コレクションプロパティ",
|
"book_properties": "コレクションプロパティ",
|
||||||
"invalid_view_type": "無効なビュータイプ '{{type}}'",
|
"invalid_view_type": "無効なビュータイプ '{{type}}'",
|
||||||
|
|||||||
@@ -1 +1,6 @@
|
|||||||
{}
|
{
|
||||||
|
"about": {
|
||||||
|
"title": "Acerca de \"Trillium Notes\"",
|
||||||
|
"app_version": "Versão da aplicação:"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { ALLOWED_PROTOCOLS } from "../../../services/link.js";
|
import { ALLOWED_PROTOCOLS, MIME_TYPE_AUTO } from "@triliumnext/commons";
|
||||||
import { MIME_TYPE_AUTO } from "@triliumnext/commons";
|
|
||||||
import { buildExtraCommands, type EditorConfig, PREMIUM_PLUGINS } from "@triliumnext/ckeditor5";
|
import { buildExtraCommands, type EditorConfig, PREMIUM_PLUGINS } from "@triliumnext/ckeditor5";
|
||||||
import { getHighlightJsNameForMime } from "../../../services/mime_types.js";
|
import { getHighlightJsNameForMime } from "../../../services/mime_types.js";
|
||||||
import options from "../../../services/options.js";
|
import options from "../../../services/options.js";
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// Ensure sharePath always starts with a single slash and does not end with (one or multiple) trailing slashes
|
||||||
|
export function normalizeSharePathInput(sharePathInput: string) {
|
||||||
|
const REGEXP_STARTING_SLASH = /^\/+/g;
|
||||||
|
const REGEXP_TRAILING_SLASH = /\b\/+$/g;
|
||||||
|
|
||||||
|
const normalizedSharePath = (!sharePathInput.startsWith("/")
|
||||||
|
? `/${sharePathInput}`
|
||||||
|
: sharePathInput)
|
||||||
|
.replaceAll(REGEXP_TRAILING_SLASH, "")
|
||||||
|
.replaceAll(REGEXP_STARTING_SLASH, "/");
|
||||||
|
|
||||||
|
return normalizedSharePath;
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { normalizeSharePathInput } from "./share_path_utils.js";
|
||||||
|
|
||||||
|
type TestCase<T extends (...args: any) => any> = [
|
||||||
|
desc: string,
|
||||||
|
fnParams: Parameters<T>,
|
||||||
|
expected: ReturnType<T>
|
||||||
|
];
|
||||||
|
|
||||||
|
describe("ShareSettingsOptions", () => {
|
||||||
|
|
||||||
|
describe("#normalizeSharePathInput", () => {
|
||||||
|
|
||||||
|
const testCases: TestCase<typeof normalizeSharePathInput>[] = [
|
||||||
|
[
|
||||||
|
"should handle multiple trailing '/' and remove them completely",
|
||||||
|
["/trailingtest////"],
|
||||||
|
"/trailingtest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"should handle multiple starting '/' and replace them by a single '/'",
|
||||||
|
["////startingtest"],
|
||||||
|
"/startingtest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"should handle multiple starting & trailing '/' and replace them by a single '/'",
|
||||||
|
["////startingAndTrailingTest///"],
|
||||||
|
"/startingAndTrailingTest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"should not remove any '/' other than at the end or start of the input",
|
||||||
|
["/test/with/subpath"],
|
||||||
|
"/test/with/subpath"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"should prepend the string with a '/' if it does not start with one",
|
||||||
|
["testpath"],
|
||||||
|
"/testpath"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"should not change anything, if the string is a single '/'",
|
||||||
|
["/"],
|
||||||
|
"/"
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
testCases.forEach((testCase) => {
|
||||||
|
const [desc, fnParams, expected] = testCase;
|
||||||
|
it(desc, () => {
|
||||||
|
const actual = normalizeSharePathInput(...fnParams);
|
||||||
|
expect(actual).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -90,6 +90,10 @@ const config: ForgeConfig = {
|
|||||||
base: "org.electronjs.Electron2.BaseApp",
|
base: "org.electronjs.Electron2.BaseApp",
|
||||||
baseVersion: "24.08",
|
baseVersion: "24.08",
|
||||||
baseFlatpakref: "https://flathub.org/repo/flathub.flatpakrepo",
|
baseFlatpakref: "https://flathub.org/repo/flathub.flatpakrepo",
|
||||||
|
finishArgs: [
|
||||||
|
"--socket=fallback-x11",
|
||||||
|
"--socket=wayland"
|
||||||
|
],
|
||||||
modules: [
|
modules: [
|
||||||
{
|
{
|
||||||
name: "zypak",
|
name: "zypak",
|
||||||
|
|||||||
73
apps/edit-docs/demo/!!!meta.json
vendored
73
apps/edit-docs/demo/!!!meta.json
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"formatVersion": 2,
|
"formatVersion": 2,
|
||||||
"appVersion": "0.98.1",
|
"appVersion": "0.99.1",
|
||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"isClone": false,
|
"isClone": false,
|
||||||
@@ -60,6 +60,13 @@
|
|||||||
"value": "dayGridMonth",
|
"value": "dayGridMonth",
|
||||||
"isInheritable": false,
|
"isInheritable": false,
|
||||||
"position": 40
|
"position": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "relation",
|
||||||
|
"name": "dateTemplate",
|
||||||
|
"value": "bRQvb9VCkc3t",
|
||||||
|
"isInheritable": false,
|
||||||
|
"position": 50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dataFileName": "Journal.dat",
|
"dataFileName": "Journal.dat",
|
||||||
@@ -75,7 +82,7 @@
|
|||||||
"title": "Trilium Demo",
|
"title": "Trilium Demo",
|
||||||
"notePosition": 20,
|
"notePosition": 20,
|
||||||
"prefix": null,
|
"prefix": null,
|
||||||
"isExpanded": true,
|
"isExpanded": false,
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"mime": "text/html",
|
"mime": "text/html",
|
||||||
"attributes": [
|
"attributes": [
|
||||||
@@ -6033,6 +6040,68 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"isClone": false,
|
||||||
|
"noteId": "fhNlr1V1o3d8",
|
||||||
|
"notePath": [
|
||||||
|
"root",
|
||||||
|
"fhNlr1V1o3d8"
|
||||||
|
],
|
||||||
|
"title": "Miscellaneous",
|
||||||
|
"notePosition": 30,
|
||||||
|
"prefix": null,
|
||||||
|
"isExpanded": false,
|
||||||
|
"type": "text",
|
||||||
|
"mime": "text/html",
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"type": "label",
|
||||||
|
"name": "iconClass",
|
||||||
|
"value": "bx bx-dots-horizontal-rounded",
|
||||||
|
"isInheritable": false,
|
||||||
|
"position": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"format": "html",
|
||||||
|
"attachments": [],
|
||||||
|
"dirFileName": "Miscellaneous",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"isClone": false,
|
||||||
|
"noteId": "bRQvb9VCkc3t",
|
||||||
|
"notePath": [
|
||||||
|
"root",
|
||||||
|
"fhNlr1V1o3d8",
|
||||||
|
"bRQvb9VCkc3t"
|
||||||
|
],
|
||||||
|
"title": "Day Note Template",
|
||||||
|
"notePosition": 10,
|
||||||
|
"prefix": null,
|
||||||
|
"isExpanded": false,
|
||||||
|
"type": "text",
|
||||||
|
"mime": "text/html",
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"type": "label",
|
||||||
|
"name": "iconClass",
|
||||||
|
"value": "bx bx-notepad",
|
||||||
|
"isInheritable": false,
|
||||||
|
"position": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "label",
|
||||||
|
"name": "excludeFromNoteMap",
|
||||||
|
"value": "",
|
||||||
|
"isInheritable": false,
|
||||||
|
"position": 20
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"format": "html",
|
||||||
|
"dataFileName": "Day Note Template.html",
|
||||||
|
"attachments": []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
6
apps/edit-docs/demo/navigation.html
vendored
6
apps/edit-docs/demo/navigation.html
vendored
@@ -637,6 +637,12 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>Miscellaneous
|
||||||
|
<ul>
|
||||||
|
<li><a href="root/Miscellaneous/Day%20Note%20Template.html" target="detail">Day Note Template</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
24
apps/edit-docs/demo/root/Miscellaneous/Day Note Template.html
vendored
Normal file
24
apps/edit-docs/demo/root/Miscellaneous/Day Note Template.html
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../../style.css">
|
||||||
|
<base target="_parent">
|
||||||
|
<title data-trilium-title>Day Note Template</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1 data-trilium-h1>Day Note Template</h1>
|
||||||
|
|
||||||
|
<div class="ck-content">
|
||||||
|
<h2>☑️ Tasks</h2>
|
||||||
|
<ul>
|
||||||
|
<li data-list-item-id="e4b26220d6ce48997f1116dc1d1d83dc0">[…]</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -23,10 +23,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
alert("Hello world");
|
alert("Hello world");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}</code></pre>
|
}</code></pre>
|
||||||
<p>For larger pieces of code it is better to use a code note, which uses
|
<p>For larger pieces of code it is better to use a code note, which uses
|
||||||
a fully-fledged code editor (CodeMirror). For an example of a code note,
|
a fully-fledged code editor (CodeMirror). For an example of a code note,
|
||||||
|
|||||||
@@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# This script opens 4 terminal windows.
|
# This script opens 4 terminal windows.
|
||||||
|
|
||||||
|
|
||||||
@@ -26,18 +30,38 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i="0"
|
i="0"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while [ $i -lt 4 ]
|
while [ $i -lt 4 ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xterm &
|
xterm &
|
||||||
|
|
||||||
|
|
||||||
@@ -46,10 +70,22 @@ do
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i=$[$i+1]
|
i=$[$i+1]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
done</code></pre>
|
done</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
"multer": "2.0.2",
|
"multer": "2.0.2",
|
||||||
"normalize-strings": "1.1.1",
|
"normalize-strings": "1.1.1",
|
||||||
"ollama": "0.6.0",
|
"ollama": "0.6.0",
|
||||||
"openai": "6.1.0",
|
"openai": "6.2.0",
|
||||||
"rand-token": "1.0.1",
|
"rand-token": "1.0.1",
|
||||||
"safe-compare": "1.1.4",
|
"safe-compare": "1.1.4",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
|
|||||||
Binary file not shown.
@@ -116,6 +116,13 @@ class="admonition tip">
|
|||||||
<td>JavaScript note which will be injected into the share page. JS note must
|
<td>JavaScript note which will be injected into the share page. JS note must
|
||||||
be in the shared sub-tree as well. Consider using <code>share_hidden_from_tree</code>.</td>
|
be in the shared sub-tree as well. Consider using <code>share_hidden_from_tree</code>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>shareHtml</code>
|
||||||
|
</td>
|
||||||
|
<td>HTML note which will be injected into the share page at locations specified
|
||||||
|
by the <code>shareHtmlLocation</code> label. HTML note must be in the shared
|
||||||
|
sub-tree as well. Consider using <code>share_hidden_from_tree</code>.</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>shareTemplate</code>
|
<td><code>shareTemplate</code>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
47
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Advanced Usage/Sharing.html
generated
vendored
47
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Advanced Usage/Sharing.html
generated
vendored
@@ -6,8 +6,7 @@ class="image">
|
|||||||
<img style="aspect-ratio:1144/660;" src="Sharing_image.png" width="1144"
|
<img style="aspect-ratio:1144/660;" src="Sharing_image.png" width="1144"
|
||||||
height="660">
|
height="660">
|
||||||
</figure>
|
</figure>
|
||||||
|
<h2>Features, interaction and limitations</h2>
|
||||||
<h2>Features, interaction and limitations</h2>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Searching by note title.</li>
|
<li>Searching by note title.</li>
|
||||||
<li>Automatic dark/light mode based on the user's browser settings.</li>
|
<li>Automatic dark/light mode based on the user's browser settings.</li>
|
||||||
@@ -189,11 +188,9 @@ class="image">
|
|||||||
<img src="Sharing_share-single-note.png" alt="Share Note">
|
<img src="Sharing_share-single-note.png" alt="Share Note">
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li><strong>Access the Shared Note</strong>: The link provided will open the
|
||||||
<p><strong>Access the Shared Note</strong>: The link provided will open the
|
note in your browser. If your server is not configured with a public IP,
|
||||||
note in your browser. If your server is not configured with a public IP,
|
the URL will refer to <code>localhost (127.0.0.1)</code>.</li>
|
||||||
the URL will refer to <code>localhost (127.0.0.1)</code>.</p>
|
|
||||||
</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
<h2>Sharing a note subtree</h2>
|
<h2>Sharing a note subtree</h2>
|
||||||
<p>When you share a note, you actually share the entire subtree of notes
|
<p>When you share a note, you actually share the entire subtree of notes
|
||||||
@@ -234,6 +231,34 @@ class="image">
|
|||||||
This allows you to access note attributes or traverse the note tree using
|
This allows you to access note attributes or traverse the note tree using
|
||||||
the <code>fetchNote()</code> API, which retrieves note data based on its
|
the <code>fetchNote()</code> API, which retrieves note data based on its
|
||||||
ID.</p>
|
ID.</p>
|
||||||
|
<h3>Adding custom HTML</h3>
|
||||||
|
<p>You can inject custom HTML snippets into specific locations of the shared
|
||||||
|
page using the <code>~shareHtml</code> relation. The HTML note should contain
|
||||||
|
the raw HTML content you want to inject, and you can control where it appears
|
||||||
|
by adding the <code>#shareHtmlLocation</code> label to the HTML snippet note
|
||||||
|
itself.</p>
|
||||||
|
<p>The <code>#shareHtmlLocation</code> label accepts values in the format <code>location:position</code>:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Locations</strong>: <code>head</code>, <code>body</code>, <code>content</code>
|
||||||
|
</li>
|
||||||
|
<li><strong>Positions</strong>: <code>start</code>, <code>end</code>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>For example:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>#shareHtmlLocation=head:start</code> - Injects HTML at the beginning
|
||||||
|
of the <code><head></code> section</li>
|
||||||
|
<li><code>#shareHtmlLocation=head:end</code> - Injects HTML at the end of the <code><head></code> section
|
||||||
|
(default)</li>
|
||||||
|
<li><code>#shareHtmlLocation=body:start</code> - Injects HTML at the beginning
|
||||||
|
of the <code><body></code> section</li>
|
||||||
|
<li><code>#shareHtmlLocation=content:start</code> - Injects HTML at the beginning
|
||||||
|
of the content area</li>
|
||||||
|
<li><code>#shareHtmlLocation=content:end</code> - Injects HTML at the end of
|
||||||
|
the content area</li>
|
||||||
|
</ul>
|
||||||
|
<p>If no location is specified, the HTML will be injected at <code>content:end</code> by
|
||||||
|
default.</p>
|
||||||
<p>Example:</p><pre><code class="language-application-javascript-env-backend">const currentNote = await fetchNote();
|
<p>Example:</p><pre><code class="language-application-javascript-env-backend">const currentNote = await fetchNote();
|
||||||
const parentNote = await fetchNote(currentNote.parentNoteIds[0]);
|
const parentNote = await fetchNote(currentNote.parentNoteIds[0]);
|
||||||
|
|
||||||
@@ -344,6 +369,14 @@ for (const attr of parentNote.attributes) {
|
|||||||
</td>
|
</td>
|
||||||
<td>Note with this label will list all roots of shared notes.</td>
|
<td>Note with this label will list all roots of shared notes.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>shareHtmlLocation</code>
|
||||||
|
</td>
|
||||||
|
<td>defines where custom HTML injected via <code>~shareHtml</code> relation
|
||||||
|
should be placed. Applied to the HTML snippet note itself. Format: <code>location:position</code> where
|
||||||
|
location is <code>head</code>, <code>body</code>, or <code>content</code> and
|
||||||
|
position is <code>start</code> or <code>end</code>. Defaults to <code>content:end</code>.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
{
|
{
|
||||||
"keyboard_actions": {
|
"keyboard_actions": {
|
||||||
"back-in-note-history": "Navegar para a nota anterior no histórico",
|
"back-in-note-history": "Navegar para a nota anterior no histórico",
|
||||||
"forward-in-note-history": "Navegar para a próxima nota no histórico",
|
"forward-in-note-history": "Navegar para a nota seguinte no histórico",
|
||||||
"open-jump-to-note-dialog": "Abrir diálogo \"Ir para nota\"",
|
"open-jump-to-note-dialog": "Abrir diálogo \"Ir para nota\"",
|
||||||
"open-command-palette": "Abrir paleta de comandos",
|
"open-command-palette": "Abrir paleta de comandos",
|
||||||
"scroll-to-active-note": "Rolar a árvore de notas até a nota atual",
|
"scroll-to-active-note": "Rolar a árvore de notas até a nota atual",
|
||||||
"quick-search": "Ativar barra de pesquisa rápida",
|
"quick-search": "Ativar barra de pesquisa rápida",
|
||||||
"search-in-subtree": "Pesquisar notas na subárvore da nota atual",
|
"search-in-subtree": "Pesquisar notas na sub-árvore da nota atual",
|
||||||
"expand-subtree": "Expandir subárvore da nota atual",
|
"expand-subtree": "Expandir sub-árvore da nota atual",
|
||||||
"collapse-tree": "Colapsar a árvore completa de notas",
|
"collapse-tree": "Colapsar a árvore de notas completa",
|
||||||
"collapse-subtree": "Colapsar subárvore da nota atual",
|
"collapse-subtree": "Colapsar sub-árvore da nota atual",
|
||||||
"sort-child-notes": "Ordenar notas filhas",
|
"sort-child-notes": "Ordenar notas filhas",
|
||||||
"creating-and-moving-notes": "A criar e mover notas",
|
"creating-and-moving-notes": "A criar e mover notas",
|
||||||
"create-note-after": "Criar nota após nota atual",
|
"create-note-after": "Criar nota após nota atual",
|
||||||
"create-note-into": "Criar nota como subnota da nota atual",
|
"create-note-into": "Criar nota como sub-nota da nota atual",
|
||||||
"create-note-into-inbox": "Crie uma nota na caixa de entrada (se definida) ou na nota do dia",
|
"create-note-into-inbox": "Criar uma nota na caixa de entrada (se definida) ou na nota do dia",
|
||||||
"delete-note": "Apagar nota",
|
"delete-note": "Apagar nota",
|
||||||
"move-note-up": "Mover nota para cima",
|
"move-note-up": "Mover nota para cima",
|
||||||
"move-note-down": "Mover nota para baixo",
|
"move-note-down": "Mover nota para baixo",
|
||||||
"move-note-up-in-hierarchy": "Mover nota para cima na hierarquia",
|
"move-note-up-in-hierarchy": "Mover nota para cima na hierarquia",
|
||||||
"move-note-down-in-hierarchy": "Mover nota para baixo na hierarquia",
|
"move-note-down-in-hierarchy": "Mover nota para baixo na hierarquia",
|
||||||
"edit-note-title": "Pular da árvore para os pormenores da nota e editar o título",
|
"edit-note-title": "Saltar da árvore para os pormenores da nota e editar o título",
|
||||||
"edit-branch-prefix": "Exibir o diálogo \"Editar prefixo da ramificação\"",
|
"edit-branch-prefix": "Exibir o diálogo \"Editar prefixo da ramificação\"",
|
||||||
"clone-notes-to": "Clonar notas selecionadas",
|
"clone-notes-to": "Clonar notas selecionadas",
|
||||||
"move-notes-to": "Mover notas selecionadas",
|
"move-notes-to": "Mover notas selecionadas",
|
||||||
@@ -31,36 +31,36 @@
|
|||||||
"select-all-notes-in-parent": "Selecionar todas as notas do nível atual da nota",
|
"select-all-notes-in-parent": "Selecionar todas as notas do nível atual da nota",
|
||||||
"add-note-above-to-the-selection": "Adicionar nota acima à seleção",
|
"add-note-above-to-the-selection": "Adicionar nota acima à seleção",
|
||||||
"add-note-below-to-selection": "Adicionar nota abaixo à seleção",
|
"add-note-below-to-selection": "Adicionar nota abaixo à seleção",
|
||||||
"duplicate-subtree": "Duplicar subárvores",
|
"duplicate-subtree": "Duplicar subárvore",
|
||||||
"tabs-and-windows": "Guias & Janelas",
|
"tabs-and-windows": "Separadores & Janelas",
|
||||||
"open-new-tab": "Abre nova guia",
|
"open-new-tab": "Abre novo separador",
|
||||||
"close-active-tab": "Fecha guia ativa",
|
"close-active-tab": "Fechar separador ativo",
|
||||||
"reopen-last-tab": "Reabre a última guia fechada",
|
"reopen-last-tab": "Reabre o último separador fechado",
|
||||||
"activate-next-tab": "Ativa guia à direita",
|
"activate-next-tab": "Ativa separador à direita",
|
||||||
"activate-previous-tab": "Ativa guia à esquerda",
|
"activate-previous-tab": "Ativa separador à esquerda",
|
||||||
"open-new-window": "Abre nova janela vazia",
|
"open-new-window": "Abre nova janela vazia",
|
||||||
"toggle-tray": "Mostrar/ocultar a aplicação da bandeja do sistema",
|
"toggle-tray": "Mostrar/ocultar a aplicação na bandeja do sistema",
|
||||||
"first-tab": "Ativa a primeira guia na lista",
|
"first-tab": "Ativar o primeiro separador na lista",
|
||||||
"second-tab": "Ativa a segunda guia na lista",
|
"second-tab": "Ativa o segundo separador na lista",
|
||||||
"third-tab": "Ativa a terceira guia na lista",
|
"third-tab": "Ativar o terceiro separador na lista",
|
||||||
"fourth-tab": "Ativa a quarta guia na lista",
|
"fourth-tab": "Ativar o quarto separador na lista",
|
||||||
"fifth-tab": "Ativa a quinta guia na lista",
|
"fifth-tab": "Ativar o quinto separador na lista",
|
||||||
"sixth-tab": "Ativa a sexta guia na lista",
|
"sixth-tab": "Ativar o sexto separador na lista",
|
||||||
"seventh-tab": "Ativa a sétima guia na lista",
|
"seventh-tab": "Ativar o sétimo separador na lista",
|
||||||
"eight-tab": "Ativa a oitava guia na lista",
|
"eight-tab": "Ativar o oitavo separador na lista",
|
||||||
"ninth-tab": "Ativa a nona guia na lista",
|
"ninth-tab": "Ativar o novo separador na lista",
|
||||||
"last-tab": "Ativa a última guia na lista",
|
"last-tab": "Ativar o último separador na lista",
|
||||||
"dialogs": "Diálogos",
|
"dialogs": "Diálogos",
|
||||||
"show-note-source": "Exibe o diálogo de origem da nota",
|
"show-note-source": "Exibe o diálogo \"origem da nota\"",
|
||||||
"show-options": "Mostrar página de configurações",
|
"show-options": "Abrir página de configurações",
|
||||||
"show-revisions": "Exibe diálogo de revisões de nota",
|
"show-revisions": "Exibe diálogo \"revisões de nota\"",
|
||||||
"show-recent-changes": "Exibe o diálogo de alterações recentes",
|
"show-recent-changes": "Exibe o diálogo \"alterações recentes\"",
|
||||||
"show-sql-console": "Exibe a página do console SQL",
|
"show-sql-console": "Exibe a página \"consola SQL\"",
|
||||||
"show-backend-log": "Exibe a página do backend",
|
"show-backend-log": "Exibe a página \"registo do backend\"",
|
||||||
"show-help": "Exibir Ajuda integrada / colinha",
|
"show-help": "Exibir o guia de utilizador integrado",
|
||||||
"show-cheatsheet": "Exibir um modal com operações comuns de teclado",
|
"show-cheatsheet": "Exibir um modal com atalhos de teclado",
|
||||||
"text-note-operations": "Operações de nota de texto",
|
"text-note-operations": "Operações de nota de texto",
|
||||||
"add-link-to-text": "Abrir diálogo e adicionar ligação ao texto",
|
"add-link-to-text": "Abrir diálogo para adicionar ligação ao texto",
|
||||||
"follow-link-under-cursor": "Seguir a ligação sob o cursor",
|
"follow-link-under-cursor": "Seguir a ligação sob o cursor",
|
||||||
"insert-date-and-time-to-text": "Inserir data e hora atual no texto",
|
"insert-date-and-time-to-text": "Inserir data e hora atual no texto",
|
||||||
"paste-markdown-into-text": "Colar Markdown da área de transferência na nota de texto",
|
"paste-markdown-into-text": "Colar Markdown da área de transferência na nota de texto",
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ vi.mock("../../services/ws.js", () => ({
|
|||||||
default: {
|
default: {
|
||||||
sendMessageToAllClients: vi.fn(),
|
sendMessageToAllClients: vi.fn(),
|
||||||
sendTransactionEntityChangesToAllClients: vi.fn(),
|
sendTransactionEntityChangesToAllClients: vi.fn(),
|
||||||
setLastSyncedPush: vi.fn()
|
setLastSyncedPush: vi.fn(),
|
||||||
|
syncFailed() {}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ async function loginWithSession(app: Application) {
|
|||||||
.post("/login")
|
.post("/login")
|
||||||
.send({ password: "demo1234" })
|
.send({ password: "demo1234" })
|
||||||
.expect(302);
|
.expect(302);
|
||||||
|
|
||||||
const setCookieHeader = response.headers["set-cookie"][0];
|
const setCookieHeader = response.headers["set-cookie"][0];
|
||||||
expect(setCookieHeader).toBeTruthy();
|
expect(setCookieHeader).toBeTruthy();
|
||||||
return setCookieHeader;
|
return setCookieHeader;
|
||||||
@@ -91,14 +92,14 @@ async function loginWithSession(app: Application) {
|
|||||||
async function getCsrfToken(app: Application, sessionCookie: string) {
|
async function getCsrfToken(app: Application, sessionCookie: string) {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.get("/")
|
.get("/")
|
||||||
|
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const csrfTokenMatch = response.text.match(/csrfToken: '([^']+)'/);
|
const csrfTokenMatch = response.text.match(/csrfToken: '([^']+)'/);
|
||||||
if (csrfTokenMatch) {
|
if (csrfTokenMatch) {
|
||||||
return csrfTokenMatch[1];
|
return csrfTokenMatch[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("CSRF token not found in response");
|
throw new Error("CSRF token not found in response");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
expect(response.body).toHaveProperty('sessions');
|
expect(response.body).toHaveProperty('sessions');
|
||||||
expect(Array.isArray(response.body.sessions)).toBe(true);
|
expect(Array.isArray(response.body.sessions)).toBe(true);
|
||||||
|
|
||||||
if (response.body.sessions.length > 0) {
|
if (response.body.sessions.length > 0) {
|
||||||
expect(response.body.sessions[0]).toMatchObject({
|
expect(response.body.sessions[0]).toMatchObject({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
@@ -171,18 +172,18 @@ describe("LLM API Tests", () => {
|
|||||||
// Create a chat first if we don't have one
|
// Create a chat first if we don't have one
|
||||||
const createResponse = await supertest(app)
|
const createResponse = await supertest(app)
|
||||||
.post("/api/llm/chat")
|
.post("/api/llm/chat")
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
title: "Test Retrieval Chat"
|
title: "Test Retrieval Chat"
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
createdChatId = createResponse.body.id;
|
createdChatId = createResponse.body.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.get(`/api/llm/chat/${createdChatId}`)
|
.get(`/api/llm/chat/${createdChatId}`)
|
||||||
|
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
expect(response.body).toMatchObject({
|
expect(response.body).toMatchObject({
|
||||||
@@ -202,7 +203,7 @@ describe("LLM API Tests", () => {
|
|||||||
title: "Test Update Chat"
|
title: "Test Update Chat"
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
createdChatId = createResponse.body.id;
|
createdChatId = createResponse.body.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +225,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should return 404 for non-existent chat session", async () => {
|
it("should return 404 for non-existent chat session", async () => {
|
||||||
await supertest(app)
|
await supertest(app)
|
||||||
.get("/api/llm/chat/nonexistent-chat-id")
|
.get("/api/llm/chat/nonexistent-chat-id")
|
||||||
|
|
||||||
.expect(404);
|
.expect(404);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -240,7 +241,7 @@ describe("LLM API Tests", () => {
|
|||||||
title: "Message Test Chat"
|
title: "Message Test Chat"
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
testChatId = createResponse.body.id;
|
testChatId = createResponse.body.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -260,10 +261,10 @@ describe("LLM API Tests", () => {
|
|||||||
// The response depends on whether AI is actually configured
|
// The response depends on whether AI is actually configured
|
||||||
// We should get either a successful response or an error about AI not being configured
|
// We should get either a successful response or an error about AI not being configured
|
||||||
expect([200, 400, 500]).toContain(response.status);
|
expect([200, 400, 500]).toContain(response.status);
|
||||||
|
|
||||||
// All responses should have some body
|
// All responses should have some body
|
||||||
expect(response.body).toBeDefined();
|
expect(response.body).toBeDefined();
|
||||||
|
|
||||||
// Either success with response or error
|
// Either success with response or error
|
||||||
if (response.body.response) {
|
if (response.body.response) {
|
||||||
expect(response.body).toMatchObject({
|
expect(response.body).toMatchObject({
|
||||||
@@ -310,10 +311,10 @@ describe("LLM API Tests", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Reset all mocks
|
// Reset all mocks
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
|
||||||
// Import options service to access mock
|
// Import options service to access mock
|
||||||
const options = (await import("../../services/options.js")).default;
|
const options = (await import("../../services/options.js")).default;
|
||||||
|
|
||||||
// Setup default mock behaviors
|
// Setup default mock behaviors
|
||||||
(options.getOptionBool as any).mockReturnValue(true); // AI enabled
|
(options.getOptionBool as any).mockReturnValue(true); // AI enabled
|
||||||
mockAiServiceManager.getOrCreateAnyService.mockResolvedValue({});
|
mockAiServiceManager.getOrCreateAnyService.mockResolvedValue({});
|
||||||
@@ -321,7 +322,7 @@ describe("LLM API Tests", () => {
|
|||||||
model: 'test-model',
|
model: 'test-model',
|
||||||
provider: 'test-provider'
|
provider: 'test-provider'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a fresh chat for each test
|
// Create a fresh chat for each test
|
||||||
const mockChat = {
|
const mockChat = {
|
||||||
id: 'streaming-test-chat',
|
id: 'streaming-test-chat',
|
||||||
@@ -331,15 +332,15 @@ describe("LLM API Tests", () => {
|
|||||||
};
|
};
|
||||||
mockChatStorage.createChat.mockResolvedValue(mockChat);
|
mockChatStorage.createChat.mockResolvedValue(mockChat);
|
||||||
mockChatStorage.getChat.mockResolvedValue(mockChat);
|
mockChatStorage.getChat.mockResolvedValue(mockChat);
|
||||||
|
|
||||||
const createResponse = await supertest(app)
|
const createResponse = await supertest(app)
|
||||||
.post("/api/llm/chat")
|
.post("/api/llm/chat")
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
title: "Streaming Test Chat"
|
title: "Streaming Test Chat"
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
testChatId = createResponse.body.id;
|
testChatId = createResponse.body.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -358,7 +359,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Tell me a short story",
|
content: "Tell me a short story",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -372,17 +373,17 @@ describe("LLM API Tests", () => {
|
|||||||
success: true,
|
success: true,
|
||||||
message: "Streaming initiated successfully"
|
message: "Streaming initiated successfully"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify WebSocket messages were sent
|
// Verify WebSocket messages were sent
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
chatNoteId: testChatId,
|
chatNoteId: testChatId,
|
||||||
thinking: undefined
|
thinking: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify streaming chunks were sent
|
// Verify streaming chunks were sent
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -390,7 +391,7 @@ describe("LLM API Tests", () => {
|
|||||||
content: 'Hello',
|
content: 'Hello',
|
||||||
done: false
|
done: false
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
chatNoteId: testChatId,
|
chatNoteId: testChatId,
|
||||||
@@ -402,7 +403,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should handle empty content for streaming", async () => {
|
it("should handle empty content for streaming", async () => {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "",
|
content: "",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -419,7 +420,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should handle whitespace-only content for streaming", async () => {
|
it("should handle whitespace-only content for streaming", async () => {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: " \n\t ",
|
content: " \n\t ",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -436,7 +437,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should handle invalid chat ID for streaming", async () => {
|
it("should handle invalid chat ID for streaming", async () => {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post("/api/llm/chat/invalid-chat-id/messages/stream")
|
.post("/api/llm/chat/invalid-chat-id/messages/stream")
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Hello",
|
content: "Hello",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -467,7 +468,7 @@ describe("LLM API Tests", () => {
|
|||||||
// Verify mention content is included
|
// Verify mention content is included
|
||||||
expect(input.query).toContain('Tell me about this note');
|
expect(input.query).toContain('Tell me about this note');
|
||||||
expect(input.query).toContain('Root note content for testing');
|
expect(input.query).toContain('Root note content for testing');
|
||||||
|
|
||||||
const callback = input.streamCallback;
|
const callback = input.streamCallback;
|
||||||
await callback('The root note contains', false, {});
|
await callback('The root note contains', false, {});
|
||||||
await callback(' important information.', true, {});
|
await callback(' important information.', true, {});
|
||||||
@@ -475,7 +476,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Tell me about this note",
|
content: "Tell me about this note",
|
||||||
useAdvancedContext: true,
|
useAdvancedContext: true,
|
||||||
@@ -493,10 +494,10 @@ describe("LLM API Tests", () => {
|
|||||||
success: true,
|
success: true,
|
||||||
message: "Streaming initiated successfully"
|
message: "Streaming initiated successfully"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify thinking message was sent
|
// Verify thinking message was sent
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -517,7 +518,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "What is the meaning of life?",
|
content: "What is the meaning of life?",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -525,10 +526,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify thinking messages
|
// Verify thinking messages
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -536,7 +537,7 @@ describe("LLM API Tests", () => {
|
|||||||
thinking: 'Analyzing the question...',
|
thinking: 'Analyzing the question...',
|
||||||
done: false
|
done: false
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
chatNoteId: testChatId,
|
chatNoteId: testChatId,
|
||||||
@@ -564,7 +565,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "What is 2 + 2?",
|
content: "What is 2 + 2?",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -572,10 +573,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify tool execution message
|
// Verify tool execution message
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -597,7 +598,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "This will fail",
|
content: "This will fail",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -605,10 +606,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200); // Still returns 200
|
expect(response.status).toBe(200); // Still returns 200
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify error message was sent via WebSocket
|
// Verify error message was sent via WebSocket
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -625,7 +626,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Hello AI",
|
content: "Hello AI",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -633,10 +634,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify error message about AI being disabled
|
// Verify error message about AI being disabled
|
||||||
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
expect(ws.sendMessageToAllClients).toHaveBeenCalledWith({
|
||||||
type: 'llm-stream',
|
type: 'llm-stream',
|
||||||
@@ -655,7 +656,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
await supertest(app)
|
await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Save this response",
|
content: "Save this response",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -680,10 +681,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Send multiple requests rapidly
|
// Send multiple requests rapidly
|
||||||
const promises = Array.from({ length: 3 }, (_, i) =>
|
const promises = Array.from({ length: 3 }, (_, i) =>
|
||||||
supertest(app)
|
supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: `Request ${i + 1}`,
|
content: `Request ${i + 1}`,
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -692,7 +693,7 @@ describe("LLM API Tests", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const responses = await Promise.all(promises);
|
const responses = await Promise.all(promises);
|
||||||
|
|
||||||
// All should succeed
|
// All should succeed
|
||||||
responses.forEach(response => {
|
responses.forEach(response => {
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@@ -716,7 +717,7 @@ describe("LLM API Tests", () => {
|
|||||||
|
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
.post(`/api/llm/chat/${testChatId}/messages/stream`)
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
content: "Generate large response",
|
content: "Generate large response",
|
||||||
useAdvancedContext: false,
|
useAdvancedContext: false,
|
||||||
@@ -724,10 +725,10 @@ describe("LLM API Tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
|
||||||
// Import ws service to access mock
|
// Import ws service to access mock
|
||||||
const ws = (await import("../../services/ws.js")).default;
|
const ws = (await import("../../services/ws.js")).default;
|
||||||
|
|
||||||
// Verify multiple chunks were sent
|
// Verify multiple chunks were sent
|
||||||
const streamCalls = (ws.sendMessageToAllClients as any).mock.calls.filter(
|
const streamCalls = (ws.sendMessageToAllClients as any).mock.calls.filter(
|
||||||
call => call[0].type === 'llm-stream' && call[0].content
|
call => call[0].type === 'llm-stream' && call[0].content
|
||||||
@@ -741,7 +742,7 @@ describe("LLM API Tests", () => {
|
|||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post("/api/llm/chat")
|
.post("/api/llm/chat")
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
|
|
||||||
.send('{ invalid json }');
|
.send('{ invalid json }');
|
||||||
|
|
||||||
expect([400, 500]).toContain(response.status);
|
expect([400, 500]).toContain(response.status);
|
||||||
@@ -750,7 +751,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should handle missing required fields", async () => {
|
it("should handle missing required fields", async () => {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post("/api/llm/chat")
|
.post("/api/llm/chat")
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
// Missing required fields
|
// Missing required fields
|
||||||
});
|
});
|
||||||
@@ -762,7 +763,7 @@ describe("LLM API Tests", () => {
|
|||||||
it("should handle invalid parameter types", async () => {
|
it("should handle invalid parameter types", async () => {
|
||||||
const response = await supertest(app)
|
const response = await supertest(app)
|
||||||
.post("/api/llm/chat")
|
.post("/api/llm/chat")
|
||||||
|
|
||||||
.send({
|
.send({
|
||||||
title: "Test Chat",
|
title: "Test Chat",
|
||||||
temperature: "invalid", // Should be number
|
temperature: "invalid", // Should be number
|
||||||
@@ -786,4 +787,4 @@ describe("LLM API Tests", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
|
|||||||
"allowedHtmlTags",
|
"allowedHtmlTags",
|
||||||
"redirectBareDomain",
|
"redirectBareDomain",
|
||||||
"showLoginInShareTheme",
|
"showLoginInShareTheme",
|
||||||
|
"shareSubtree",
|
||||||
|
"sharePath",
|
||||||
"splitEditorOrientation",
|
"splitEditorOrientation",
|
||||||
"seenCallToActions",
|
"seenCallToActions",
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ const GET = "get",
|
|||||||
DEL = "delete";
|
DEL = "delete";
|
||||||
|
|
||||||
function register(app: express.Application) {
|
function register(app: express.Application) {
|
||||||
|
|
||||||
route(GET, "/", [auth.checkAuth, csrfMiddleware], indexRoute.index);
|
route(GET, "/", [auth.checkAuth, csrfMiddleware], indexRoute.index);
|
||||||
route(GET, "/login", [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage);
|
route(GET, "/login", [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage);
|
||||||
route(GET, "/set-password", [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPasswordPage);
|
route(GET, "/set-password", [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPasswordPage);
|
||||||
|
|||||||
@@ -37,9 +37,26 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
|
|||||||
// Check if any note has the #shareRoot label
|
// Check if any note has the #shareRoot label
|
||||||
const shareRootNotes = attributes.getNotesWithLabel("shareRoot");
|
const shareRootNotes = attributes.getNotesWithLabel("shareRoot");
|
||||||
if (shareRootNotes.length === 0) {
|
if (shareRootNotes.length === 0) {
|
||||||
|
// should this be a translation string?
|
||||||
res.status(404).json({ message: "Share root not found. Please set up a note with #shareRoot label first." });
|
res.status(404).json({ message: "Share root not found. Please set up a note with #shareRoot label first." });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the configured share path
|
||||||
|
const sharePath = options.getOption("sharePath") || '/share';
|
||||||
|
|
||||||
|
// Check if we're already at the share path to prevent redirect loops
|
||||||
|
if (req.path === sharePath || req.path.startsWith(`${sharePath}/`)) {
|
||||||
|
log.info(`checkAuth: Already at share path, skipping redirect. Path: ${req.path}, SharePath: ${sharePath}`);
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect to the share path
|
||||||
|
log.info(`checkAuth: Redirecting to share path. From: ${req.path}, To: ${sharePath}`);
|
||||||
|
res.redirect(`${sharePath}/`);
|
||||||
|
} else {
|
||||||
|
res.redirect("login");
|
||||||
}
|
}
|
||||||
res.redirect(hasRedirectBareDomain ? "share" : "login");
|
res.redirect(hasRedirectBareDomain ? "share" : "login");
|
||||||
} else if (currentTotpStatus !== lastAuthState.totpEnabled || currentSsoStatus !== lastAuthState.ssoEnabled) {
|
} else if (currentTotpStatus !== lastAuthState.totpEnabled || currentSsoStatus !== lastAuthState.ssoEnabled) {
|
||||||
@@ -81,15 +98,6 @@ function checkApiAuthOrElectron(req: Request, res: Response, next: NextFunction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkApiAuth(req: Request, res: Response, next: NextFunction) {
|
|
||||||
if (!req.session.loggedIn && !noAuthentication) {
|
|
||||||
console.warn(`Missing session with ID '${req.sessionID}'.`);
|
|
||||||
reject(req, res, "Logged in session not found");
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAppInitialized(req: Request, res: Response, next: NextFunction) {
|
function checkAppInitialized(req: Request, res: Response, next: NextFunction) {
|
||||||
if (!sqlInit.isDbInitialized()) {
|
if (!sqlInit.isDbInitialized()) {
|
||||||
res.redirect("setup");
|
res.redirect("setup");
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ export default [
|
|||||||
{ type: "label", name: "shareDisallowRobotIndexing" },
|
{ type: "label", name: "shareDisallowRobotIndexing" },
|
||||||
{ type: "label", name: "shareCredentials" },
|
{ type: "label", name: "shareCredentials" },
|
||||||
{ type: "label", name: "shareIndex" },
|
{ type: "label", name: "shareIndex" },
|
||||||
|
{ type: "label", name: "shareHtmlLocation" },
|
||||||
{ type: "label", name: "displayRelations" },
|
{ type: "label", name: "displayRelations" },
|
||||||
{ type: "label", name: "hideRelations" },
|
{ type: "label", name: "hideRelations" },
|
||||||
{ type: "label", name: "titleTemplate", isDangerous: true },
|
{ type: "label", name: "titleTemplate", isDangerous: true },
|
||||||
@@ -105,6 +106,7 @@ export default [
|
|||||||
{ type: "relation", name: "renderNote", isDangerous: true },
|
{ type: "relation", name: "renderNote", isDangerous: true },
|
||||||
{ type: "relation", name: "shareCss" },
|
{ type: "relation", name: "shareCss" },
|
||||||
{ type: "relation", name: "shareJs" },
|
{ type: "relation", name: "shareJs" },
|
||||||
|
{ type: "relation", name: "shareHtml" },
|
||||||
{ type: "relation", name: "shareTemplate" },
|
{ type: "relation", name: "shareTemplate" },
|
||||||
{ type: "relation", name: "shareFavicon" }
|
{ type: "relation", name: "shareFavicon" }
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import { changeLanguage } from "./i18n.js";
|
|||||||
import { deferred } from "./utils.js";
|
import { deferred } from "./utils.js";
|
||||||
|
|
||||||
describe("Hidden Subtree", () => {
|
describe("Hidden Subtree", () => {
|
||||||
describe("Launcher movement persistence", () => {
|
beforeAll(async () => {
|
||||||
beforeAll(async () => {
|
sql_init.initializeDb();
|
||||||
sql_init.initializeDb();
|
await sql_init.dbReady;
|
||||||
await sql_init.dbReady;
|
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
|
||||||
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
|
});
|
||||||
});
|
|
||||||
|
|
||||||
|
describe("Launcher movement persistence", () => {
|
||||||
it("should persist launcher movement between visible and available after integrity check", () => {
|
it("should persist launcher movement between visible and available after integrity check", () => {
|
||||||
// Move backend log to visible launchers.
|
// Move backend log to visible launchers.
|
||||||
const backendLogBranch = becca.getBranchFromChildAndParent("_lbBackendLog", "_lbAvailableLaunchers");
|
const backendLogBranch = becca.getBranchFromChildAndParent("_lbBackendLog", "_lbAvailableLaunchers");
|
||||||
@@ -119,4 +119,14 @@ describe("Hidden Subtree", () => {
|
|||||||
await done;
|
await done;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Hidden subtree", () => {
|
||||||
|
it("cleans up exclude from note map at the root", async () => {
|
||||||
|
const hiddenSubtree = becca.getNoteOrThrow("_hidden");
|
||||||
|
cls.init(() => hiddenSubtree.addLabel("excludeFromNoteMap"));
|
||||||
|
expect(hiddenSubtree.hasLabel("excludeFromNoteMap")).toBeTruthy();
|
||||||
|
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
|
||||||
|
expect(hiddenSubtree.hasLabel("excludeFromNoteMap")).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ function buildHiddenSubtreeDefinition(helpSubtree: HiddenSubtreeItem[]): HiddenS
|
|||||||
// we want to keep the hidden subtree always last, otherwise there will be problems with e.g., keyboard navigation
|
// we want to keep the hidden subtree always last, otherwise there will be problems with e.g., keyboard navigation
|
||||||
// over tree when it's in the middle
|
// over tree when it's in the middle
|
||||||
notePosition: 999_999_999,
|
notePosition: 999_999_999,
|
||||||
|
enforceAttributes: true,
|
||||||
attributes: [
|
attributes: [
|
||||||
{ type: "label", name: "excludeFromNoteMap", isInheritable: true },
|
|
||||||
{ type: "label", name: "docName", value: "hidden" }
|
{ type: "label", name: "docName", value: "hidden" }
|
||||||
],
|
],
|
||||||
children: [
|
children: [
|
||||||
@@ -441,6 +441,15 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enforce attribute structure if needed.
|
||||||
|
if (item.enforceAttributes) {
|
||||||
|
for (const attribute of note.getAttributes()) {
|
||||||
|
if (!attrs.some(a => a.name === attribute.name)) {
|
||||||
|
attribute.markAsDeleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const attr of attrs) {
|
for (const attr of attrs) {
|
||||||
const attrId = note.noteId + "_" + attr.type.charAt(0) + attr.name;
|
const attrId = note.noteId + "_" + attr.type.charAt(0) + attr.name;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
import sanitizeHtml from "sanitize-html";
|
import sanitizeHtml from "sanitize-html";
|
||||||
import { sanitizeUrl } from "@braintree/sanitize-url";
|
import { sanitizeUrl } from "@braintree/sanitize-url";
|
||||||
import optionService from "./options.js";
|
import optionService from "./options.js";
|
||||||
import { SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
|
import { ALLOWED_PROTOCOLS, SANITIZER_DEFAULT_ALLOWED_TAGS } from "@triliumnext/commons";
|
||||||
|
|
||||||
// Be consistent with `ALLOWED_PROTOCOLS` in `src\public\app\services\link.js`
|
|
||||||
// TODO: Deduplicate with client once we can.
|
|
||||||
export const ALLOWED_PROTOCOLS = [
|
|
||||||
'http', 'https', 'ftp', 'ftps', 'mailto', 'data', 'evernote', 'file', 'facetime', 'gemini', 'git',
|
|
||||||
'gopher', 'imap', 'irc', 'irc6', 'jabber', 'jar', 'lastfm', 'ldap', 'ldaps', 'magnet', 'message',
|
|
||||||
'mumble', 'nfs', 'onenote', 'pop', 'rmi', 's3', 'sftp', 'skype', 'sms', 'spotify', 'steam', 'svn', 'udp',
|
|
||||||
'view-source', 'vlc', 'vnc', 'ws', 'wss', 'xmpp', 'jdbc', 'slack', 'tel', 'smb', 'zotero', 'geo',
|
|
||||||
'mid'
|
|
||||||
];
|
|
||||||
|
|
||||||
// intended mainly as protection against XSS via import
|
// intended mainly as protection against XSS via import
|
||||||
// secondarily, it (partly) protects against "CSS takeover"
|
// secondarily, it (partly) protects against "CSS takeover"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
import { StreamProcessor, createStreamHandler, processProviderStream, extractStreamStats, performProviderHealthCheck } from './stream_handler.js';
|
import { StreamProcessor, createStreamHandler, processProviderStream, extractStreamStats, performProviderHealthCheck } from './stream_handler.js';
|
||||||
import type { StreamProcessingOptions, StreamChunk, ProviderStreamOptions } from './stream_handler.js';
|
import type { StreamProcessingOptions, StreamChunk } from './stream_handler.js';
|
||||||
|
|
||||||
// Mock the log module
|
// Mock the log module
|
||||||
vi.mock('../../log.js', () => ({
|
vi.mock('../../log.js', () => ({
|
||||||
@@ -86,7 +86,7 @@ describe('StreamProcessor', () => {
|
|||||||
|
|
||||||
it('should handle callback errors gracefully', async () => {
|
it('should handle callback errors gracefully', async () => {
|
||||||
const errorCallback = vi.fn().mockRejectedValue(new Error('Callback error'));
|
const errorCallback = vi.fn().mockRejectedValue(new Error('Callback error'));
|
||||||
|
|
||||||
// Should not throw
|
// Should not throw
|
||||||
await expect(StreamProcessor.sendChunkToCallback(errorCallback, 'test', false, {}, 1))
|
await expect(StreamProcessor.sendChunkToCallback(errorCallback, 'test', false, {}, 1))
|
||||||
.resolves.toBeUndefined();
|
.resolves.toBeUndefined();
|
||||||
@@ -127,7 +127,7 @@ describe('StreamProcessor', () => {
|
|||||||
|
|
||||||
it('should handle final callback errors gracefully', async () => {
|
it('should handle final callback errors gracefully', async () => {
|
||||||
const errorCallback = vi.fn().mockRejectedValue(new Error('Final callback error'));
|
const errorCallback = vi.fn().mockRejectedValue(new Error('Final callback error'));
|
||||||
|
|
||||||
await expect(StreamProcessor.sendFinalCallback(errorCallback, 'test'))
|
await expect(StreamProcessor.sendFinalCallback(errorCallback, 'test'))
|
||||||
.resolves.toBeUndefined();
|
.resolves.toBeUndefined();
|
||||||
});
|
});
|
||||||
@@ -297,8 +297,8 @@ describe('processProviderStream', () => {
|
|||||||
it('should handle tool calls in stream', async () => {
|
it('should handle tool calls in stream', async () => {
|
||||||
const chunks = [
|
const chunks = [
|
||||||
{ message: { content: 'Using tool...' } },
|
{ message: { content: 'Using tool...' } },
|
||||||
{
|
{
|
||||||
message: {
|
message: {
|
||||||
tool_calls: [
|
tool_calls: [
|
||||||
{ id: 'call_1', function: { name: 'calculator', arguments: '{"x": 5}' } }
|
{ id: 'call_1', function: { name: 'calculator', arguments: '{"x": 5}' } }
|
||||||
]
|
]
|
||||||
@@ -573,8 +573,8 @@ describe('Streaming edge cases and concurrency', () => {
|
|||||||
it('should handle mixed content and tool calls', async () => {
|
it('should handle mixed content and tool calls', async () => {
|
||||||
const chunks = [
|
const chunks = [
|
||||||
{ message: { content: 'Let me calculate that...' } },
|
{ message: { content: 'Let me calculate that...' } },
|
||||||
{
|
{
|
||||||
message: {
|
message: {
|
||||||
content: '',
|
content: '',
|
||||||
tool_calls: [{ id: '1', function: { name: 'calc' } }]
|
tool_calls: [{ id: '1', function: { name: 'calc' } }]
|
||||||
}
|
}
|
||||||
@@ -599,4 +599,4 @@ describe('Streaming edge cases and concurrency', () => {
|
|||||||
expect(result.completeText).toBe('Let me calculate that...The answer is 42.');
|
expect(result.completeText).toBe('Let me calculate that...The answer is 42.');
|
||||||
expect(result.toolCalls).toHaveLength(1);
|
expect(result.toolCalls).toHaveLength(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -196,8 +196,10 @@ const defaultOptions: DefaultOption[] = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Share settings
|
// Share settings
|
||||||
|
{ name: "sharePath", value: "/share", isSynced: true },
|
||||||
{ name: "redirectBareDomain", value: "false", isSynced: true },
|
{ name: "redirectBareDomain", value: "false", isSynced: true },
|
||||||
{ name: "showLoginInShareTheme", value: "false", isSynced: true },
|
{ name: "showLoginInShareTheme", value: "false", isSynced: true },
|
||||||
|
{ name: "shareSubtree", value: "false", isSynced: true },
|
||||||
|
|
||||||
// AI Options
|
// AI Options
|
||||||
{ name: "aiEnabled", value: "false", isSynced: true },
|
{ name: "aiEnabled", value: "false", isSynced: true },
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export function getContent(note: SNote) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (note.type === "text") {
|
if (note.type === "text") {
|
||||||
renderText(result, note);
|
renderText(result, note, relativePath);
|
||||||
} else if (note.type === "code") {
|
} else if (note.type === "code") {
|
||||||
renderCode(result);
|
renderCode(result);
|
||||||
} else if (note.type === "mermaid") {
|
} else if (note.type === "mermaid") {
|
||||||
@@ -106,10 +106,10 @@ function renderText(result: Result, note: SNote) {
|
|||||||
|
|
||||||
if (result.content.includes(`<span class="math-tex">`)) {
|
if (result.content.includes(`<span class="math-tex">`)) {
|
||||||
result.header += `
|
result.header += `
|
||||||
<script src="../${assetPath}/node_modules/katex/dist/katex.min.js"></script>
|
<script src="${relativePath}${assetPath}/node_modules/katex/dist/katex.min.js"></script>
|
||||||
<link rel="stylesheet" href="../${assetPath}/node_modules/katex/dist/katex.min.css">
|
<link rel="stylesheet" href="${relativePath}${assetPath}/node_modules/katex/dist/katex.min.css">
|
||||||
<script src="../${assetPath}/node_modules/katex/dist/contrib/auto-render.min.js"></script>
|
<script src="${relativePath}${assetPath}/node_modules/katex/dist/contrib/auto-render.min.js"></script>
|
||||||
<script src="../${assetPath}/node_modules/katex/dist/contrib/mhchem.min.js"></script>
|
<script src="${relativePath}${assetPath}/node_modules/katex/dist/contrib/mhchem.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
renderMathInElement(document.getElementById('content'));
|
renderMathInElement(document.getElementById('content'));
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ describe("Share API test", () => {
|
|||||||
let cannotSetHeadersCount = 0;
|
let cannotSetHeadersCount = 0;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
const buildApp = (await import("../app.js")).default;
|
const buildApp = (await import("../app.js")).default;
|
||||||
app = await buildApp();
|
app = await buildApp();
|
||||||
app.use((err: unknown, req: Request, res: Response, next: NextFunction) => {
|
app.use((err: unknown, req: Request, res: Response, next: NextFunction) => {
|
||||||
@@ -43,3 +44,39 @@ describe("Share API test", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Share Routes - Asset Path Calculation", () => {
|
||||||
|
it("should calculate correct relative path depth for different share paths", () => {
|
||||||
|
// Helper function to simulate the path depth calculation
|
||||||
|
const calculateRelativePath = (sharePath: string) => {
|
||||||
|
const pathDepth = sharePath.split('/').filter(segment => segment.length > 0).length;
|
||||||
|
return '../'.repeat(pathDepth);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test single level path
|
||||||
|
expect(calculateRelativePath("/share")).toBe("../");
|
||||||
|
|
||||||
|
// Test double level path
|
||||||
|
expect(calculateRelativePath("/sharePath/test")).toBe("../../");
|
||||||
|
|
||||||
|
// Test triple level path
|
||||||
|
expect(calculateRelativePath("/my/custom/share")).toBe("../../../");
|
||||||
|
|
||||||
|
// Test root path
|
||||||
|
expect(calculateRelativePath("/")).toBe("");
|
||||||
|
|
||||||
|
// Test path with trailing slash
|
||||||
|
expect(calculateRelativePath("/share/")).toBe("../");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle normalized share paths correctly", () => {
|
||||||
|
const calculateRelativePath = (sharePath: string) => {
|
||||||
|
const pathDepth = sharePath.split('/').filter(segment => segment.length > 0).length;
|
||||||
|
return '../'.repeat(pathDepth);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test the examples from the original TODO comment
|
||||||
|
expect(calculateRelativePath("/sharePath")).toBe("../");
|
||||||
|
expect(calculateRelativePath("/sharePath/test")).toBe("../../");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import safeCompare from "safe-compare";
|
import safeCompare from "safe-compare";
|
||||||
|
|
||||||
import type { Request, Response, Router } from "express";
|
import type { Request, Response, Router, NextFunction } from "express";
|
||||||
|
|
||||||
import shaca from "./shaca/shaca.js";
|
import shaca from "./shaca/shaca.js";
|
||||||
import shacaLoader from "./shaca/shaca_loader.js";
|
import shacaLoader from "./shaca/shaca_loader.js";
|
||||||
@@ -139,17 +139,21 @@ function renderImageAttachment(image: SNote, res: Response, attachmentName: stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
function register(router: Router) {
|
function register(router: Router) {
|
||||||
function renderNote(note: SNote, req: Request, res: Response) {
|
function renderNote(note: SNote, req: Request, res: Response) {
|
||||||
|
// Calculate the correct relative path depth based on the current request path
|
||||||
|
// We need to go up one level for each path segment in the request URL
|
||||||
|
const pathSegments = req.path.split('/').filter(segment => segment.length > 0);
|
||||||
|
const relativePath = '../'.repeat(pathSegments.length);
|
||||||
|
|
||||||
if (!note) {
|
if (!note) {
|
||||||
console.log("Unable to find note ", note);
|
console.log("Unable to find note ", note);
|
||||||
res.status(404);
|
res.status(404);
|
||||||
renderDefault(res, "404");
|
renderDefault(res, "404", { relativePath, t });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkNoteAccess(note.noteId, req, res)) {
|
if (!checkNoteAccess(note.noteId, req, res)) {
|
||||||
requestCredentials(res);
|
requestCredentials(res);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,18 +165,20 @@ function register(router: Router) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { header, content, isEmpty } = contentRenderer.getContent(note);
|
const { header, content, isEmpty } = contentRenderer.getContent(note, relativePath);
|
||||||
const subRoot = getSharedSubTreeRoot(note);
|
const subRoot = getSharedSubTreeRoot(note);
|
||||||
const showLoginInShareTheme = options.getOption("showLoginInShareTheme");
|
const showLoginInShareTheme = options.getOption("showLoginInShareTheme");
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
note,
|
note,
|
||||||
header,
|
header,
|
||||||
content,
|
content,
|
||||||
isEmpty,
|
isEmpty,
|
||||||
subRoot,
|
subRoot,
|
||||||
assetPath: isDev ? assetPath : `../${assetPath}`,
|
assetPath: isDev ? assetPath : `${relativePath}${assetPath}`,
|
||||||
assetUrlFragment,
|
assetUrlFragment,
|
||||||
appPath: isDev ? appPath : `../${appPath}`,
|
appPath: isDev ? appPath : `${relativePath}${appPath}`,
|
||||||
|
relativePath,
|
||||||
showLoginInShareTheme,
|
showLoginInShareTheme,
|
||||||
t,
|
t,
|
||||||
isDev
|
isDev
|
||||||
@@ -219,184 +225,165 @@ function register(router: Router) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get("/share/", (req, res) => {
|
// Dynamic dispatch middleware
|
||||||
if (req.path.substr(-1) !== "/") {
|
router.use((req: Request, res: Response, next: NextFunction) => {
|
||||||
res.redirect("../share/");
|
const sharePath = options.getOptionOrNull("sharePath") || "/share";
|
||||||
return;
|
// Only handle requests starting with sharePath
|
||||||
|
if (req.path === sharePath || req.path.startsWith(sharePath + "/")) {
|
||||||
|
// Remove sharePath prefix to get the remaining path
|
||||||
|
const subPath = req.path.slice(sharePath.length);
|
||||||
|
// Handle root path
|
||||||
|
if (subPath === "" || subPath === "/") {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
if (!shaca.shareRootNote) {
|
||||||
|
res.status(404).json({ message: "Share root not found" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
renderNote(shaca.shareRootNote, req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /:shareId
|
||||||
|
const shareIdMatch = subPath.match(/^\/([^/]+)$/);
|
||||||
|
if (shareIdMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const shareId = shareIdMatch[1];
|
||||||
|
const note = shaca.aliasToNote[shareId] || shaca.notes[shareId];
|
||||||
|
renderNote(note, req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/notes/:noteId
|
||||||
|
const apiNoteMatch = subPath.match(/^\/api\/notes\/([^/]+)$/);
|
||||||
|
if (apiNoteMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const noteId = apiNoteMatch[1];
|
||||||
|
let note: SNote | boolean;
|
||||||
|
if (!(note = checkNoteAccess(noteId, req, res))) return;
|
||||||
|
addNoIndexHeader(note, res);
|
||||||
|
res.json(note.getPojo());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/notes/:noteId/download
|
||||||
|
const apiNoteDownloadMatch = subPath.match(/^\/api\/notes\/([^/]+)\/download$/);
|
||||||
|
if (apiNoteDownloadMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const noteId = apiNoteDownloadMatch[1];
|
||||||
|
let note: SNote | boolean;
|
||||||
|
if (!(note = checkNoteAccess(noteId, req, res))) return;
|
||||||
|
addNoIndexHeader(note, res);
|
||||||
|
const filename = utils.formatDownloadTitle(note.title, note.type, note.mime);
|
||||||
|
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
|
||||||
|
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||||
|
res.setHeader("Content-Type", note.mime);
|
||||||
|
res.send(note.getContent());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/images/:noteId/:filename
|
||||||
|
const apiImageMatch = subPath.match(/^\/api\/images\/([^/]+)\/([^/]+)$/);
|
||||||
|
if (apiImageMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const noteId = apiImageMatch[1];
|
||||||
|
let image: SNote | boolean;
|
||||||
|
if (!(image = checkNoteAccess(noteId, req, res))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (image.type === "image") {
|
||||||
|
// normal image
|
||||||
|
res.set("Content-Type", image.mime);
|
||||||
|
addNoIndexHeader(image, res);
|
||||||
|
res.send(image.getContent());
|
||||||
|
} else if (image.type === "canvas") {
|
||||||
|
renderImageAttachment(image, res, "canvas-export.svg");
|
||||||
|
} else if (image.type === "mermaid") {
|
||||||
|
renderImageAttachment(image, res, "mermaid-export.svg");
|
||||||
|
} else if (image.type === "mindMap") {
|
||||||
|
renderImageAttachment(image, res, "mindmap-export.svg");
|
||||||
|
} else {
|
||||||
|
res.status(400).json({ message: "Requested note is not a shareable image" });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/attachments/:attachmentId/image/:filename
|
||||||
|
const apiAttachmentImageMatch = subPath.match(/^\/api\/attachments\/([^/]+)\/image\/([^/]+)$/);
|
||||||
|
if (apiAttachmentImageMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const attachmentId = apiAttachmentImageMatch[1];
|
||||||
|
let attachment: SAttachment | boolean;
|
||||||
|
if (!(attachment = checkAttachmentAccess(attachmentId, req, res))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attachment.role === "image") {
|
||||||
|
res.set("Content-Type", attachment.mime);
|
||||||
|
addNoIndexHeader(attachment.note, res);
|
||||||
|
res.send(attachment.getContent());
|
||||||
|
} else {
|
||||||
|
res.status(400).json({ message: "Requested attachment is not a shareable image" });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/attachments/:attachmentId/download
|
||||||
|
const apiAttachmentDownloadMatch = subPath.match(/^\/api\/attachments\/([^/]+)\/download$/);
|
||||||
|
if (apiAttachmentDownloadMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const attachmentId = apiAttachmentDownloadMatch[1];
|
||||||
|
let attachment: SAttachment | boolean;
|
||||||
|
if (!(attachment = checkAttachmentAccess(attachmentId, req, res))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addNoIndexHeader(attachment.note, res);
|
||||||
|
const filename = utils.formatDownloadTitle(attachment.title, null, attachment.mime);
|
||||||
|
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
|
||||||
|
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||||
|
res.setHeader("Content-Type", attachment.mime);
|
||||||
|
res.send(attachment.getContent());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/notes/:noteId/view
|
||||||
|
const apiNoteViewMatch = subPath.match(/^\/api\/notes\/([^/]+)\/view$/);
|
||||||
|
if (apiNoteViewMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const noteId = apiNoteViewMatch[1];
|
||||||
|
let note: SNote | boolean;
|
||||||
|
if (!(note = checkNoteAccess(noteId, req, res))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addNoIndexHeader(note, res);
|
||||||
|
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||||
|
res.setHeader("Content-Type", note.mime);
|
||||||
|
res.send(note.getContent());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle /api/notes 搜索
|
||||||
|
const apiNotesSearchMatch = subPath.match(/^\/api\/notes$/);
|
||||||
|
if (apiNotesSearchMatch) {
|
||||||
|
shacaLoader.ensureLoad();
|
||||||
|
const ancestorNoteId = req.query.ancestorNoteId ?? "_share";
|
||||||
|
if (typeof ancestorNoteId !== "string") {
|
||||||
|
res.status(400).json({ message: "'ancestorNoteId' parameter is mandatory." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// This will automatically return if no ancestorNoteId is provided and there is no shareIndex
|
||||||
|
if (!checkNoteAccess(ancestorNoteId, req, res)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { search } = req.query;
|
||||||
|
if (typeof search !== "string" || !search?.trim()) {
|
||||||
|
res.status(400).json({ message: "'search' parameter is mandatory." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const searchContext = new SearchContext({ ancestorNoteId: ancestorNoteId });
|
||||||
|
const searchResults = searchService.findResultsWithQuery(search, searchContext);
|
||||||
|
const filteredResults = searchResults.map((sr) => {
|
||||||
|
const fullNote = shaca.notes[sr.noteId];
|
||||||
|
const startIndex = sr.notePathArray.indexOf(ancestorNoteId);
|
||||||
|
const localPathArray = sr.notePathArray.slice(startIndex + 1).filter((id) => shaca.notes[id]);
|
||||||
|
const pathTitle = localPathArray.map((id) => shaca.notes[id].title).join(" / ");
|
||||||
|
return { id: fullNote.shareId, title: fullNote.title, score: sr.score, path: pathTitle };
|
||||||
|
});
|
||||||
|
res.json({ results: filteredResults });
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
next();
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
if (!shaca.shareRootNote) {
|
|
||||||
res.status(404).json({ message: "Share root note not found" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderNote(shaca.shareRootNote, req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get("/share/:shareId", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
const { shareId } = req.params;
|
|
||||||
|
|
||||||
const note = shaca.aliasToNote[shareId] || shaca.notes[shareId];
|
|
||||||
|
|
||||||
renderNote(note, req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get("/share/api/notes/:noteId", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
let note: SNote | boolean;
|
|
||||||
|
|
||||||
if (!(note = checkNoteAccess(req.params.noteId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addNoIndexHeader(note, res);
|
|
||||||
|
|
||||||
res.json(note.getPojo());
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get("/share/api/notes/:noteId/download", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
let note: SNote | boolean;
|
|
||||||
|
|
||||||
if (!(note = checkNoteAccess(req.params.noteId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addNoIndexHeader(note, res);
|
|
||||||
|
|
||||||
const filename = utils.formatDownloadTitle(note.title, note.type, note.mime);
|
|
||||||
|
|
||||||
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
|
|
||||||
|
|
||||||
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
||||||
res.setHeader("Content-Type", note.mime);
|
|
||||||
|
|
||||||
res.send(note.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
// :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
|
|
||||||
router.get("/share/api/images/:noteId/:filename", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
let image: SNote | boolean;
|
|
||||||
|
|
||||||
if (!(image = checkNoteAccess(req.params.noteId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.type === "image") {
|
|
||||||
// normal image
|
|
||||||
res.set("Content-Type", image.mime);
|
|
||||||
addNoIndexHeader(image, res);
|
|
||||||
res.send(image.getContent());
|
|
||||||
} else if (image.type === "canvas") {
|
|
||||||
renderImageAttachment(image, res, "canvas-export.svg");
|
|
||||||
} else if (image.type === "mermaid") {
|
|
||||||
renderImageAttachment(image, res, "mermaid-export.svg");
|
|
||||||
} else if (image.type === "mindMap") {
|
|
||||||
renderImageAttachment(image, res, "mindmap-export.svg");
|
|
||||||
} else {
|
|
||||||
res.status(400).json({ message: "Requested note is not a shareable image" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
|
|
||||||
router.get("/share/api/attachments/:attachmentId/image/:filename", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
let attachment: SAttachment | boolean;
|
|
||||||
|
|
||||||
if (!(attachment = checkAttachmentAccess(req.params.attachmentId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachment.role === "image") {
|
|
||||||
res.set("Content-Type", attachment.mime);
|
|
||||||
addNoIndexHeader(attachment.note, res);
|
|
||||||
res.send(attachment.getContent());
|
|
||||||
} else {
|
|
||||||
res.status(400).json({ message: "Requested attachment is not a shareable image" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get("/share/api/attachments/:attachmentId/download", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
let attachment: SAttachment | boolean;
|
|
||||||
|
|
||||||
if (!(attachment = checkAttachmentAccess(req.params.attachmentId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addNoIndexHeader(attachment.note, res);
|
|
||||||
|
|
||||||
const filename = utils.formatDownloadTitle(attachment.title, null, attachment.mime);
|
|
||||||
|
|
||||||
res.setHeader("Content-Disposition", utils.getContentDisposition(filename));
|
|
||||||
|
|
||||||
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
||||||
res.setHeader("Content-Type", attachment.mime);
|
|
||||||
|
|
||||||
res.send(attachment.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
// used for PDF viewing
|
|
||||||
router.get("/share/api/notes/:noteId/view", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
let note: SNote | boolean;
|
|
||||||
|
|
||||||
if (!(note = checkNoteAccess(req.params.noteId, req, res))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addNoIndexHeader(note, res);
|
|
||||||
|
|
||||||
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
||||||
res.setHeader("Content-Type", note.mime);
|
|
||||||
|
|
||||||
res.send(note.getContent());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Used for searching, require noteId so we know the subTreeRoot
|
|
||||||
router.get("/share/api/notes", (req, res) => {
|
|
||||||
shacaLoader.ensureLoad();
|
|
||||||
|
|
||||||
const ancestorNoteId = req.query.ancestorNoteId ?? "_share";
|
|
||||||
|
|
||||||
if (typeof ancestorNoteId !== "string") {
|
|
||||||
res.status(400).json({ message: "'ancestorNoteId' parameter is mandatory." });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will automatically return if no ancestorNoteId is provided and there is no shareIndex
|
|
||||||
if (!checkNoteAccess(ancestorNoteId, req, res)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { search } = req.query;
|
|
||||||
|
|
||||||
if (typeof search !== "string" || !search?.trim()) {
|
|
||||||
res.status(400).json({ message: "'search' parameter is mandatory." });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchContext = new SearchContext({ ancestorNoteId: ancestorNoteId });
|
|
||||||
const searchResults = searchService.findResultsWithQuery(search, searchContext);
|
|
||||||
const filteredResults = searchResults.map((sr) => {
|
|
||||||
const fullNote = shaca.notes[sr.noteId];
|
|
||||||
const startIndex = sr.notePathArray.indexOf(ancestorNoteId);
|
|
||||||
const localPathArray = sr.notePathArray.slice(startIndex + 1).filter((id) => shaca.notes[id]);
|
|
||||||
const pathTitle = localPathArray.map((id) => shaca.notes[id].title).join(" / ");
|
|
||||||
return { id: fullNote.shareId, title: fullNote.title, score: sr.score, path: pathTitle };
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({ results: filteredResults });
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import utils from "../services/utils.js";
|
import utils from "../services/utils.js";
|
||||||
import BNote from "../becca/entities/bnote.js";
|
import BNote from "../becca/entities/bnote.js";
|
||||||
import BAttribute from "../becca/entities/battribute.js";
|
import BAttribute from "../becca/entities/battribute.js";
|
||||||
|
import BBranch from "../becca/entities/bbranch.js";
|
||||||
|
|
||||||
type AttributeDefinitions = { [key in `#${string}`]: string; };
|
type AttributeDefinitions = { [key in `#${string}`]: string; };
|
||||||
type RelationDefinitions = { [key in `~${string}`]: string; };
|
type RelationDefinitions = { [key in `~${string}`]: string; };
|
||||||
@@ -9,6 +10,7 @@ interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
|
|||||||
id?: string | undefined;
|
id?: string | undefined;
|
||||||
title?: string;
|
title?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
|
children?: NoteDefinition[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,6 +53,18 @@ export function buildNote(noteDef: NoteDefinition) {
|
|||||||
note.getContent = () => noteDef.content!;
|
note.getContent = () => noteDef.content!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle children
|
||||||
|
if (noteDef.children) {
|
||||||
|
for (const childDef of noteDef.children) {
|
||||||
|
const childNote = buildNote(childDef);
|
||||||
|
new BBranch({
|
||||||
|
noteId: childNote.noteId,
|
||||||
|
parentNoteId: note.noteId,
|
||||||
|
branchId: `${note.noteId}_${childNote.noteId}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle labels and relations.
|
// Handle labels and relations.
|
||||||
let position = 0;
|
let position = 0;
|
||||||
for (const [ key, value ] of Object.entries(noteDef)) {
|
for (const [ key, value ] of Object.entries(noteDef)) {
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ export default defineConfig(() => ({
|
|||||||
provider: 'v8' as const,
|
provider: 'v8' as const,
|
||||||
reporter: [ "text", "html" ]
|
reporter: [ "text", "html" ]
|
||||||
},
|
},
|
||||||
pool: "threads"
|
pool: "vmForks"
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
2
docs/README-ro.md
vendored
2
docs/README-ro.md
vendored
@@ -153,7 +153,7 @@ sugestii sau probleme aveți!
|
|||||||
|
|
||||||
## 🏗 Procesul de instalare
|
## 🏗 Procesul de instalare
|
||||||
|
|
||||||
### Windows / MacOS
|
### Windows / macOS
|
||||||
|
|
||||||
Descărcați release-ul binar pentru platforma dvs. de pe pagina [ultimului
|
Descărcați release-ul binar pentru platforma dvs. de pe pagina [ultimului
|
||||||
release](https://github.com/TriliumNext/Trilium/releases/latest), dezarhivați și
|
release](https://github.com/TriliumNext/Trilium/releases/latest), dezarhivați și
|
||||||
|
|||||||
26563
docs/User Guide/!!!meta.json
vendored
26563
docs/User Guide/!!!meta.json
vendored
File diff suppressed because it is too large
Load Diff
@@ -50,5 +50,6 @@ These relations are supported and used internally by Trilium.
|
|||||||
| `widget_relation` | target of this relation will be executed and rendered as a widget in the sidebar |
|
| `widget_relation` | target of this relation will be executed and rendered as a widget in the sidebar |
|
||||||
| `shareCss` | CSS note which will be injected into the share page. CSS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree` and `share_omit_default_css` as well. |
|
| `shareCss` | CSS note which will be injected into the share page. CSS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree` and `share_omit_default_css` as well. |
|
||||||
| `shareJs` | JavaScript note which will be injected into the share page. JS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. |
|
| `shareJs` | JavaScript note which will be injected into the share page. JS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. |
|
||||||
|
| `shareHtml` | HTML note which will be injected into the share page at locations specified by the `shareHtmlLocation` label. HTML note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. |
|
||||||
| `shareTemplate` | Embedded JavaScript note that will be used as the template for displaying the shared note. Falls back to the default template. Consider using `share_hidden_from_tree`. |
|
| `shareTemplate` | Embedded JavaScript note that will be used as the template for displaying the shared note. Falls back to the default template. Consider using `share_hidden_from_tree`. |
|
||||||
| `shareFavicon` | Favicon note to be set in the shared page. Typically you want to set it to share root and make it inheritable. Favicon note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. |
|
| `shareFavicon` | Favicon note to be set in the shared page. Typically you want to set it to share root and make it inheritable. Favicon note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. |
|
||||||
@@ -67,6 +67,25 @@ The default design should be a good starting point, but you can customize it usi
|
|||||||
|
|
||||||
You can inject custom JavaScript into the shared note using the `~shareJs` relation. This allows you to access note attributes or traverse the note tree using the `fetchNote()` API, which retrieves note data based on its ID.
|
You can inject custom JavaScript into the shared note using the `~shareJs` relation. This allows you to access note attributes or traverse the note tree using the `fetchNote()` API, which retrieves note data based on its ID.
|
||||||
|
|
||||||
|
### Adding custom HTML
|
||||||
|
|
||||||
|
You can inject custom HTML snippets into specific locations of the shared page using the `~shareHtml` relation. The HTML note should contain the raw HTML content you want to inject, and you can control where it appears by adding the `#shareHtmlLocation` label to the HTML snippet note itself.
|
||||||
|
|
||||||
|
The `#shareHtmlLocation` label accepts values in the format `location:position`:
|
||||||
|
|
||||||
|
* **Locations**: `head`, `body`, `content`
|
||||||
|
* **Positions**: `start`, `end`
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
* `#shareHtmlLocation=head:start` - Injects HTML at the beginning of the `<head>` section
|
||||||
|
* `#shareHtmlLocation=head:end` - Injects HTML at the end of the `<head>` section (default)
|
||||||
|
* `#shareHtmlLocation=body:start` - Injects HTML at the beginning of the `<body>` section
|
||||||
|
* `#shareHtmlLocation=content:start` - Injects HTML at the beginning of the content area
|
||||||
|
* `#shareHtmlLocation=content:end` - Injects HTML at the end of the content area
|
||||||
|
|
||||||
|
If no location is specified, the HTML will be injected at `content:end` by default.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -104,9 +123,19 @@ When accessing a share, the sub-notes will be displayed in a tree on the left. B
|
|||||||
|
|
||||||
To do so, create a shared text note and apply the `shareIndex` label. When viewed, the list of shared roots will be displayed at the bottom of the note.
|
To do so, create a shared text note and apply the `shareIndex` label. When viewed, the list of shared roots will be displayed at the bottom of the note.
|
||||||
|
|
||||||
|
### Redirect Bare Domain to Share Page
|
||||||
|
|
||||||
|
This option can be enabled under `Option → Other → Share Settings`. When activated, anonymous users accessing the bare domain will be redirected to the Share page, preventing them from seeing the login option and thereby improving security.
|
||||||
|
To ensure accessibility for legitimate users, you can also enable a login link on the Share page, allowing yourself to access the login screen if you're redirected there.
|
||||||
|
|
||||||
|
### Setting a Custom Share Path
|
||||||
|
|
||||||
|
This option can be enabled under `Option → Other → Share Settings`. It allows you to customize the share URL prefix before the `noteId`. Nested paths are supported.
|
||||||
|
If you're using a proxy service, make sure to update its configuration accordingly to reflect the new path structure.
|
||||||
|
|
||||||
## Attribute reference
|
## Attribute reference
|
||||||
|
|
||||||
<table><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also <a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a> for an alternative method without setting an attribute.</td></tr><tr><td><code>shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li data-list-item-id="e6baa9f60bf59d085fd31aa2cce07a0e7">Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li data-list-item-id="ec0d067db136ef9794e4f1033405880b7">Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr></tbody></table>
|
<table><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>shareHiddenFromTree</code></td><td>this note is hidden from left navigation tree, but still accessible with its URL</td></tr><tr><td><code>shareExternalLink</code></td><td>note will act as a link to an external website in the share tree</td></tr><tr><td><code>shareAlias</code></td><td>define an alias using which the note will be available under <code>https://your_trilium_host/share/[your_alias]</code></td></tr><tr><td><code>shareOmitDefaultCss</code></td><td>default share page CSS will be omitted. Use when you make extensive styling changes.</td></tr><tr><td><code>shareRoot</code></td><td>marks note which is served on /share root.</td></tr><tr><td><code>shareDescription</code></td><td>define text to be added to the HTML meta tag for description</td></tr><tr><td><code>shareRaw</code></td><td>Note will be served in its raw format, without HTML wrapper. See also <a class="reference-link" href="Sharing/Serving%20directly%20the%20content%20o.md">Serving directly the content of a note</a> for an alternative method without setting an attribute.</td></tr><tr><td><code>shareDisallowRobotIndexing</code></td><td><p>Indicates to web crawlers that the page should not be indexed of this note by:</p><ul><li data-list-item-id="e6baa9f60bf59d085fd31aa2cce07a0e7">Setting the <code>X-Robots-Tag: noindex</code> HTTP header.</li><li data-list-item-id="ec0d067db136ef9794e4f1033405880b7">Setting the <code>noindex, follow</code> meta tag.</li></ul></td></tr><tr><td><code>shareCredentials</code></td><td>require credentials to access this shared note. Value is expected to be in format <code>username:password</code>. Don't forget to make this inheritable to apply to child-notes/images.</td></tr><tr><td><code>shareIndex</code></td><td>Note with this label will list all roots of shared notes.</td></tr><tr><td><code>shareHtmlLocation</code></td><td>defines where custom HTML injected via <code>~shareHtml</code> relation should be placed. Applied to the HTML snippet note itself. Format: <code>location:position</code> where location is <code>head</code>, <code>body</code>, or <code>content</code> and position is <code>start</code> or <code>end</code>. Defaults to <code>content:end</code>.</td></tr></tbody></table>
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
|||||||
@@ -200,7 +200,7 @@
|
|||||||
# '/build/source/apps/desktop/node_modules/better-sqlite3/build/node_gyp_bins'
|
# '/build/source/apps/desktop/node_modules/better-sqlite3/build/node_gyp_bins'
|
||||||
preBuildCommands = ''
|
preBuildCommands = ''
|
||||||
export npm_config_nodedir=${electron.headers}
|
export npm_config_nodedir=${electron.headers}
|
||||||
pnpm postinstall || true
|
pnpm postinstall
|
||||||
'';
|
'';
|
||||||
buildTask = "desktop:build";
|
buildTask = "desktop:build";
|
||||||
mainProgram = "trilium";
|
mainProgram = "trilium";
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron/rebuild": "4.0.1",
|
"@electron/rebuild": "4.0.1",
|
||||||
"@playwright/test": "1.55.1",
|
"@playwright/test": "1.56.0",
|
||||||
"@triliumnext/server": "workspace:*",
|
"@triliumnext/server": "workspace:*",
|
||||||
"@types/express": "5.0.3",
|
"@types/express": "5.0.3",
|
||||||
"@types/node": "22.18.8",
|
"@types/node": "22.18.8",
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
"tslib": "2.8.1",
|
"tslib": "2.8.1",
|
||||||
"tsx": "4.20.6",
|
"tsx": "4.20.6",
|
||||||
"typescript": "~5.9.0",
|
"typescript": "~5.9.0",
|
||||||
"typescript-eslint": "8.45.0",
|
"typescript-eslint": "8.46.0",
|
||||||
"upath": "2.0.1",
|
"upath": "2.0.1",
|
||||||
"vite": "7.1.9",
|
"vite": "7.1.9",
|
||||||
"vite-plugin-dts": "~4.5.0",
|
"vite-plugin-dts": "~4.5.0",
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
"url": "https://github.com/TriliumNext/Trilium/issues"
|
"url": "https://github.com/TriliumNext/Trilium/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://triliumnotes.org",
|
"homepage": "https://triliumnotes.org",
|
||||||
"packageManager": "pnpm@10.18.0",
|
"packageManager": "pnpm@10.18.1",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
"@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch",
|
"@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"mermaid": "11.12.0",
|
"mermaid": "11.12.0",
|
||||||
"preact": "10.27.2",
|
"preact": "10.27.2",
|
||||||
"roughjs": "4.6.6",
|
"roughjs": "4.6.6",
|
||||||
"@types/express-serve-static-core": "5.0.7",
|
"@types/express-serve-static-core": "5.1.0",
|
||||||
"flat@<5.0.1": ">=5.0.1",
|
"flat@<5.0.1": ">=5.0.1",
|
||||||
"debug@>=3.2.0 <3.2.7": ">=3.2.7",
|
"debug@>=3.2.0 <3.2.7": ">=3.2.7",
|
||||||
"nanoid@<3.3.8": ">=3.3.8",
|
"nanoid@<3.3.8": ">=3.3.8",
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
||||||
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
||||||
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "~8.45.0",
|
"@typescript-eslint/eslint-plugin": "~8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@vitest/browser": "3.2.4",
|
"@vitest/browser": "3.2.4",
|
||||||
"@vitest/coverage-istanbul": "3.2.4",
|
"@vitest/coverage-istanbul": "3.2.4",
|
||||||
"ckeditor5": "47.0.0",
|
"ckeditor5": "47.0.0",
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
||||||
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
||||||
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "~8.45.0",
|
"@typescript-eslint/eslint-plugin": "~8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@vitest/browser": "3.2.4",
|
"@vitest/browser": "3.2.4",
|
||||||
"@vitest/coverage-istanbul": "3.2.4",
|
"@vitest/coverage-istanbul": "3.2.4",
|
||||||
"ckeditor5": "47.0.0",
|
"ckeditor5": "47.0.0",
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
||||||
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
||||||
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "~8.45.0",
|
"@typescript-eslint/eslint-plugin": "~8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@vitest/browser": "3.2.4",
|
"@vitest/browser": "3.2.4",
|
||||||
"@vitest/coverage-istanbul": "3.2.4",
|
"@vitest/coverage-istanbul": "3.2.4",
|
||||||
"ckeditor5": "47.0.0",
|
"ckeditor5": "47.0.0",
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
"@ckeditor/ckeditor5-dev-utils": "43.1.0",
|
"@ckeditor/ckeditor5-dev-utils": "43.1.0",
|
||||||
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
||||||
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "~8.45.0",
|
"@typescript-eslint/eslint-plugin": "~8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@vitest/browser": "3.2.4",
|
"@vitest/browser": "3.2.4",
|
||||||
"@vitest/coverage-istanbul": "3.2.4",
|
"@vitest/coverage-istanbul": "3.2.4",
|
||||||
"ckeditor5": "47.0.0",
|
"ckeditor5": "47.0.0",
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ export default class MathCommand extends Command {
|
|||||||
|
|
||||||
mathtex = writer.createElement(
|
mathtex = writer.createElement(
|
||||||
display ? 'mathtex-display' : 'mathtex-inline',
|
display ? 'mathtex-display' : 'mathtex-inline',
|
||||||
{ equation, type, display }
|
{
|
||||||
|
...Object.fromEntries(selection.getAttributes()),
|
||||||
|
equation,
|
||||||
|
type,
|
||||||
|
display
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const selection = this.editor.model.document.selection;
|
const selection = this.editor.model.document.selection;
|
||||||
@@ -40,7 +45,7 @@ export default class MathCommand extends Command {
|
|||||||
display ? 'mathtex-display' : 'mathtex-inline',
|
display ? 'mathtex-display' : 'mathtex-inline',
|
||||||
{
|
{
|
||||||
// Inherit all attributes from selection (e.g. color, background color, size).
|
// Inherit all attributes from selection (e.g. color, background color, size).
|
||||||
...Object.fromEntries( selection.getAttributes() ),
|
...Object.fromEntries(selection.getAttributes()),
|
||||||
equation,
|
equation,
|
||||||
type: outputType,
|
type: outputType,
|
||||||
display,
|
display,
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
"@ckeditor/ckeditor5-dev-build-tools": "43.1.0",
|
||||||
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
"@ckeditor/ckeditor5-inspector": ">=4.1.0",
|
||||||
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
"@ckeditor/ckeditor5-package-tools": "4.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "~8.45.0",
|
"@typescript-eslint/eslint-plugin": "~8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@vitest/browser": "3.2.4",
|
"@vitest/browser": "3.2.4",
|
||||||
"@vitest/coverage-istanbul": "3.2.4",
|
"@vitest/coverage-istanbul": "3.2.4",
|
||||||
"ckeditor5": "47.0.0",
|
"ckeditor5": "47.0.0",
|
||||||
|
|||||||
@@ -49,4 +49,9 @@ export interface HiddenSubtreeItem {
|
|||||||
* the user moves it around.
|
* the user moves it around.
|
||||||
*/
|
*/
|
||||||
enforceBranches?: boolean;
|
enforceBranches?: boolean;
|
||||||
|
/**
|
||||||
|
* If set to true, then the attributes of this note will be checked. Any owned attribute that does not match the
|
||||||
|
* definitions will be removed.
|
||||||
|
*/
|
||||||
|
enforceAttributes?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,6 +135,8 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
|
|||||||
// Share settings
|
// Share settings
|
||||||
redirectBareDomain: boolean;
|
redirectBareDomain: boolean;
|
||||||
showLoginInShareTheme: boolean;
|
showLoginInShareTheme: boolean;
|
||||||
|
shareSubtree: boolean;
|
||||||
|
sharePath: string;
|
||||||
|
|
||||||
// AI/LLM integration options
|
// AI/LLM integration options
|
||||||
aiEnabled: boolean;
|
aiEnabled: boolean;
|
||||||
|
|||||||
@@ -1,98 +1,22 @@
|
|||||||
// Default list of allowed HTML tags
|
// Default list of allowed HTML tags
|
||||||
export const SANITIZER_DEFAULT_ALLOWED_TAGS = [
|
export const SANITIZER_DEFAULT_ALLOWED_TAGS = [
|
||||||
"h1",
|
"h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "p", "a", "ul", "ol", "li", "b", "i", "strong", "em",
|
||||||
"h2",
|
"strike", "s", "del", "abbr", "code", "hr", "br", "div", "table", "thead", "caption", "tbody", "tfoot",
|
||||||
"h3",
|
"tr", "th", "td", "pre", "section", "img", "figure", "figcaption", "span", "label", "input", "details",
|
||||||
"h4",
|
"summary", "address", "aside", "footer", "header", "hgroup", "main", "nav", "dl", "dt", "menu", "bdi",
|
||||||
"h5",
|
"bdo", "dfn", "kbd", "mark", "q", "time", "var", "wbr", "area", "map", "track", "video", "audio", "picture",
|
||||||
"h6",
|
"del", "ins",
|
||||||
"blockquote",
|
// for ENEX import
|
||||||
"p",
|
"en-media",
|
||||||
"a",
|
|
||||||
"ul",
|
|
||||||
"ol",
|
|
||||||
"li",
|
|
||||||
"b",
|
|
||||||
"i",
|
|
||||||
"strong",
|
|
||||||
"em",
|
|
||||||
"strike",
|
|
||||||
"s",
|
|
||||||
"del",
|
|
||||||
"abbr",
|
|
||||||
"code",
|
|
||||||
"hr",
|
|
||||||
"br",
|
|
||||||
"div",
|
|
||||||
"table",
|
|
||||||
"thead",
|
|
||||||
"caption",
|
|
||||||
"tbody",
|
|
||||||
"tfoot",
|
|
||||||
"tr",
|
|
||||||
"th",
|
|
||||||
"td",
|
|
||||||
"pre",
|
|
||||||
"section",
|
|
||||||
"img",
|
|
||||||
"figure",
|
|
||||||
"figcaption",
|
|
||||||
"span",
|
|
||||||
"label",
|
|
||||||
"input",
|
|
||||||
"details",
|
|
||||||
"summary",
|
|
||||||
"address",
|
|
||||||
"aside",
|
|
||||||
"footer",
|
|
||||||
"header",
|
|
||||||
"hgroup",
|
|
||||||
"main",
|
|
||||||
"nav",
|
|
||||||
"dl",
|
|
||||||
"dt",
|
|
||||||
"menu",
|
|
||||||
"bdi",
|
|
||||||
"bdo",
|
|
||||||
"dfn",
|
|
||||||
"kbd",
|
|
||||||
"mark",
|
|
||||||
"q",
|
|
||||||
"time",
|
|
||||||
"var",
|
|
||||||
"wbr",
|
|
||||||
"area",
|
|
||||||
"map",
|
|
||||||
"track",
|
|
||||||
"video",
|
|
||||||
"audio",
|
|
||||||
"picture",
|
|
||||||
"del",
|
|
||||||
"ins",
|
|
||||||
"en-media", // for ENEX import
|
|
||||||
// Additional tags (https://github.com/TriliumNext/Trilium/issues/567)
|
// Additional tags (https://github.com/TriliumNext/Trilium/issues/567)
|
||||||
"acronym",
|
"acronym", "article", "big", "button", "cite", "col", "colgroup", "data", "dd", "fieldset", "form", "legend",
|
||||||
"article",
|
"meter", "noscript", "option", "progress", "rp", "samp", "small", "sub", "sup", "template", "textarea", "tt"
|
||||||
"big",
|
|
||||||
"button",
|
|
||||||
"cite",
|
|
||||||
"col",
|
|
||||||
"colgroup",
|
|
||||||
"data",
|
|
||||||
"dd",
|
|
||||||
"fieldset",
|
|
||||||
"form",
|
|
||||||
"legend",
|
|
||||||
"meter",
|
|
||||||
"noscript",
|
|
||||||
"option",
|
|
||||||
"progress",
|
|
||||||
"rp",
|
|
||||||
"samp",
|
|
||||||
"small",
|
|
||||||
"sub",
|
|
||||||
"sup",
|
|
||||||
"template",
|
|
||||||
"textarea",
|
|
||||||
"tt"
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
export const ALLOWED_PROTOCOLS = [
|
||||||
|
'http', 'https', 'ftp', 'ftps', 'mailto', 'data', 'evernote', 'file', 'facetime', 'gemini', 'git',
|
||||||
|
'gopher', 'imap', 'irc', 'irc6', 'jabber', 'jar', 'lastfm', 'ldap', 'ldaps', 'magnet', 'message',
|
||||||
|
'mumble', 'nfs', 'onenote', 'pop', 'rmi', 's3', 'sftp', 'skype', 'sms', 'spotify', 'steam', 'svn', 'udp',
|
||||||
|
'view-source', 'vlc', 'vnc', 'ws', 'wss', 'xmpp', 'jdbc', 'slack', 'tel', 'smb', 'zotero', 'geo',
|
||||||
|
'mid', 'obsidian'
|
||||||
|
];
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@digitak/esrun": "3.2.26",
|
"@digitak/esrun": "3.2.26",
|
||||||
"@types/swagger-ui": "5.21.1",
|
"@types/swagger-ui": "5.21.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.45.0",
|
"@typescript-eslint/eslint-plugin": "8.46.0",
|
||||||
"@typescript-eslint/parser": "8.45.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"dotenv": "17.2.3",
|
"dotenv": "17.2.3",
|
||||||
"esbuild": "0.25.10",
|
"esbuild": "0.25.10",
|
||||||
"eslint": "9.37.0",
|
"eslint": "9.37.0",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="shortcut icon" href="../favicon.ico">
|
<link rel="shortcut icon" href="<%= relativePath %>favicon.ico">
|
||||||
<title><%= t("share_404.title") %></title>
|
<title><%= t("share_404.title") %></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,7 +1,31 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<% const hasTree = subRoot.note.hasVisibleChildren(); %>
|
<%
|
||||||
|
const hasTree = subRoot.note.hasVisibleChildren();
|
||||||
|
|
||||||
|
// Collect HTML snippets by location
|
||||||
|
const htmlSnippetsByLocation = {};
|
||||||
|
for (const htmlRelation of note.getRelations("shareHtml")) {
|
||||||
|
const htmlNote = htmlRelation.targetNote;
|
||||||
|
if (htmlNote) {
|
||||||
|
let location = htmlNote.getLabelValue("shareHtmlLocation") || "content:end";
|
||||||
|
// Default to :end if no position specified
|
||||||
|
if (!location.includes(":")) {
|
||||||
|
location = location + ":end";
|
||||||
|
}
|
||||||
|
if (!htmlSnippetsByLocation[location]) {
|
||||||
|
htmlSnippetsByLocation[location] = [];
|
||||||
|
}
|
||||||
|
htmlSnippetsByLocation[location].push(htmlNote.getContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const renderSnippets = (location) => {
|
||||||
|
const snippets = htmlSnippetsByLocation[location];
|
||||||
|
return snippets ? snippets.join("\n") : "";
|
||||||
|
};
|
||||||
|
%>
|
||||||
|
<%- renderSnippets("head:start") %>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
@@ -53,10 +77,11 @@
|
|||||||
<meta name="twitter:image" content="<%= openGraphImage %>">
|
<meta name="twitter:image" content="<%= openGraphImage %>">
|
||||||
<!-- Meta Tags Generated via https://opengraph.dev -->
|
<!-- Meta Tags Generated via https://opengraph.dev -->
|
||||||
<meta name="theme-color" content="<%= openGraphColor %>">
|
<meta name="theme-color" content="<%= openGraphColor %>">
|
||||||
|
<%- renderSnippets("head:end") %>
|
||||||
</head>
|
</head>
|
||||||
<%
|
<%
|
||||||
const customLogoId = subRoot.note.getRelation("shareLogo")?.value;
|
const customLogoId = subRoot.note.getRelation("shareLogo")?.value;
|
||||||
const logoUrl = customLogoId ? `api/images/${customLogoId}/image.png` : `../${assetUrlFragment}/images/icon-color.svg`;
|
const logoUrl = customLogoId ? `api/images/${customLogoId}/image.png` : `${relativePath}${assetUrlFragment}/images/icon-color.svg`;
|
||||||
const logoWidth = subRoot.note.getLabelValue("shareLogoWidth") ?? 53;
|
const logoWidth = subRoot.note.getLabelValue("shareLogoWidth") ?? 53;
|
||||||
const logoHeight = subRoot.note.getLabelValue("shareLogoHeight") ?? 40;
|
const logoHeight = subRoot.note.getLabelValue("shareLogoHeight") ?? 40;
|
||||||
const mobileLogoHeight = logoHeight && logoWidth ? 32 / (logoWidth / logoHeight) : "";
|
const mobileLogoHeight = logoHeight && logoWidth ? 32 / (logoWidth / logoHeight) : "";
|
||||||
@@ -72,6 +97,7 @@ content = content.replaceAll(headingRe, (...match) => {
|
|||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
<body data-note-id="<%= note.noteId %>" class="type-<%= note.type %><%= themeClass %>" data-ancestor-note-id="<%= subRoot.note.noteId %>">
|
<body data-note-id="<%= note.noteId %>" class="type-<%= note.type %><%= themeClass %>" data-ancestor-note-id="<%= subRoot.note.noteId %>">
|
||||||
|
<%- renderSnippets("body:start") %>
|
||||||
<div id="mobile-header">
|
<div id="mobile-header">
|
||||||
<a href="<%= shareRootLink %>">
|
<a href="<%= shareRootLink %>">
|
||||||
<img src="<%= logoUrl %>" width="32" height="<%= mobileLogoHeight %>" alt="Logo" />
|
<img src="<%= logoUrl %>" width="32" height="<%= mobileLogoHeight %>" alt="Logo" />
|
||||||
@@ -121,8 +147,8 @@ content = content.replaceAll(headingRe, (...match) => {
|
|||||||
</div>
|
</div>
|
||||||
<div id="right-pane">
|
<div id="right-pane">
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
||||||
<div id="content" class="type-<%= note.type %><% if (note.type === "text") { %> ck-content<% } %><% if (isEmpty) { %> no-content<% } %>">
|
<div id="content" class="type-<%= note.type %><% if (note.type === "text") { %> ck-content<% } %><% if (isEmpty) { %> no-content<% } %>">
|
||||||
|
<%- renderSnippets("content:start") %>
|
||||||
<h1 id="title"><%= note.title %></h1>
|
<h1 id="title"><%= note.title %></h1>
|
||||||
<% if (isEmpty && (!note.hasVisibleChildren() && note.type !== "book")) { %>
|
<% if (isEmpty && (!note.hasVisibleChildren() && note.type !== "book")) { %>
|
||||||
<p>This note has no content.</p>
|
<p>This note has no content.</p>
|
||||||
@@ -132,6 +158,7 @@ content = content.replaceAll(headingRe, (...match) => {
|
|||||||
%>
|
%>
|
||||||
<%- content %>
|
<%- content %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
<%- renderSnippets("content:end") %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if (note.hasVisibleChildren() || note.type === "book") { %>
|
<% if (note.hasVisibleChildren() || note.type === "book") { %>
|
||||||
@@ -164,7 +191,7 @@ content = content.replaceAll(headingRe, (...match) => {
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<% if (hasTree) { %>
|
<% if (hasTree) { %>
|
||||||
<%- include("prev_next", { note: note, subRoot: subRoot }) %>
|
<%- include("prev_next", { note: note, subRoot: subRoot }) %>
|
||||||
<% } %>
|
<% } %>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -205,5 +232,6 @@ content = content.replaceAll(headingRe, (...match) => {
|
|||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<%- renderSnippets("body:end") %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
260
pnpm-lock.yaml
generated
260
pnpm-lock.yaml
generated
@@ -8,7 +8,7 @@ overrides:
|
|||||||
mermaid: 11.12.0
|
mermaid: 11.12.0
|
||||||
preact: 10.27.2
|
preact: 10.27.2
|
||||||
roughjs: 4.6.6
|
roughjs: 4.6.6
|
||||||
'@types/express-serve-static-core': 5.0.7
|
'@types/express-serve-static-core': 5.1.0
|
||||||
flat@<5.0.1: '>=5.0.1'
|
flat@<5.0.1: '>=5.0.1'
|
||||||
debug@>=3.2.0 <3.2.7: '>=3.2.7'
|
debug@>=3.2.0 <3.2.7: '>=3.2.7'
|
||||||
nanoid@<3.3.8: '>=3.3.8'
|
nanoid@<3.3.8: '>=3.3.8'
|
||||||
@@ -41,8 +41,8 @@ importers:
|
|||||||
specifier: 4.0.1
|
specifier: 4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
'@playwright/test':
|
'@playwright/test':
|
||||||
specifier: 1.55.1
|
specifier: 1.56.0
|
||||||
version: 1.55.1
|
version: 1.56.0
|
||||||
'@triliumnext/server':
|
'@triliumnext/server':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:apps/server
|
version: link:apps/server
|
||||||
@@ -107,8 +107,8 @@ importers:
|
|||||||
specifier: ~5.9.0
|
specifier: ~5.9.0
|
||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
upath:
|
upath:
|
||||||
specifier: 2.0.1
|
specifier: 2.0.1
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
@@ -694,8 +694,8 @@ importers:
|
|||||||
specifier: 0.6.0
|
specifier: 0.6.0
|
||||||
version: 0.6.0
|
version: 0.6.0
|
||||||
openai:
|
openai:
|
||||||
specifier: 6.1.0
|
specifier: 6.2.0
|
||||||
version: 6.1.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4)
|
version: 6.2.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4)
|
||||||
rand-token:
|
rand-token:
|
||||||
specifier: 1.0.1
|
specifier: 1.0.1
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
@@ -837,14 +837,14 @@ importers:
|
|||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ~8.45.0
|
specifier: ~8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/coverage-istanbul':
|
'@vitest/coverage-istanbul':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -897,14 +897,14 @@ importers:
|
|||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ~8.45.0
|
specifier: ~8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/coverage-istanbul':
|
'@vitest/coverage-istanbul':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -957,14 +957,14 @@ importers:
|
|||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ~8.45.0
|
specifier: ~8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/coverage-istanbul':
|
'@vitest/coverage-istanbul':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -1024,14 +1024,14 @@ importers:
|
|||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ~8.45.0
|
specifier: ~8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/coverage-istanbul':
|
'@vitest/coverage-istanbul':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -1091,14 +1091,14 @@ importers:
|
|||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
version: 4.1.0(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@22.18.8)(bufferutil@4.0.9)(esbuild@0.25.10)(utf-8-validate@6.0.5)
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ~8.45.0
|
specifier: ~8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/coverage-istanbul':
|
'@vitest/coverage-istanbul':
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -1315,11 +1315,11 @@ importers:
|
|||||||
specifier: 5.21.1
|
specifier: 5.21.1
|
||||||
version: 5.21.1
|
version: 5.21.1
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: 8.45.0
|
specifier: 8.46.0
|
||||||
version: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: 17.2.3
|
specifier: 17.2.3
|
||||||
version: 17.2.3
|
version: 17.2.3
|
||||||
@@ -3372,8 +3372,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
'@playwright/test@1.55.1':
|
'@playwright/test@1.56.0':
|
||||||
resolution: {integrity: sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==}
|
resolution: {integrity: sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -4715,8 +4715,8 @@ packages:
|
|||||||
'@types/express-http-proxy@1.6.7':
|
'@types/express-http-proxy@1.6.7':
|
||||||
resolution: {integrity: sha512-CEp9pbnwVI1RzN9PXc+KESMxwUW5r1O7tkWb5h7Wg/YAIf+KulD/zKev8fbbn+Ljt0Yvs8MXwV2W6Id+cKxe2Q==}
|
resolution: {integrity: sha512-CEp9pbnwVI1RzN9PXc+KESMxwUW5r1O7tkWb5h7Wg/YAIf+KulD/zKev8fbbn+Ljt0Yvs8MXwV2W6Id+cKxe2Q==}
|
||||||
|
|
||||||
'@types/express-serve-static-core@5.0.7':
|
'@types/express-serve-static-core@5.1.0':
|
||||||
resolution: {integrity: sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==}
|
resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==}
|
||||||
|
|
||||||
'@types/express-session@1.18.2':
|
'@types/express-session@1.18.2':
|
||||||
resolution: {integrity: sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==}
|
resolution: {integrity: sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==}
|
||||||
@@ -4989,11 +4989,11 @@ packages:
|
|||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.45.0':
|
'@typescript-eslint/eslint-plugin@8.46.0':
|
||||||
resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==}
|
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@typescript-eslint/parser': ^8.45.0
|
'@typescript-eslint/parser': ^8.46.0
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
@@ -5004,8 +5004,8 @@ packages:
|
|||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/parser@8.45.0':
|
'@typescript-eslint/parser@8.46.0':
|
||||||
resolution: {integrity: sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==}
|
resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
@@ -5023,8 +5023,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.45.0':
|
'@typescript-eslint/project-service@8.46.0':
|
||||||
resolution: {integrity: sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==}
|
resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
@@ -5037,8 +5037,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==}
|
resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.45.0':
|
'@typescript-eslint/scope-manager@8.46.0':
|
||||||
resolution: {integrity: sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==}
|
resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/tsconfig-utils@8.40.0':
|
'@typescript-eslint/tsconfig-utils@8.40.0':
|
||||||
@@ -5059,6 +5059,12 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
|
'@typescript-eslint/tsconfig-utils@8.46.0':
|
||||||
|
resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==}
|
||||||
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.40.0':
|
'@typescript-eslint/type-utils@8.40.0':
|
||||||
resolution: {integrity: sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==}
|
resolution: {integrity: sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -5066,8 +5072,8 @@ packages:
|
|||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.45.0':
|
'@typescript-eslint/type-utils@8.46.0':
|
||||||
resolution: {integrity: sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==}
|
resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
@@ -5085,6 +5091,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==}
|
resolution: {integrity: sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
|
'@typescript-eslint/types@8.46.0':
|
||||||
|
resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==}
|
||||||
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.40.0':
|
'@typescript-eslint/typescript-estree@8.40.0':
|
||||||
resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==}
|
resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -5097,8 +5107,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.45.0':
|
'@typescript-eslint/typescript-estree@8.46.0':
|
||||||
resolution: {integrity: sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==}
|
resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
@@ -5117,8 +5127,8 @@ packages:
|
|||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.45.0':
|
'@typescript-eslint/utils@8.46.0':
|
||||||
resolution: {integrity: sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==}
|
resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
@@ -5132,8 +5142,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==}
|
resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.45.0':
|
'@typescript-eslint/visitor-keys@8.46.0':
|
||||||
resolution: {integrity: sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==}
|
resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@ungap/structured-clone@1.3.0':
|
'@ungap/structured-clone@1.3.0':
|
||||||
@@ -10096,8 +10106,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
|
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
openai@6.1.0:
|
openai@6.2.0:
|
||||||
resolution: {integrity: sha512-5sqb1wK67HoVgGlsPwcH2bUbkg66nnoIYKoyV9zi5pZPqh7EWlmSrSDjAh4O5jaIg/0rIlcDKBtWvZBuacmGZg==}
|
resolution: {integrity: sha512-qqjzHls7F5xkXNGy9P1Ei1rorI5LWupUUFWP66zPU8FlZbiITX8SFcHMKNZg/NATJ0LpIZcMUFxSwQmdeQPwSw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
ws: ^8.18.0
|
ws: ^8.18.0
|
||||||
@@ -10428,13 +10438,13 @@ packages:
|
|||||||
pkg-types@2.1.0:
|
pkg-types@2.1.0:
|
||||||
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
|
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
|
||||||
|
|
||||||
playwright-core@1.55.1:
|
playwright-core@1.56.0:
|
||||||
resolution: {integrity: sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==}
|
resolution: {integrity: sha512-1SXl7pMfemAMSDn5rkPeZljxOCYAmQnYLBTExuh6E8USHXGSX3dx6lYZN/xPpTz1vimXmPA9CDnILvmJaB8aSQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
playwright@1.55.1:
|
playwright@1.56.0:
|
||||||
resolution: {integrity: sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==}
|
resolution: {integrity: sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -13012,8 +13022,8 @@ packages:
|
|||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
typescript: '>=4.8.4 <6.0.0'
|
typescript: '>=4.8.4 <6.0.0'
|
||||||
|
|
||||||
typescript-eslint@8.45.0:
|
typescript-eslint@8.46.0:
|
||||||
resolution: {integrity: sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==}
|
resolution: {integrity: sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
eslint: ^8.57.0 || ^9.0.0
|
||||||
@@ -14714,6 +14724,8 @@ snapshots:
|
|||||||
'@ckeditor/ckeditor5-utils': 47.0.0
|
'@ckeditor/ckeditor5-utils': 47.0.0
|
||||||
'@ckeditor/ckeditor5-watchdog': 47.0.0
|
'@ckeditor/ckeditor5-watchdog': 47.0.0
|
||||||
es-toolkit: 1.39.5
|
es-toolkit: 1.39.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
|
'@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -14905,6 +14917,8 @@ snapshots:
|
|||||||
'@ckeditor/ckeditor5-utils': 47.0.0
|
'@ckeditor/ckeditor5-utils': 47.0.0
|
||||||
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||||
es-toolkit: 1.39.5
|
es-toolkit: 1.39.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@ckeditor/ckeditor5-editor-multi-root@47.0.0':
|
'@ckeditor/ckeditor5-editor-multi-root@47.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -14927,6 +14941,8 @@ snapshots:
|
|||||||
'@ckeditor/ckeditor5-table': 47.0.0
|
'@ckeditor/ckeditor5-table': 47.0.0
|
||||||
'@ckeditor/ckeditor5-utils': 47.0.0
|
'@ckeditor/ckeditor5-utils': 47.0.0
|
||||||
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@ckeditor/ckeditor5-emoji@47.0.0':
|
'@ckeditor/ckeditor5-emoji@47.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -15098,6 +15114,8 @@ snapshots:
|
|||||||
'@ckeditor/ckeditor5-widget': 47.0.0
|
'@ckeditor/ckeditor5-widget': 47.0.0
|
||||||
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||||
es-toolkit: 1.39.5
|
es-toolkit: 1.39.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@ckeditor/ckeditor5-icons@47.0.0': {}
|
'@ckeditor/ckeditor5-icons@47.0.0': {}
|
||||||
|
|
||||||
@@ -15484,8 +15502,6 @@ snapshots:
|
|||||||
'@ckeditor/ckeditor5-ui': 47.0.0
|
'@ckeditor/ckeditor5-ui': 47.0.0
|
||||||
'@ckeditor/ckeditor5-utils': 47.0.0
|
'@ckeditor/ckeditor5-utils': 47.0.0
|
||||||
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
ckeditor5: 47.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
'@ckeditor/ckeditor5-special-characters@47.0.0':
|
'@ckeditor/ckeditor5-special-characters@47.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -17551,9 +17567,9 @@ snapshots:
|
|||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@playwright/test@1.55.1':
|
'@playwright/test@1.56.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
playwright: 1.55.1
|
playwright: 1.56.0
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.29': {}
|
'@polka/url@1.0.0-next.29': {}
|
||||||
|
|
||||||
@@ -18777,7 +18793,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/connect-history-api-fallback@1.5.4':
|
'@types/connect-history-api-fallback@1.5.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/express-serve-static-core': 5.0.7
|
'@types/express-serve-static-core': 5.1.0
|
||||||
'@types/node': 22.18.8
|
'@types/node': 22.18.8
|
||||||
|
|
||||||
'@types/connect@3.4.38':
|
'@types/connect@3.4.38':
|
||||||
@@ -18948,7 +18964,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/express': 5.0.3
|
'@types/express': 5.0.3
|
||||||
|
|
||||||
'@types/express-serve-static-core@5.0.7':
|
'@types/express-serve-static-core@5.1.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.18.8
|
'@types/node': 22.18.8
|
||||||
'@types/qs': 6.14.0
|
'@types/qs': 6.14.0
|
||||||
@@ -18962,14 +18978,14 @@ snapshots:
|
|||||||
'@types/express@4.17.23':
|
'@types/express@4.17.23':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/body-parser': 1.19.6
|
'@types/body-parser': 1.19.6
|
||||||
'@types/express-serve-static-core': 5.0.7
|
'@types/express-serve-static-core': 5.1.0
|
||||||
'@types/qs': 6.14.0
|
'@types/qs': 6.14.0
|
||||||
'@types/serve-static': 1.15.9
|
'@types/serve-static': 1.15.9
|
||||||
|
|
||||||
'@types/express@5.0.3':
|
'@types/express@5.0.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/body-parser': 1.19.6
|
'@types/body-parser': 1.19.6
|
||||||
'@types/express-serve-static-core': 5.0.7
|
'@types/express-serve-static-core': 5.1.0
|
||||||
'@types/serve-static': 1.15.9
|
'@types/serve-static': 1.15.9
|
||||||
|
|
||||||
'@types/fs-extra@11.0.4':
|
'@types/fs-extra@11.0.4':
|
||||||
@@ -19270,14 +19286,14 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.1
|
'@eslint-community/regexpp': 4.12.1
|
||||||
'@typescript-eslint/parser': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/scope-manager': 8.45.0
|
'@typescript-eslint/scope-manager': 8.46.0
|
||||||
'@typescript-eslint/type-utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.45.0
|
'@typescript-eslint/visitor-keys': 8.46.0
|
||||||
eslint: 9.37.0(jiti@2.6.1)
|
eslint: 9.37.0(jiti@2.6.1)
|
||||||
graphemer: 1.4.0
|
graphemer: 1.4.0
|
||||||
ignore: 7.0.5
|
ignore: 7.0.5
|
||||||
@@ -19299,12 +19315,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 8.45.0
|
'@typescript-eslint/scope-manager': 8.46.0
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.45.0
|
'@typescript-eslint/visitor-keys': 8.46.0
|
||||||
debug: 4.4.3(supports-color@6.0.0)
|
debug: 4.4.3(supports-color@6.0.0)
|
||||||
eslint: 9.37.0(jiti@2.6.1)
|
eslint: 9.37.0(jiti@2.6.1)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
@@ -19329,10 +19345,10 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.45.0(typescript@5.9.3)':
|
'@typescript-eslint/project-service@8.46.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
debug: 4.4.3(supports-color@6.0.0)
|
debug: 4.4.3(supports-color@6.0.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -19348,10 +19364,10 @@ snapshots:
|
|||||||
'@typescript-eslint/types': 8.44.1
|
'@typescript-eslint/types': 8.44.1
|
||||||
'@typescript-eslint/visitor-keys': 8.44.1
|
'@typescript-eslint/visitor-keys': 8.44.1
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.45.0':
|
'@typescript-eslint/scope-manager@8.46.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
'@typescript-eslint/visitor-keys': 8.45.0
|
'@typescript-eslint/visitor-keys': 8.46.0
|
||||||
|
|
||||||
'@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.9.3)':
|
'@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -19365,6 +19381,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|
||||||
|
'@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)':
|
||||||
|
dependencies:
|
||||||
|
typescript: 5.9.3
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.40.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/type-utils@8.40.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.40.0
|
'@typescript-eslint/types': 8.40.0
|
||||||
@@ -19377,11 +19397,11 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
debug: 4.4.3(supports-color@6.0.0)
|
debug: 4.4.3(supports-color@6.0.0)
|
||||||
eslint: 9.37.0(jiti@2.6.1)
|
eslint: 9.37.0(jiti@2.6.1)
|
||||||
ts-api-utils: 2.1.0(typescript@5.9.3)
|
ts-api-utils: 2.1.0(typescript@5.9.3)
|
||||||
@@ -19395,6 +19415,8 @@ snapshots:
|
|||||||
|
|
||||||
'@typescript-eslint/types@8.45.0': {}
|
'@typescript-eslint/types@8.45.0': {}
|
||||||
|
|
||||||
|
'@typescript-eslint/types@8.46.0': {}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.3)':
|
'@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.40.0(typescript@5.9.3)
|
'@typescript-eslint/project-service': 8.40.0(typescript@5.9.3)
|
||||||
@@ -19427,12 +19449,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.45.0(typescript@5.9.3)':
|
'@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/project-service': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/tsconfig-utils': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
'@typescript-eslint/visitor-keys': 8.45.0
|
'@typescript-eslint/visitor-keys': 8.46.0
|
||||||
debug: 4.4.3(supports-color@6.0.0)
|
debug: 4.4.3(supports-color@6.0.0)
|
||||||
fast-glob: 3.3.3
|
fast-glob: 3.3.3
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -19465,12 +19487,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1))
|
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1))
|
||||||
'@typescript-eslint/scope-manager': 8.45.0
|
'@typescript-eslint/scope-manager': 8.46.0
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
|
||||||
eslint: 9.37.0(jiti@2.6.1)
|
eslint: 9.37.0(jiti@2.6.1)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -19486,9 +19508,9 @@ snapshots:
|
|||||||
'@typescript-eslint/types': 8.44.1
|
'@typescript-eslint/types': 8.44.1
|
||||||
eslint-visitor-keys: 4.2.1
|
eslint-visitor-keys: 4.2.1
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.45.0':
|
'@typescript-eslint/visitor-keys@8.46.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.45.0
|
'@typescript-eslint/types': 8.46.0
|
||||||
eslint-visitor-keys: 4.2.1
|
eslint-visitor-keys: 4.2.1
|
||||||
|
|
||||||
'@ungap/structured-clone@1.3.0': {}
|
'@ungap/structured-clone@1.3.0': {}
|
||||||
@@ -19524,7 +19546,7 @@ snapshots:
|
|||||||
- bufferutil
|
- bufferutil
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
'@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
|
'@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@testing-library/dom': 10.4.0
|
'@testing-library/dom': 10.4.0
|
||||||
'@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0)
|
'@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0)
|
||||||
@@ -19536,7 +19558,7 @@ snapshots:
|
|||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.8)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@19.0.2)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.8)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@19.0.2)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||||
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
playwright: 1.55.1
|
playwright: 1.56.0
|
||||||
webdriverio: 9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
webdriverio: 9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
@@ -19577,7 +19599,7 @@ snapshots:
|
|||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.8)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@19.0.2)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.8)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@19.0.2)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -25917,7 +25939,7 @@ snapshots:
|
|||||||
is-inside-container: 1.0.0
|
is-inside-container: 1.0.0
|
||||||
wsl-utils: 0.1.0
|
wsl-utils: 0.1.0
|
||||||
|
|
||||||
openai@6.1.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4):
|
openai@6.2.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5))(zod@3.24.4):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
zod: 3.24.4
|
zod: 3.24.4
|
||||||
@@ -26251,11 +26273,11 @@ snapshots:
|
|||||||
exsolve: 1.0.5
|
exsolve: 1.0.5
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
playwright-core@1.55.1: {}
|
playwright-core@1.56.0: {}
|
||||||
|
|
||||||
playwright@1.55.1:
|
playwright@1.56.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
playwright-core: 1.55.1
|
playwright-core: 1.56.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
|
|
||||||
@@ -29434,12 +29456,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
typescript-eslint@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3):
|
typescript-eslint@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
eslint: 9.37.0(jiti@2.6.1)
|
eslint: 9.37.0(jiti@2.6.1)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -29806,7 +29828,7 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/debug': 4.1.12
|
'@types/debug': 4.1.12
|
||||||
'@types/node': 22.18.8
|
'@types/node': 22.18.8
|
||||||
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.55.1)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@22.18.8)(typescript@5.9.3))(playwright@1.56.0)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@22.18.8)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||||
'@vitest/ui': 3.2.4(vitest@3.2.4)
|
'@vitest/ui': 3.2.4(vitest@3.2.4)
|
||||||
happy-dom: 19.0.2
|
happy-dom: 19.0.2
|
||||||
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||||
@@ -29972,7 +29994,7 @@ snapshots:
|
|||||||
'@types/bonjour': 3.5.13
|
'@types/bonjour': 3.5.13
|
||||||
'@types/connect-history-api-fallback': 1.5.4
|
'@types/connect-history-api-fallback': 1.5.4
|
||||||
'@types/express': 4.17.23
|
'@types/express': 4.17.23
|
||||||
'@types/express-serve-static-core': 5.0.7
|
'@types/express-serve-static-core': 5.1.0
|
||||||
'@types/serve-index': 1.9.4
|
'@types/serve-index': 1.9.4
|
||||||
'@types/serve-static': 1.15.9
|
'@types/serve-static': 1.15.9
|
||||||
'@types/sockjs': 0.3.36
|
'@types/sockjs': 0.3.36
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function copyNativeDependencies(projectRoot: string) {
|
|||||||
cpSync(sourcePath, destPath, { recursive: true, dereference: true });
|
cpSync(sourcePath, destPath, { recursive: true, dereference: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function rebuildNativeDependencies(projectRoot: string) {
|
async function rebuildNativeDependencies(projectRoot: string) {
|
||||||
const electronVersion = determineElectronVersion(projectRoot);
|
const electronVersion = determineElectronVersion(projectRoot);
|
||||||
|
|
||||||
if (!electronVersion) {
|
if (!electronVersion) {
|
||||||
@@ -35,7 +35,7 @@ function rebuildNativeDependencies(projectRoot: string) {
|
|||||||
console.log(`Rebuilding ${projectRoot} with ${electronVersion} for ${targetArch}...`);
|
console.log(`Rebuilding ${projectRoot} with ${electronVersion} for ${targetArch}...`);
|
||||||
|
|
||||||
const resolvedPath = resolve(projectRoot);
|
const resolvedPath = resolve(projectRoot);
|
||||||
rebuild({
|
await rebuild({
|
||||||
projectRootPath: resolvedPath,
|
projectRootPath: resolvedPath,
|
||||||
buildPath: resolvedPath,
|
buildPath: resolvedPath,
|
||||||
electronVersion,
|
electronVersion,
|
||||||
@@ -64,5 +64,5 @@ function determineElectronVersion(projectRoot: string) {
|
|||||||
|
|
||||||
for (const projectRoot of [ "apps/desktop", "apps/edit-docs" ]) {
|
for (const projectRoot of [ "apps/desktop", "apps/edit-docs" ]) {
|
||||||
copyNativeDependencies(projectRoot);
|
copyNativeDependencies(projectRoot);
|
||||||
rebuildNativeDependencies(projectRoot);
|
await rebuildNativeDependencies(projectRoot);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user