Merge branch 'main' into electron_newwindow

This commit is contained in:
SngAbc 2025-11-03 09:49:46 +08:00 committed by GitHub
commit 5782e58db1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 1774 additions and 632 deletions

View File

@ -48,9 +48,7 @@
"lorem-ipsum": "2.0.8",
"rcedit": "4.0.1",
"rimraf": "6.1.0",
"tslib": "2.8.1",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
"tslib": "2.8.1"
},
"optionalDependencies": {
"appdmg": "0.6.6"

View File

@ -1,15 +0,0 @@
{
"entryPoints": [
"src/services/backend_script_entrypoint.ts",
"src/public/app/services/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
],
"outputs": [
{
"name": "html",
"path": "./docs/Script API"
}
]
}

View File

@ -0,0 +1,22 @@
{
"name": "build-docs",
"version": "1.0.0",
"description": "",
"main": "src/main.ts",
"scripts": {
"start": "tsx ."
},
"keywords": [],
"author": "Elian Doran <contact@eliandoran.me>",
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.19.0",
"devDependencies": {
"@redocly/cli": "2.10.0",
"archiver": "7.0.1",
"fs-extra": "11.3.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

View File

@ -0,0 +1,36 @@
/**
* The backend script API is accessible to code notes with the "JS (backend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Backend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note on the server side.
*
* Make sure to keep in line with backend's `script_context.ts`.
*/
export type { default as AbstractBeccaEntity } from "../../server/src/becca/entities/abstract_becca_entity.js";
export type { default as BAttachment } from "../../server/src/becca/entities/battachment.js";
export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js";
export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js";
export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js";
export type { BNote };
export type { default as BOption } from "../../server/src/becca/entities/boption.js";
export type { default as BRecentNote } from "../../server/src/becca/entities/brecent_note.js";
export type { default as BRevision } from "../../server/src/becca/entities/brevision.js";
import BNote from "../../server/src/becca/entities/bnote.js";
import BackendScriptApi, { type Api } from "../../server/src/services/backend_script_api.js";
export type { Api };
const fakeNote = new BNote();
/**
* The `api` global variable allows access to the backend script API, which is documented in {@link Api}.
*/
export const api: Api = new BackendScriptApi(fakeNote, {});

View File

@ -4,14 +4,17 @@ process.env.NODE_ENV = "development";
import cls from "@triliumnext/server/src/services/cls.js";
import { dirname, join, resolve } from "path";
import fs, { copyFile } from "fs/promises";
import fsExtra, { createWriteStream, type WriteStream } from "fs-extra";
import * as fs from "fs/promises";
import * as fsExtra from "fs-extra";
import archiver from "archiver";
import { WriteStream } from "fs";
import { execSync } from "child_process";
import BuildContext from "./context.js";
const DOCS_ROOT = "../../../docs";
const OUTPUT_DIR = "../../site";
async function main() {
async function buildDocsInner() {
const i18n = await import("@triliumnext/server/src/services/i18n.js");
await i18n.initializeTranslations();
@ -30,7 +33,7 @@ async function main() {
"export",
null
);
const fileOutputStream = createWriteStream(zipFilePath);
const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
await exportToZip(taskContext, branch, "share", fileOutputStream);
await waitForStreamToFinish(fileOutputStream);
await extractZip(zipFilePath, OUTPUT_DIR);
@ -41,7 +44,7 @@ async function main() {
}
// Copy favicon.
await copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
console.log("Documentation built successfully!");
}
@ -106,4 +109,19 @@ export async function extractZip(zipFilePath: string, outputPath: string, ignore
});
}
cls.init(main);
export default async function buildDocs({ gitRootDir }: BuildContext) {
// Build the share theme.
execSync(`pnpm run --filter share-theme build`, {
stdio: "inherit",
cwd: gitRootDir
});
// Trigger the actual build.
await new Promise((res, rej) => {
cls.init(() => {
buildDocsInner()
.catch(rej)
.then(res);
});
});
}

View File

@ -0,0 +1,4 @@
export default interface BuildContext {
gitRootDir: string;
baseDir: string;
}

View File

@ -0,0 +1,28 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
export type { default as FAttachment } from "../../client/src/entities/fattachment.js";
export type { default as FAttribute } from "../../client/src/entities/fattribute.js";
export type { default as FBranch } from "../../client/src/entities/fbranch.js";
export type { default as FNote } from "../../client/src/entities/fnote.js";
export type { Api } from "../../client/src/services/frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../../client/src/widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@ -0,0 +1,26 @@
import { join } from "path";
import BuildContext from "./context";
import buildSwagger from "./swagger";
import { existsSync, mkdirSync, rmSync } from "fs";
import buildDocs from "./build-docs";
import buildScriptApi from "./script-api";
const context: BuildContext = {
gitRootDir: join(__dirname, "../../../"),
baseDir: join(__dirname, "../../../site")
};
async function main() {
// Clean input dir.
if (existsSync(context.baseDir)) {
rmSync(context.baseDir, { recursive: true });
}
mkdirSync(context.baseDir);
// Start building.
await buildDocs(context);
buildSwagger(context);
buildScriptApi(context);
}
main();

View File

@ -0,0 +1,15 @@
import { execSync } from "child_process";
import BuildContext from "./context";
import { join } from "path";
export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) {
// Generate types
execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir });
for (const config of [ "backend", "frontend" ]) {
const outDir = join(baseDir, "script-api", config);
execSync(`pnpm typedoc --options typedoc.${config}.json --html "${outDir}"`, {
stdio: "inherit"
});
}
}

View File

@ -0,0 +1,32 @@
import BuildContext from "./context";
import { join } from "path";
import { execSync } from "child_process";
import { mkdirSync } from "fs";
interface BuildInfo {
specPath: string;
outDir: string;
}
const DIR_PREFIX = "rest-api";
const buildInfos: BuildInfo[] = [
{
// Paths are relative to Git root.
specPath: "apps/server/internal.openapi.yaml",
outDir: `${DIR_PREFIX}/internal`
},
{
specPath: "apps/server/etapi.openapi.yaml",
outDir: `${DIR_PREFIX}/etapi`
}
];
export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) {
for (const { specPath, outDir } of buildInfos) {
const absSpecPath = join(gitRootDir, specPath);
const targetDir = join(baseDir, outDir);
mkdirSync(targetDir, { recursive: true });
execSync(`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, { stdio: "inherit" });
}
}

View File

@ -0,0 +1,36 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"outDir": "dist",
"strict": false,
"types": [
"node",
"express"
],
"rootDir": "src",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
},
"include": [
"src/**/*.ts",
"../server/src/*.d.ts"
],
"exclude": [
"eslint.config.js",
"eslint.config.cjs",
"eslint.config.mjs"
],
"references": [
{
"path": "../server/tsconfig.app.json"
},
{
"path": "../desktop/tsconfig.app.json"
},
{
"path": "../client/tsconfig.app.json"
}
]
}

View File

@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.base.json",
"include": [],
"references": [
{
"path": "../server"
},
{
"path": "../client"
},
{
"path": "./tsconfig.app.json"
}
]
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Backend API",
"entryPoints": [
"src/backend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Frontend API",
"entryPoints": [
"src/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@ -1,28 +0,0 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../widgets/basic_widget.js";
export type { default as FAttachment } from "../entities/fattachment.js";
export type { default as FAttribute } from "../entities/fattribute.js";
export type { default as FBranch } from "../entities/fbranch.js";
export type { default as FNote } from "../entities/fnote.js";
export type { Api } from "./frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "./frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@ -10,7 +10,7 @@ export const byNoteType: Record<Exclude<NoteType, "book">, string | null> = {
file: null,
image: null,
launcher: null,
mermaid: null,
mermaid: "s1aBHPd79XYj",
mindMap: null,
noteMap: null,
relationMap: null,

View File

@ -716,7 +716,6 @@
"backup_database_now": "نسخ اختياطي لقاعدة البيانات الان"
},
"etapi": {
"wiki": "ويكي",
"created": "تم الأنشاء",
"actions": "أجراءات",
"title": "ETAPI",

View File

@ -1289,10 +1289,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI 是一个 REST API用于以编程方式访问 Trilium 实例,而无需 UI。",
"see_more": "有关更多详细信息,请参见 {{- link_to_wiki}} 和 {{- link_to_openapi_spec}} 或 {{- link_to_swagger_ui}}。",
"wiki": "维基",
"openapi_spec": "ETAPI OpenAPI 规范",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "创建新的 ETAPI 令牌",
"existing_tokens": "现有令牌",
"no_tokens_yet": "目前还没有令牌。点击上面的按钮创建一个。",

View File

@ -1286,10 +1286,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI ist eine REST-API, die für den programmgesteuerten Zugriff auf die Trilium-Instanz ohne Benutzeroberfläche verwendet wird.",
"see_more": "Weitere Details können im {{- link_to_wiki}} und in der {{- link_to_openapi_spec}} oder der {{- link_to_swagger_ui }} gefunden werden.",
"wiki": "Wiki",
"openapi_spec": "ETAPI OpenAPI-Spezifikation",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Erstelle ein neues ETAPI-Token",
"existing_tokens": "Vorhandene Token",
"no_tokens_yet": "Es sind noch keine Token vorhanden. Klicke auf die Schaltfläche oben, um eine zu erstellen.",

View File

@ -1453,10 +1453,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI is a REST API used to access Trilium instance programmatically, without UI.",
"see_more": "See more details in the {{- link_to_wiki}} and the {{- link_to_openapi_spec}} or the {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "ETAPI OpenAPI spec",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Create new ETAPI token",
"existing_tokens": "Existing tokens",
"no_tokens_yet": "There are no tokens yet. Click on the button above to create one.",

View File

@ -1446,10 +1446,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI es una REST API que se utiliza para acceder a la instancia de Trilium mediante programación, sin interfaz de usuario.",
"see_more": "Véa más detalles en el {{- link_to_wiki}} y el {{- link_to_openapi_spec}} o el {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "Especificación ETAPI OpenAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Crear nuevo token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Aún no hay tokens. Dé clic en el botón de arriba para crear uno.",

View File

@ -1288,8 +1288,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI est une API REST utilisée pour accéder à l'instance Trilium par programme, sans interface utilisateur.",
"wiki": "wiki",
"openapi_spec": "Spec ETAPI OpenAPI",
"create_token": "Créer un nouveau jeton ETAPI",
"existing_tokens": "Jetons existants",
"no_tokens_yet": "Il n'y a pas encore de jetons. Cliquez sur le bouton ci-dessus pour en créer un.",
@ -1306,9 +1304,7 @@
"delete_token": "Supprimer/désactiver ce token",
"rename_token_title": "Renommer le jeton",
"rename_token_message": "Veuillez saisir le nom du nouveau jeton",
"delete_token_confirmation": "Êtes-vous sûr de vouloir supprimer le jeton ETAPI « {{name}} » ?",
"see_more": "Voir plus de détails dans le {{- link_to_wiki}} et le {{- link_to_openapi_spec}} ou le {{- link_to_swagger_ui }}.",
"swagger_ui": "Interface utilisateur ETAPI Swagger"
"delete_token_confirmation": "Êtes-vous sûr de vouloir supprimer le jeton ETAPI « {{name}} » ?"
},
"options_widget": {
"options_status": "Statut des options",

View File

@ -132,10 +132,6 @@
"new_token_message": "Inserisci il nome del nuovo token",
"title": "ETAPI",
"description": "ETAPI è un'API REST utilizzata per accedere alle istanze di Trilium in modo programmatico, senza interfaccia utente.",
"see_more": "Per maggiori dettagli consulta {{- link_to_wiki}} e {{- link_to_openapi_spec}} o {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Specifiche ETAPI OpenAPI",
"swagger_ui": "Interfaccia utente ETAPI Swagger",
"create_token": "Crea un nuovo token ETAPI",
"existing_tokens": "Token esistenti",
"no_tokens_yet": "Non ci sono ancora token. Clicca sul pulsante qui sopra per crearne uno.",

View File

@ -657,10 +657,6 @@
"created": "作成日時",
"title": "ETAPI",
"description": "ETAPI は、Trilium インスタンスに UI なしでプログラム的にアクセスするための REST API です。",
"see_more": "詳細は{{- link_to_wiki}}と{{- link_to_openapi_spec}}または{{- link_to_swagger_ui }}を参照してください。",
"wiki": "wiki",
"openapi_spec": "ETAPI OpenAPIの仕様",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "新しくETAPIトークンを作成",
"existing_tokens": "既存のトークン",
"no_tokens_yet": "トークンはまだありません。上のボタンをクリックして作成してください。",

View File

@ -1663,10 +1663,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI to interfejs API REST używany do programowego dostępu do instancji Trilium, bez interfejsu użytkownika.",
"see_more": "Zobacz więcej szczegółów w {{- link_to_wiki}} oraz w {{- link_to_openapi_spec}} lub {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "specyfikacja ETAPI OpenAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Utwórz nowy token ETAPI",
"existing_tokens": "Istniejące tokeny",
"no_tokens_yet": "Nie ma jeszcze żadnych tokenów. Kliknij przycisk powyżej, aby utworzyć jeden.",

View File

@ -1422,10 +1422,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI é uma API REST usada para aceder a instância do Trilium programaticamente, sem interface gráfica.",
"see_more": "Veja mais pormenores no {{- link_to_wiki}}, na {{- link_to_openapi_spec}} ou na {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Especificação OpenAPI do ETAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Criar token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.",

View File

@ -1932,10 +1932,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI é uma API REST usada para acessar a instância do Trilium programaticamente, sem interface gráfica.",
"see_more": "Veja mais detalhes no {{- link_to_wiki}}, na {{- link_to_openapi_spec}} ou na {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Especificação OpenAPI do ETAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Criar novo token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.",

View File

@ -507,17 +507,13 @@
"new_token_message": "Introduceți denumirea noului token",
"new_token_title": "Token ETAPI nou",
"no_tokens_yet": "Nu există încă token-uri. Clic pe butonul de deasupra pentru a crea una.",
"openapi_spec": "Specificația OpenAPI pentru ETAPI",
"swagger_ui": "UI-ul Swagger pentru ETAPI",
"rename_token": "Redenumește token-ul",
"rename_token_message": "Introduceți denumirea noului token",
"rename_token_title": "Redenumire token",
"see_more": "Vedeți mai multe detalii în {{- link_to_wiki}} și în {{- link_to_openapi_spec}} sau în {{- link_to_swagger_ui }}.",
"title": "ETAPI",
"token_created_message": "Copiați token-ul creat în clipboard. Trilium stochează token-ul ca hash așadar această valoare poate fi văzută doar acum.",
"token_created_title": "Token ETAPI creat",
"token_name": "Denumire token",
"wiki": "wiki"
"token_name": "Denumire token"
},
"execute_script": {
"example_1": "De exemplu, pentru a adăuga un șir de caractere la titlul unei notițe, se poate folosi acest mic script:",

View File

@ -1440,7 +1440,6 @@
},
"etapi": {
"title": "ETAPI",
"wiki": "вики",
"created": "Создано",
"actions": "Действия",
"existing_tokens": "Существующие токены",
@ -1448,10 +1447,7 @@
"default_token_name": "новый токен",
"rename_token_title": "Переименовать токен",
"description": "ETAPI — это REST API, используемый для программного доступа к экземпляру Trilium без пользовательского интерфейса.",
"see_more": "Более подробную информацию смотрите в {{- link_to_wiki}} и {{- link_to_openapi_spec}} или {{- link_to_swagger_ui }}.",
"create_token": "Создать новый токен ETAPI",
"openapi_spec": "Спецификация ETAPI OpenAPI",
"swagger_ui": "Пользовательский интерфейс ETAPI Swagger",
"new_token_title": "Новый токен ETAPI",
"token_created_title": "Создан токен ETAPI",
"rename_token": "Переименовать этот токен",

View File

@ -1281,8 +1281,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI 是一個 REST API用於以編程方式訪問 Trilium 實例,而無需 UI。",
"wiki": "維基",
"openapi_spec": "ETAPI OpenAPI 規範",
"create_token": "新增 ETAPI 令牌",
"existing_tokens": "現有令牌",
"no_tokens_yet": "目前還沒有令牌。點擊上面的按鈕新增一個。",
@ -1299,9 +1297,7 @@
"delete_token": "刪除 / 停用此令牌",
"rename_token_title": "重新命名令牌",
"rename_token_message": "請輸入新的令牌名稱",
"delete_token_confirmation": "您確定要刪除 ETAPI 令牌 \"{{name}}\" 嗎?",
"see_more": "有關更多詳細資訊,請參閱 {{- link_to_wiki}} 和 {{- link_to_openapi_spec}} 或 {{- link_to_swagger_ui}}。",
"swagger_ui": "ETAPI Swagger UI"
"delete_token_confirmation": "您確定要刪除 ETAPI 令牌 \"{{name}}\" 嗎?"
},
"options_widget": {
"options_status": "選項狀態",

View File

@ -1402,10 +1402,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI — це REST API, який використовується для програмного доступу до екземпляра Trilium без інтерфейсу користувача.",
"see_more": "Див. докладнішу інформацію у {{- link_to_wiki}} та {{- link_to_openapi_spec}} або {{- link_to_swagger_ui }}.",
"wiki": "вікі",
"openapi_spec": "ETAPI OpenAPI spec",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Створити новий токен ETAPI",
"existing_tokens": "Існуючі токени",
"no_tokens_yet": "Токенів поки що немає. Натисніть кнопку вище, щоб створити його.",

View File

@ -2,7 +2,7 @@ import type { ComponentChildren } from "preact";
import { CSSProperties } from "preact/compat";
interface OptionsSectionProps {
title?: string;
title?: ComponentChildren;
children: ComponentChildren;
noCard?: boolean;
style?: CSSProperties;

View File

@ -11,6 +11,7 @@ import dialog from "../../../services/dialog";
import { formatDateTime } from "../../../utils/formatters";
import ActionButton from "../../react/ActionButton";
import { useTriliumEvent } from "../../react/hooks";
import HelpButton from "../../react/HelpButton";
type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>;
type DeleteTokenCallback = (tokenId: string, name: string ) => Promise<void>;
@ -48,19 +49,13 @@ export default function EtapiSettings() {
message: t("etapi.token_created_message"),
defaultValue: authToken
});
}, []);
}, []);
return (
<OptionsSection title={t("etapi.title")}>
<FormText>
{t("etapi.description")}<br />
<RawHtml
html={t("etapi.see_more", {
link_to_wiki: `<a class="tn-link" href="https://triliumnext.github.io/Docs/Wiki/etapi.html">${t("etapi.wiki")}</a>`,
// TODO: We use window.open src/public/app/services/link.ts -> prevents regular click behavior on "a" element here because it's a relative path
link_to_openapi_spec: `<a class="tn-link" onclick="window.open('etapi/etapi.openapi.yaml')" href="etapi/etapi.openapi.yaml">${t("etapi.openapi_spec")}</a>`,
link_to_swagger_ui: `<a class="tn-link" href="#_help_f3xpgx6H01PW">${t("etapi.swagger_ui")}</a>`
})} />
{t("etapi.description")}
<HelpButton helpPage="pgxEVkzLl1OP" />
</FormText>
<Button
@ -68,6 +63,7 @@ export default function EtapiSettings() {
text={t("etapi.create_token")}
onClick={createTokenCallback}
/>
<hr />
<h5>{t("etapi.existing_tokens")}</h5>
@ -123,7 +119,7 @@ function TokenList({ tokens }: { tokens: EtapiToken[] }) {
text={t("etapi.rename_token")}
onClick={() => renameCallback(etapiTokenId, name)}
/>
<ActionButton
icon="bx bx-trash"
text={t("etapi.delete_token")}

View File

@ -23,6 +23,8 @@ if (!DOCS_ROOT || !USER_GUIDE_ROOT) {
throw new Error("Missing DOCS_ROOT or USER_GUIDE_ROOT environment variable.");
}
const BASE_URL = "https://docs.triliumnotes.org";
const NOTE_MAPPINGS: NoteMapping[] = [
{
rootNoteId: "pOsGYCXsbNQG",
@ -158,6 +160,14 @@ async function cleanUpMeta(outputPath: string, minify: boolean) {
}
el.isExpanded = false;
// Rewrite web view URLs that point to root.
if (el.type === "webView" && minify) {
const srcAttr = el.attributes.find(attr => attr.name === "webViewSrc");
if (srcAttr.value.startsWith("/")) {
srcAttr.value = BASE_URL + srcAttr.value;
}
}
}
if (minify) {

View File

@ -4,12 +4,12 @@ info:
title: ETAPI
description: External Trilium API
contact:
name: zadam
email: zadam.apps@gmail.com
url: https://github.com/zadam/trilium
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:37740/etapi
- url: http://localhost:8080/etapi

View File

@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: Trilium Notes Internal API
version: 0.98.0
title: Internal Trilium API
version: 0.99.3
description: |
This is the internal API used by the Trilium Notes client application.
@ -24,11 +24,12 @@ info:
State-changing operations require CSRF tokens when using session authentication.
contact:
name: TriliumNext Issue Tracker
url: https://github.com/TriliumNext/Trilium/issues
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: GNU Affero General Public License v3.0
url: https://www.gnu.org/licenses/agpl-3.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:8080

View File

@ -61,7 +61,6 @@
"@types/serve-static": "2.2.0",
"@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.3",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.6",
"@types/ws": "8.18.1",
@ -123,7 +122,6 @@
"striptags": "3.2.0",
"supertest": "7.1.4",
"swagger-jsdoc": "6.2.8",
"swagger-ui-express": "5.0.1",
"time2fa": "1.4.2",
"tmp": "0.2.5",
"turndown": "7.2.2",

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,13 @@
<aside class="admonition tip">
<p>For a quick start, consult the&nbsp;<a class="reference-link" href="#root/pgxEVkzLl1OP/_help_9qPsTWBorUhQ">API Reference</a>.</p>
</aside>
<p>ETAPI is Trilium's public/external REST API. It is available since Trilium
v0.50.</p>
<p>The documentation is in OpenAPI format, available <a href="https://github.com/TriliumNext/Trilium/blob/master/src/etapi/etapi.openapi.yaml">here</a>.</p>
<h2>API clients</h2>
<p>As an alternative to calling the API directly, there are client libraries
to simplify this</p>
<ul>
<li><a href="https://github.com/Nriver/trilium-py">trilium-py</a>, you can
<li data-list-item-id="e3342ddfa108f6c8c6c47d7d3da8b02fa"><a href="https://github.com/Nriver/trilium-py">trilium-py</a>, you can
use Python to communicate with Trilium.</li>
</ul>
<h2>Obtaining a token</h2>
@ -23,10 +25,10 @@ Authorization: ETAPITOKEN</code></pre>
<p>Since v0.56 you can also use basic auth format:</p><pre><code class="language-text-x-trilium-auto">GET https://myserver.com/etapi/app-info
Authorization: Basic BATOKEN</code></pre>
<ul>
<li>Where <code>BATOKEN = BASE64(username + ':' + password)</code> - this is
<li data-list-item-id="ec59ac570a3d2a846da38378a5f2428ed">Where <code>BATOKEN = BASE64(username + ':' + password)</code> - this is
a standard Basic Auth serialization</li>
<li>Where <code>username</code> is "etapi"</li>
<li>And <code>password</code> is the generated ETAPI token described above.</li>
<li data-list-item-id="e18e2e73ebecc949dd4a51cd9f8bb0b91">Where <code>username</code> is "etapi"</li>
<li data-list-item-id="ee892223f95cef4a53caec5477ab31edb">And <code>password</code> is the generated ETAPI token described above.</li>
</ul>
<p>Basic Auth is meant to be used with tools which support only basic auth.</p>
<h2>Interaction using Bash scripts</h2>
@ -42,10 +44,10 @@ NOTE_ID="i6ra4ZshJhgN"
curl "$SERVER/etapi/notes/$NOTE_ID/content" -H "Authorization: $TOKEN" </code></pre>
<p>Make sure to replace the values of:</p>
<ul>
<li><code>TOKEN</code> with your ETAPI token.</li>
<li><code>SERVER</code> with the correct protocol, host name and port to your
<li data-list-item-id="e68020f83acc951e180bb405d149a64a5"><code>TOKEN</code> with your ETAPI token.</li>
<li data-list-item-id="ef4c31df5f6d18811e7de0ee8ff95f3a7"><code>SERVER</code> with the correct protocol, host name and port to your
Trilium instance.</li>
<li><code>NOTE_ID</code> with an existing note ID to download.</li>
<li data-list-item-id="e25086bb4c54d32259f987f9366e22204"><code>NOTE_ID</code> with an existing note ID to download.</li>
</ul>
<p>As another example, to obtain a .zip export of a note and place it in
a directory called <code>out</code>, simply replace the last statement in

View File

@ -1,3 +1,8 @@
<aside class="admonition tip">
<p>For a quick understanding of the Mermaid syntax, see&nbsp;<a class="reference-link"
href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/s1aBHPd79XYj/_help_WWgeUaBb7UfC">Syntax reference</a>&nbsp;(official
documentation).</p>
</aside>
<figure class="image image-style-align-center">
<img style="aspect-ratio:886/663;" src="2_Mermaid Diagrams_image.png"
width="886" height="663">
@ -6,14 +11,13 @@
as flowchart, sequence diagram, class diagram, state diagram, pie charts,
etc., all using a text description of the chart instead of manually drawing
the diagram.</p>
<p>For the official documentation of Mermaid.js see <a href="https://mermaid.js.org/intro/">mermaid.js.org/intro/</a>.</p>
<h2>Layouts</h2>
<p>Depending on the chart being edited and user preference, there are two
layouts supported by the Mermaid note type:</p>
<ul>
<li>Horizontal, where the source code (editable part) is on the left side
<li data-list-item-id="e5998f20495a1079ee7b6e284dc4d14e4">Horizontal, where the source code (editable part) is on the left side
of the screen and the preview is to the right.</li>
<li>Vertical, where the source code is at the bottom of the screen and the
<li data-list-item-id="ebebfbd8cf2125c70056e3e9075d8681e">Vertical, where the source code is at the bottom of the screen and the
preview is at the top.</li>
</ul>
<p>It's possible to switch between the two layouts at any time by pressing
@ -21,44 +25,48 @@
<img src="Mermaid Diagrams_image.png">icon in the&nbsp;<a class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons</a>&nbsp;area.</p>
<h2>Interaction</h2>
<ul>
<li>The source code of the diagram (in Mermaid format) is displayed on the
<li data-list-item-id="e67d8f093c4793e19e2ade2d58728ae81">The source code of the diagram (in Mermaid format) is displayed on the
left or bottom side of the note (depending on the layout).
<ul>
<li>Changing the diagram code will refresh automatically the diagram.</li>
<li data-list-item-id="e4d777ef787093815b961d734021ccc55">Changing the diagram code will refresh automatically the diagram.</li>
</ul>
</li>
<li>The preview of the diagram is displayed at the right or top side of the
<li data-list-item-id="e6faf589831e3252f8cda42f62248377a">The preview of the diagram is displayed at the right or top side of the
note (depending on the layout):
<ul>
<li>There are dedicated buttons at the bottom-right of the preview to control
<li data-list-item-id="e1dc5994137e511eb29657629d9e729a3">There are dedicated buttons at the bottom-right of the preview to control
the zoom in, zoom out or re-center the diagram:
<img src="1_Mermaid Diagrams_image.png">
</li>
<li>The preview can be moved around by holding the left mouse button and dragging.</li>
<li>Zooming can also be done by using the scroll wheel.</li>
<li>The zoom and position on the preview will remain fixed as the diagram
changes, to be able to work more easily with large diagrams.</li>
</ul>
<li data-list-item-id="e51812ca016db170ceb6814007a60eb10">The preview can be moved around by holding the left mouse button and dragging.</li>
<li
data-list-item-id="e617128e494ed43ca5d0f5c749a8c9208">Zooming can also be done by using the scroll wheel.</li>
<li data-list-item-id="e7b87c55d329003996861f24d8d162b85">The zoom and position on the preview will remain fixed as the diagram
changes, to be able to work more easily with large diagrams.</li>
</ul>
</li>
<li>The size of the source/preview panes can be adjusted by hovering over
<li data-list-item-id="e11cf4ecd9d2408ce5a46b949dea40b06">The size of the source/preview panes can be adjusted by hovering over
the border between them and dragging it with the mouse.</li>
<li>In the&nbsp;<a class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons</a>&nbsp;area:
<li data-list-item-id="ebc96b0fe8366ef4e00561de1c866d53b">In the&nbsp;<a class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons</a>&nbsp;area:
<ul>
<li>The source/preview can be laid out left-right or bottom-top via the <em>Move editing pane to the left / bottom</em> option.</li>
<li>Press <em>Lock editing</em> to automatically mark the note as read-only.
<li data-list-item-id="e12f31dc31db3c8be1fe87822ca2f451e">The source/preview can be laid out left-right or bottom-top via the <em>Move editing pane to the left / bottom</em> option.</li>
<li
data-list-item-id="ed29e7616e6c77105103a68b1e8a6f7b3">Press <em>Lock editing</em> to automatically mark the note as read-only.
In this mode, the code pane is hidden and the diagram is displayed full-size.
Similarly, press <em>Unlock editing</em> to mark a read-only note as editable.</li>
<li>Press the <em>Copy image reference to the clipboard</em> to be able to insert
the image representation of the diagram into a text note. See&nbsp;<a class="reference-link"
href="#root/_help_0Ofbk1aSuVRu">Image references</a>&nbsp;for more information.</li>
<li>Press the <em>Export diagram as SVG</em> to download a scalable/vector rendering
of the diagram. Can be used to present the diagram without degrading when
zooming.</li>
<li>Press the <em>Export diagram as PNG</em> to download a normal image (at
<li
data-list-item-id="e2bc7d5d8d1f8f02e61a6d86a3faae3b4">Press the <em>Copy image reference to the clipboard</em> to be able to insert
the image representation of the diagram into a text note. See&nbsp;<a class="reference-link"
href="#root/_help_0Ofbk1aSuVRu">Image references</a>&nbsp;for more information.</li>
<li
data-list-item-id="ecaac01dc52bce394f720be2826e82026">Press the <em>Export diagram as SVG</em> to download a scalable/vector rendering
of the diagram. Can be used to present the diagram without degrading when
zooming.</li>
<li data-list-item-id="e9c815090884a394d60e06628b9e38add">Press the <em>Export diagram as PNG</em> to download a normal image (at
1x scale, raster) of the diagram. Can be used to send the diagram in more
traditional channels such as e-mail.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Errors in the diagram</h2>
<p>If there is an error in the source code, the error will be displayed in

View File

@ -1,4 +1,4 @@
import { BNote } from "../../services/backend_script_entrypoint";
import BNote from '../../becca/entities/bnote.js';
import cls from "../../services/cls";
import { buildNote } from "../../test/becca_easy_mocking";
import { processContent } from "./clipper";

View File

@ -1,33 +0,0 @@
import type { Application } from "express";
import swaggerUi from "swagger-ui-express";
import { join } from "path";
import yaml from "js-yaml";
import type { JsonObject } from "swagger-ui-express";
import { readFileSync } from "fs";
import { RESOURCE_DIR } from "../services/resource_dir";
export default function register(app: Application) {
const etapiDocument = yaml.load(readFileSync(join(RESOURCE_DIR, "etapi.openapi.yaml"), "utf8")) as JsonObject;
// Load the comprehensive API documentation from YAML
const apiDocument = yaml.load(readFileSync(join(RESOURCE_DIR, "api-openapi.yaml"), "utf8")) as JsonObject;
app.use(
"/etapi/docs/",
swaggerUi.serveFiles(etapiDocument),
swaggerUi.setup(etapiDocument, {
explorer: true,
customSiteTitle: "TriliumNext ETAPI Documentation"
})
);
app.use(
"/api/docs/",
swaggerUi.serveFiles(apiDocument),
swaggerUi.setup(apiDocument, {
explorer: true,
customSiteTitle: "TriliumNext Internal API Documentation",
customCss: '.swagger-ui .topbar { display: none }'
})
);
}

View File

@ -70,7 +70,6 @@ import etapiSpecialNoteRoutes from "../etapi/special_notes.js";
import etapiSpecRoute from "../etapi/spec.js";
import etapiBackupRoute from "../etapi/backup.js";
import etapiMetricsRoute from "../etapi/metrics.js";
import apiDocsRoute from "./api_docs.js";
import { apiResultHandler, apiRoute, asyncApiRoute, asyncRoute, route, router, uploadMiddlewareWithErrorHandling } from "./route_api.js";
const GET = "get",
@ -383,9 +382,6 @@ function register(app: express.Application) {
asyncApiRoute(GET, "/api/llm/providers/openai/models", openaiRoute.listModels);
asyncApiRoute(GET, "/api/llm/providers/anthropic/models", anthropicRoute.listModels);
// API Documentation
apiDocsRoute(app);
app.use("", router);
}

View File

@ -1,37 +0,0 @@
/**
* The backend script API is accessible to code notes with the "JS (backend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Backend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note on the server side.
*
* Make sure to keep in line with backend's `script_context.ts`.
*/
export type { default as AbstractBeccaEntity } from "../becca/entities/abstract_becca_entity.js";
export type { default as BAttachment } from "../becca/entities/battachment.js";
export type { default as BAttribute } from "../becca/entities/battribute.js";
export type { default as BBranch } from "../becca/entities/bbranch.js";
export type { default as BEtapiToken } from "../becca/entities/betapi_token.js";
export type { BNote };
export type { default as BOption } from "../becca/entities/boption.js";
export type { default as BRecentNote } from "../becca/entities/brecent_note.js";
export type { default as BRevision } from "../becca/entities/brevision.js";
import BNote from "../becca/entities/bnote.js";
import type { Api } from "./backend_script_api.js";
import BackendScriptApi from "./backend_script_api.js";
export type { Api };
const fakeNote = new BNote();
/**
* The `code` api global variable allows access to the backend script API, which is documented in {@link Api}.
*/
export const api: Api = new BackendScriptApi(fakeNote, {});

View File

@ -98,6 +98,21 @@ describe("Hidden Subtree", () => {
expect(updatedBoardTemplate?.title).not.toBe("My renamed board");
});
it("enforces webviewSrc of templates", () => {
const apiRefNote = becca.getNote("_help_9qPsTWBorUhQ");
expect(apiRefNote).toBeDefined();
cls.init(() => {
apiRefNote!.setAttribute("label", "webViewSrc", "foo");
apiRefNote!.save();
hiddenSubtreeService.checkHiddenSubtree(true);
});
const updatedApiRefNote = becca.getNote("_help_9qPsTWBorUhQ");
expect(updatedApiRefNote).toBeDefined();
expect(updatedApiRefNote?.getLabelValue("webViewSrc")).not.toBe("foo");
});
it("maintains launchers hidden, if they were shown by default but moved by the user", () => {
const launcher = becca.getNote("_lbLlmChat");
const branch = launcher?.getParentBranches()[0];

View File

@ -451,8 +451,16 @@ 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)) {
// Remove unwanted attributes.
const attrDef = attrs.find(a => a.name === attribute.name);
if (!attrDef) {
attribute.markAsDeleted();
continue;
}
// Ensure value is consistent.
if (attribute.value !== attrDef.value) {
note.setAttributeValueById(attribute.attributeId, attrDef.value);
}
}
}

View File

@ -78,6 +78,7 @@ export function parseNoteMeta(noteMeta: NoteMeta, docNameRoot: string): HiddenSu
// Handle web views
if (noteMeta.type === "webView") {
item.type = "webView";
item.enforceAttributes = true;
}
// Handle children

View File

@ -9,7 +9,7 @@ import log from '../../log.js';
import becca from '../../../becca/becca.js';
import notes from '../../notes.js';
import attributes from '../../attributes.js';
import type { BNote } from '../../backend_script_entrypoint.js';
import BNote from '../../../becca/entities/bnote.js';
/**
* Definition of the note creation tool

View File

@ -9,7 +9,7 @@ import searchService from "./search/services/search.js";
import SearchContext from "./search/search_context.js";
import { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } from "./hidden_subtree.js";
import { t } from "i18next";
import { BNote } from "./backend_script_entrypoint.js";
import BNote from '../becca/entities/bnote.js';
import { SaveSearchNoteResponse, SaveSqlConsoleResponse } from "@triliumnext/commons";
function getInboxNote(date: string) {

View File

@ -16,7 +16,7 @@ import { join } from "path";
import { readFileSync } from "fs";
import { highlightAuto } from "@triliumnext/highlightjs";
import becca from "../becca/becca.js";
import { BAttachment } from "../services/backend_script_entrypoint.js";
import BAttachment from '../becca/entities/battachment.js';
import SAttachment from "./shaca/entities/sattachment.js";
import { sanitizeUrl } from "@braintree/sanitize-url";

View File

@ -1 +1,37 @@
{}
{
"get-started": {
"title": "Для начала",
"desktop_title": "Установите приложение для ПК (v{{version}})",
"architecture": "Архитектура:",
"older_releases": "См. старые релизы",
"server_title": "Настройка сервера для работы с нескольких устройств"
},
"hero_section": {
"title": "Упорядочите свои мысли. Создайте личную базу знаний.",
"subtitle": "Trilium - это open-source решение для ведение заметок и организации личной базы знаний. Используйте его локально на своём ПК, или синхронизируйтесь с собственным сервером, чтобы ваши заметки всегда были с вами.",
"get_started": "Для начала",
"github": "GitHub",
"dockerhub": "Docker Hub",
"screenshot_alt": "Скриншот приложения Trilium Notes для ПК"
},
"organization_benefits": {
"title": "Структура",
"note_structure_title": "Структура заметки",
"note_structure_description": "Строки могут распологаться иерархически. Не нужно постоянно создавать папки, так как каждая заметка может содержать вложенные под-заметки. Одну и ту же заметку можно добавить сразу в несколько мест в иерархии.",
"attributes_title": "Ярлыки и связи заметок",
"hoisting_title": "Рабочие пространства и хосты",
"hoisting_description": "Легко разделяйте заметки на личные и рабочие, группируя их в рабочей области. Благодаря этому в вашем дереве будет отображаться только определённый набор заметок."
},
"productivity_benefits": {
"revisions_content": "Заметки периодически сохраняются в фоне, ревизии могут быть использованы для просмотра или отмены случайных изменений. Ревизии также можно создавать самостоятельно.",
"sync_title": "Синхронизация",
"protected_notes_title": "Защищённые заметки",
"jump_to_title": "Бастрый поиск и команды",
"search_title": "Глубокий поиск",
"web_clipper_content": "Перемещайте целые веб-страницы (или скриншоты) в Trilium с помощью браузерного расширения web clipper."
},
"note_types": {
"title": "Несколько способов представления вашей информации",
"text_title": "Текстовые заметки"
}
}

181
docs/README-ru.md vendored
View File

@ -11,19 +11,19 @@
# Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran)
![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\
![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium)
![GitHub Downloads (all assets, all
![Спонсоры GitHub](https://img.shields.io/github/sponsors/eliandoran) ![Меценаты
LiberaPay ](https://img.shields.io/liberapay/patrons/ElianDoran)\
![Загрузок Docker](https://img.shields.io/docker/pulls/triliumnext/trilium)
![Загрузок GitHub (all assets, all
releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\
[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp)
[![Translation
status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/)
[![Процесс
перевода](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/)
[English](./README.md) | [Chinese (Simplified)](./docs/README-ZH_CN.md) |
[Chinese (Traditional)](./docs/README-ZH_TW.md) | [Russian](./docs/README-ru.md)
| [Japanese](./docs/README-ja.md) | [Italian](./docs/README-it.md) |
[Spanish](./docs/README-es.md)
[Английский](./README.md) | [Китайский (Упрощенный)](./docs/README-ZH_CN.md) |
[Китайский (Традиционный)](./docs/README-ZH_TW.md) |
[Русский](./docs/README-ru.md) | [Японский](./docs/README-ja.md) |
[Итальянский](./docs/README-it.md) | [Испанский](./docs/README-es.md)
Trilium Notes это приложение для заметок с иерархической структурой,
ориентированное на создание больших персональных баз знаний.
@ -33,38 +33,38 @@ Trilium Notes это приложение для заметок с иера
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
## ⏬ Download
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest)
stable version, recommended for most users.
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly)
unstable development version, updated daily with the latest features and
fixes.
## ⏬ Загрузка
- [Последний релиз](https://github.com/TriliumNext/Trilium/releases/latest)
стабильная версия, подойдёт для большинства пользователей.
- [Ночной билд](https://github.com/TriliumNext/Trilium/releases/tag/nightly)
нестабильная разрабатываемая версия, ежедневно получает новые функции и
исправления.
## 📚 Документация
**Visit our comprehensive documentation at
**Полная документация по адресу
[docs.triliumnotes.org](https://docs.triliumnotes.org/)**
Our documentation is available in multiple formats:
- **Online Documentation**: Browse the full documentation at
Документация доступна в нескольких форматах:
- **Онлайн Документация**: Полная документация доступна по адресу:
[docs.triliumnotes.org](https://docs.triliumnotes.org/)
- **In-App Help**: Press `F1` within Trilium to access the same documentation
directly in the application
- **Справка в приложении**: Нажмите`F1` в Trilium для доступа к этой
документации прямо в приложении
- **GitHub**: Navigate through the [User
Guide](./docs/User%20Guide/User%20Guide/) in this repository
### Quick Links
- [Getting Started Guide](https://docs.triliumnotes.org/)
- [Installation
Instructions](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md)
- [Docker
Setup](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
- [Upgrading
### Важные Ссылки
- [Руководство по началу работы](https://docs.triliumnotes.org/)
- [Инструкция по
установке](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md)
- [Установка
Docker](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
- [Обновление
TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
- [Basic Concepts and
Features](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
- [Patterns of Personal Knowledge
Base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
- [Основные идеи и
возможности](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
- [Шаблоны Персональный Базы
Знаний](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
## 🎁 Возможности
@ -88,11 +88,11 @@ Our documentation is available in multiple formats:
* Специальные [атрибуты](https://triliumnext.github.io/Docs/Wiki/attributes)
позволяют гибко организовать структуру, используются для поиска и продвинутого
[скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts)
* UI available in English, German, Spanish, French, Romanian, and Chinese
(simplified and traditional)
* Direct [OpenID and TOTP
* Интерфейс доступен на Английском, Немецком, Испанском, Французском, Румынском
и Китайском (упрощённом и традиционном)
* Интеграция [OpenID and TOTP
integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md)
for more secure login
для более безопасного входа
* [Синхронизация](https://triliumnext.github.io/Docs/Wiki/synchronization)
заметок со своим сервером
* there's a [3rd party service for hosting synchronisation
@ -223,20 +223,20 @@ installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation).
## 💻 Участвуйте в разработке
### Translations
### Переводы
If you are a native speaker, help us translate Trilium by heading over to our
[Weblate page](https://hosted.weblate.org/engage/trilium/).
Если вы являетесь носителем языка, помогите нам перевести Trilium, перейдя на
нашу [страницу Weblate](https://hosted.weblate.org/engage/trilium/).
Here's the language coverage we have so far:
Что сделано на данный момент:
[![Translation
status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/)
[![Статус
перевода](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/)
### Code
### Код
Download the repository, install dependencies using `pnpm` and then run the
server (available at http://localhost:8080):
Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем запустите
сервер (доступен по адресу http://localhost:8080):
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
@ -244,10 +244,10 @@ pnpm install
pnpm run server:start
```
### Documentation
### Документация
Download the repository, install dependencies using `pnpm` and then run the
environment required to edit the documentation:
Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем запустите
окружение, необходимое для редактирование документации:
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
@ -255,9 +255,9 @@ pnpm install
pnpm edit-docs:edit-docs
```
### Building the Executable
Download the repository, install dependencies using `pnpm` and then build the
desktop app for Windows:
### Сборка исполняемого файла
Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем соберите
приложение для Windows:
```shell
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
@ -265,10 +265,10 @@ pnpm install
pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32
```
For more details, see the [development
docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide).
Для получения подробностей, смотрите [документы
разработки](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide).
### Developer Documentation
### Документация для разработчиков
Please view the [documentation
guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)
@ -277,48 +277,49 @@ described in the "Discuss with us" section above.
## 👏 Благодарности
* [zadam](https://github.com/zadam) for the original concept and implementation
of the application.
* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the
application icon.
* [nriver](https://github.com/nriver) for his work on internationalization.
* [zadam](https://github.com/zadam) за оригинальный концепт и реализацию
приложения.
* [Sarah Hussein](https://github.com/Sarah-Hussein) за создание иконки
приложения.
* [nriver](https://github.com/nriver) за работу по интернационализации.
* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas.
* [antoniotejada](https://github.com/nriver) for the original syntax highlight
widget.
* [Dosu](https://dosu.dev/) for providing us with the automated responses to
GitHub issues and discussions.
* [Tabler Icons](https://tabler.io/icons) for the system tray icons.
* [antoniotejada](https://github.com/nriver) за оригинальный виджет подсветки
синтаксиса.
* [Dosu](https://dosu.dev/) за обеспечение автоматических ответов на вопросы и
обсуждения GitHub.
* [Tabler Icons](https://tabler.io/icons) за системные иконки.
Trilium would not be possible without the technologies behind it:
Trilium не существовал бы без технологий, лежащих в его основе:
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind
text notes. We are grateful for being offered a set of the premium features.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with
support for huge amount of languages.
* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite
whiteboard used in Canvas notes.
* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the
mind map functionality.
* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical
maps.
* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive
table used in collections.
* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library
without real competition.
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library.
Used in [relation
maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link
maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - визуальный редактор
текстовых заметок. Мы благодарны за предоставленный нам набор дополнительный
функций.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - редактор кода с
поддержкой огромного количества языков.
* [Excalidraw](https://github.com/excalidraw/excalidraw) - бесконечная белая
доска, используемая в заметках Canvas.
* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - обеспечивает
функционирование ментальной карты.
* [Leaflet](https://github.com/Leaflet/Leaflet) - отображение географических
карт.
* [Tabulator](https://github.com/olifolkerd/tabulator) - интерактивные таблицы,
используемые в коллекциях.
* [FancyTree](https://github.com/mar10/fancytree) - многофункциональная
библиотека деревьев, не имеющая себе равных.
* [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека визуальных связей.
Используется в [картах
связей](https://triliumnext.github.io/Docs/Wiki/relation-map.html) и [картах
ссылок](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)
## 🤝 Support
## 🤝 Поддержка
Trilium is built and maintained with [hundreds of hours of
work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your
support keeps it open-source, improves features, and covers costs such as
hosting.
На создание и поддержку Trilium затрачены [сотни часов
работы](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Ваша
поддержка помогает ему оставаться open-source, улучшает функции и покрывает
расходы, такие как хостинг.
Consider supporting the main developer
([eliandoran](https://github.com/eliandoran)) of the application via:
Вы также можете поддержать главного разработчика приложения
([eliandoran](https://github.com/eliandoran)) с помощью:
- [GitHub Sponsors](https://github.com/sponsors/eliandoran)
- [PayPal](https://paypal.me/eliandoran)

View File

@ -8838,6 +8838,13 @@
"value": "bx bx-selection",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "WWgeUaBb7UfC",
"isInheritable": false,
"position": 30
}
],
"format": "markdown",
@ -8921,6 +8928,33 @@
"dataFileName": "ELK layout_ELK on.svg"
}
]
},
{
"isClone": false,
"noteId": "WWgeUaBb7UfC",
"notePath": [
"pOsGYCXsbNQG",
"KSZ04uQ2D1St",
"s1aBHPd79XYj",
"WWgeUaBb7UfC"
],
"title": "Syntax reference",
"notePosition": 40,
"prefix": null,
"isExpanded": false,
"type": "webView",
"mime": "",
"attributes": [
{
"type": "label",
"name": "webViewSrc",
"value": "https://mermaid.js.org/intro/syntax-reference.html",
"isInheritable": false,
"position": 10
}
],
"dataFileName": "Syntax reference.dat",
"attachments": []
}
]
},
@ -12568,6 +12602,13 @@
"value": "bx bx-extension",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "9qPsTWBorUhQ",
"isInheritable": false,
"position": 40
}
],
"format": "markdown",
@ -12594,7 +12635,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "/etapi/docs",
"value": "/rest-api/etapi/",
"isInheritable": false,
"position": 10
},
@ -13612,7 +13653,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "/api/docs",
"value": "/rest-api/internal/",
"isInheritable": false,
"position": 10
},
@ -14968,7 +15009,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html",
"value": "/script-api/frontend",
"isInheritable": false,
"position": 10
},
@ -15003,7 +15044,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/classes/Frontend_Script_API.FNote.html",
"value": "/script-api/frontend/interfaces/FNote.html",
"isInheritable": false,
"position": 10
},
@ -15039,7 +15080,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html",
"value": "/script-api/backend",
"isInheritable": false,
"position": 10
},

View File

@ -1,7 +1,8 @@
# ETAPI (REST API)
ETAPI is Trilium's public/external REST API. It is available since Trilium v0.50.
> [!TIP]
> For a quick start, consult the <a class="reference-link" href="ETAPI%20(REST%20API)/API%20Reference.dat">API Reference</a>.
The documentation is in OpenAPI format, available [here](https://github.com/TriliumNext/Trilium/blob/master/src/etapi/etapi.openapi.yaml).
ETAPI is Trilium's public/external REST API. It is available since Trilium v0.50.
## API clients

View File

@ -1,10 +1,11 @@
# Mermaid Diagrams
> [!TIP]
> For a quick understanding of the Mermaid syntax, see <a class="reference-link" href="Mermaid%20Diagrams/Syntax%20reference.dat">Syntax reference</a> (official documentation).
<figure class="image image-style-align-center"><img style="aspect-ratio:886/663;" src="2_Mermaid Diagrams_image.png" width="886" height="663"></figure>
Trilium supports Mermaid, which adds support for various diagrams such as flowchart, sequence diagram, class diagram, state diagram, pie charts, etc., all using a text description of the chart instead of manually drawing the diagram.
For the official documentation of Mermaid.js see [mermaid.js.org/intro/](https://mermaid.js.org/intro/).
## Layouts
Depending on the chart being edited and user preference, there are two layouts supported by the Mermaid note type:

View File

@ -26,7 +26,7 @@
"chore:generate-openapi": "tsx ./scripts/generate-openapi.ts",
"chore:update-build-info": "tsx ./scripts/update-build-info.ts",
"chore:update-version": "tsx ./scripts/update-version.ts",
"docs:build": "pnpm run --filter share-theme build && cd ./apps/edit-docs && tsx ./src/build-docs.ts",
"docs:build": "pnpm run --filter build-docs start",
"edit-docs:edit-docs": "pnpm run --filter edit-docs edit-docs",
"edit-docs:edit-demo": "pnpm run --filter edit-docs edit-demo",
"test:all": "pnpm test:parallel && pnpm test:sequential",

View File

@ -32,7 +32,6 @@
"devDependencies": {
"@digitak/esrun": "3.2.26",
"@triliumnext/ckeditor5": "workspace:*",
"@types/swagger-ui": "5.21.1",
"@typescript-eslint/eslint-plugin": "8.46.2",
"@typescript-eslint/parser": "8.46.2",
"dotenv": "17.2.3",

View File

@ -54,17 +54,25 @@ body:not(.math-loaded) .math-tex {
visibility: hidden;
}
body.type-webView #main {
max-width: unset;
}
body.type-webView {
#main {
max-width: unset;
padding: 0;
}
body.type-webView #content {
display: flex;
flex-direction: column;
height: 100%;
}
#content {
display: flex;
flex-direction: column;
height: 100%;
iframe.webview {
width: 100%;
flex-grow: 1;
h1 {
display: none;
}
iframe.webview {
width: 100%;
flex-grow: 1;
border: 0;
}
}
}

1478
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff