Merge branch 'main' into electron_newwindow
Some checks failed
Checks / main (push) Has been cancelled

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", "lorem-ipsum": "2.0.8",
"rcedit": "4.0.1", "rcedit": "4.0.1",
"rimraf": "6.1.0", "rimraf": "6.1.0",
"tslib": "2.8.1", "tslib": "2.8.1"
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
}, },
"optionalDependencies": { "optionalDependencies": {
"appdmg": "0.6.6" "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 cls from "@triliumnext/server/src/services/cls.js";
import { dirname, join, resolve } from "path"; import { dirname, join, resolve } from "path";
import fs, { copyFile } from "fs/promises"; import * as fs from "fs/promises";
import fsExtra, { createWriteStream, type WriteStream } from "fs-extra"; import * as fsExtra from "fs-extra";
import archiver from "archiver"; import archiver from "archiver";
import { WriteStream } from "fs";
import { execSync } from "child_process";
import BuildContext from "./context.js";
const DOCS_ROOT = "../../../docs"; const DOCS_ROOT = "../../../docs";
const OUTPUT_DIR = "../../site"; const OUTPUT_DIR = "../../site";
async function main() { async function buildDocsInner() {
const i18n = await import("@triliumnext/server/src/services/i18n.js"); const i18n = await import("@triliumnext/server/src/services/i18n.js");
await i18n.initializeTranslations(); await i18n.initializeTranslations();
@ -30,7 +33,7 @@ async function main() {
"export", "export",
null null
); );
const fileOutputStream = createWriteStream(zipFilePath); const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
await exportToZip(taskContext, branch, "share", fileOutputStream); await exportToZip(taskContext, branch, "share", fileOutputStream);
await waitForStreamToFinish(fileOutputStream); await waitForStreamToFinish(fileOutputStream);
await extractZip(zipFilePath, OUTPUT_DIR); await extractZip(zipFilePath, OUTPUT_DIR);
@ -41,7 +44,7 @@ async function main() {
} }
// Copy favicon. // 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!"); 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, file: null,
image: null, image: null,
launcher: null, launcher: null,
mermaid: null, mermaid: "s1aBHPd79XYj",
mindMap: null, mindMap: null,
noteMap: null, noteMap: null,
relationMap: null, relationMap: null,

View File

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

View File

@ -1289,10 +1289,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI 是一个 REST API用于以编程方式访问 Trilium 实例,而无需 UI。", "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 令牌", "create_token": "创建新的 ETAPI 令牌",
"existing_tokens": "现有令牌", "existing_tokens": "现有令牌",
"no_tokens_yet": "目前还没有令牌。点击上面的按钮创建一个。", "no_tokens_yet": "目前还没有令牌。点击上面的按钮创建一个。",

View File

@ -1286,10 +1286,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI ist eine REST-API, die für den programmgesteuerten Zugriff auf die Trilium-Instanz ohne Benutzeroberfläche verwendet wird.", "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", "create_token": "Erstelle ein neues ETAPI-Token",
"existing_tokens": "Vorhandene Token", "existing_tokens": "Vorhandene Token",
"no_tokens_yet": "Es sind noch keine Token vorhanden. Klicke auf die Schaltfläche oben, um eine zu erstellen.", "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": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI is a REST API used to access Trilium instance programmatically, without UI.", "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", "create_token": "Create new ETAPI token",
"existing_tokens": "Existing tokens", "existing_tokens": "Existing tokens",
"no_tokens_yet": "There are no tokens yet. Click on the button above to create one.", "no_tokens_yet": "There are no tokens yet. Click on the button above to create one.",

View File

@ -1446,10 +1446,6 @@
"etapi": { "etapi": {
"title": "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.", "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", "create_token": "Crear nuevo token ETAPI",
"existing_tokens": "Tokens existentes", "existing_tokens": "Tokens existentes",
"no_tokens_yet": "Aún no hay tokens. Dé clic en el botón de arriba para crear uno.", "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": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI est une API REST utilisée pour accéder à l'instance Trilium par programme, sans interface utilisateur.", "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", "create_token": "Créer un nouveau jeton ETAPI",
"existing_tokens": "Jetons existants", "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.", "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", "delete_token": "Supprimer/désactiver ce token",
"rename_token_title": "Renommer le jeton", "rename_token_title": "Renommer le jeton",
"rename_token_message": "Veuillez saisir le nom du nouveau 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}} » ?", "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"
}, },
"options_widget": { "options_widget": {
"options_status": "Statut des options", "options_status": "Statut des options",

View File

@ -132,10 +132,6 @@
"new_token_message": "Inserisci il nome del nuovo token", "new_token_message": "Inserisci il nome del nuovo token",
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI è un'API REST utilizzata per accedere alle istanze di Trilium in modo programmatico, senza interfaccia utente.", "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", "create_token": "Crea un nuovo token ETAPI",
"existing_tokens": "Token esistenti", "existing_tokens": "Token esistenti",
"no_tokens_yet": "Non ci sono ancora token. Clicca sul pulsante qui sopra per crearne uno.", "no_tokens_yet": "Non ci sono ancora token. Clicca sul pulsante qui sopra per crearne uno.",

View File

@ -657,10 +657,6 @@
"created": "作成日時", "created": "作成日時",
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI は、Trilium インスタンスに UI なしでプログラム的にアクセスするための REST API です。", "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トークンを作成", "create_token": "新しくETAPIトークンを作成",
"existing_tokens": "既存のトークン", "existing_tokens": "既存のトークン",
"no_tokens_yet": "トークンはまだありません。上のボタンをクリックして作成してください。", "no_tokens_yet": "トークンはまだありません。上のボタンをクリックして作成してください。",

View File

@ -1663,10 +1663,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI to interfejs API REST używany do programowego dostępu do instancji Trilium, bez interfejsu użytkownika.", "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", "create_token": "Utwórz nowy token ETAPI",
"existing_tokens": "Istniejące tokeny", "existing_tokens": "Istniejące tokeny",
"no_tokens_yet": "Nie ma jeszcze żadnych tokenów. Kliknij przycisk powyżej, aby utworzyć jeden.", "no_tokens_yet": "Nie ma jeszcze żadnych tokenów. Kliknij przycisk powyżej, aby utworzyć jeden.",

View File

@ -1422,10 +1422,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI é uma API REST usada para aceder a instância do Trilium programaticamente, sem interface gráfica.", "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", "create_token": "Criar token ETAPI",
"existing_tokens": "Tokens existentes", "existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.", "no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.",

View File

@ -1932,10 +1932,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI é uma API REST usada para acessar a instância do Trilium programaticamente, sem interface gráfica.", "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", "create_token": "Criar novo token ETAPI",
"existing_tokens": "Tokens existentes", "existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.", "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_message": "Introduceți denumirea noului token",
"new_token_title": "Token ETAPI nou", "new_token_title": "Token ETAPI nou",
"no_tokens_yet": "Nu există încă token-uri. Clic pe butonul de deasupra pentru a crea una.", "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": "Redenumește token-ul",
"rename_token_message": "Introduceți denumirea noului token", "rename_token_message": "Introduceți denumirea noului token",
"rename_token_title": "Redenumire 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", "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_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_created_title": "Token ETAPI creat",
"token_name": "Denumire token", "token_name": "Denumire token"
"wiki": "wiki"
}, },
"execute_script": { "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:", "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": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"wiki": "вики",
"created": "Создано", "created": "Создано",
"actions": "Действия", "actions": "Действия",
"existing_tokens": "Существующие токены", "existing_tokens": "Существующие токены",
@ -1448,10 +1447,7 @@
"default_token_name": "новый токен", "default_token_name": "новый токен",
"rename_token_title": "Переименовать токен", "rename_token_title": "Переименовать токен",
"description": "ETAPI — это REST API, используемый для программного доступа к экземпляру Trilium без пользовательского интерфейса.", "description": "ETAPI — это REST API, используемый для программного доступа к экземпляру Trilium без пользовательского интерфейса.",
"see_more": "Более подробную информацию смотрите в {{- link_to_wiki}} и {{- link_to_openapi_spec}} или {{- link_to_swagger_ui }}.",
"create_token": "Создать новый токен ETAPI", "create_token": "Создать новый токен ETAPI",
"openapi_spec": "Спецификация ETAPI OpenAPI",
"swagger_ui": "Пользовательский интерфейс ETAPI Swagger",
"new_token_title": "Новый токен ETAPI", "new_token_title": "Новый токен ETAPI",
"token_created_title": "Создан токен ETAPI", "token_created_title": "Создан токен ETAPI",
"rename_token": "Переименовать этот токен", "rename_token": "Переименовать этот токен",

View File

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

View File

@ -1402,10 +1402,6 @@
"etapi": { "etapi": {
"title": "ETAPI", "title": "ETAPI",
"description": "ETAPI — це REST API, який використовується для програмного доступу до екземпляра Trilium без інтерфейсу користувача.", "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", "create_token": "Створити новий токен ETAPI",
"existing_tokens": "Існуючі токени", "existing_tokens": "Існуючі токени",
"no_tokens_yet": "Токенів поки що немає. Натисніть кнопку вище, щоб створити його.", "no_tokens_yet": "Токенів поки що немає. Натисніть кнопку вище, щоб створити його.",

View File

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

View File

@ -11,6 +11,7 @@ import dialog from "../../../services/dialog";
import { formatDateTime } from "../../../utils/formatters"; import { formatDateTime } from "../../../utils/formatters";
import ActionButton from "../../react/ActionButton"; import ActionButton from "../../react/ActionButton";
import { useTriliumEvent } from "../../react/hooks"; import { useTriliumEvent } from "../../react/hooks";
import HelpButton from "../../react/HelpButton";
type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>; type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>;
type DeleteTokenCallback = (tokenId: string, name: 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"), message: t("etapi.token_created_message"),
defaultValue: authToken defaultValue: authToken
}); });
}, []); }, []);
return ( return (
<OptionsSection title={t("etapi.title")}> <OptionsSection title={t("etapi.title")}>
<FormText> <FormText>
{t("etapi.description")}<br /> {t("etapi.description")}
<RawHtml <HelpButton helpPage="pgxEVkzLl1OP" />
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>`
})} />
</FormText> </FormText>
<Button <Button
@ -68,6 +63,7 @@ export default function EtapiSettings() {
text={t("etapi.create_token")} text={t("etapi.create_token")}
onClick={createTokenCallback} onClick={createTokenCallback}
/> />
<hr /> <hr />
<h5>{t("etapi.existing_tokens")}</h5> <h5>{t("etapi.existing_tokens")}</h5>
@ -123,7 +119,7 @@ function TokenList({ tokens }: { tokens: EtapiToken[] }) {
text={t("etapi.rename_token")} text={t("etapi.rename_token")}
onClick={() => renameCallback(etapiTokenId, name)} onClick={() => renameCallback(etapiTokenId, name)}
/> />
<ActionButton <ActionButton
icon="bx bx-trash" icon="bx bx-trash"
text={t("etapi.delete_token")} 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."); throw new Error("Missing DOCS_ROOT or USER_GUIDE_ROOT environment variable.");
} }
const BASE_URL = "https://docs.triliumnotes.org";
const NOTE_MAPPINGS: NoteMapping[] = [ const NOTE_MAPPINGS: NoteMapping[] = [
{ {
rootNoteId: "pOsGYCXsbNQG", rootNoteId: "pOsGYCXsbNQG",
@ -158,6 +160,14 @@ async function cleanUpMeta(outputPath: string, minify: boolean) {
} }
el.isExpanded = false; 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) { if (minify) {

View File

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

View File

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

View File

@ -61,7 +61,6 @@
"@types/serve-static": "2.2.0", "@types/serve-static": "2.2.0",
"@types/stream-throttle": "0.1.4", "@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.3", "@types/supertest": "6.0.3",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6", "@types/tmp": "0.2.6",
"@types/turndown": "5.0.6", "@types/turndown": "5.0.6",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
@ -123,7 +122,6 @@
"striptags": "3.2.0", "striptags": "3.2.0",
"supertest": "7.1.4", "supertest": "7.1.4",
"swagger-jsdoc": "6.2.8", "swagger-jsdoc": "6.2.8",
"swagger-ui-express": "5.0.1",
"time2fa": "1.4.2", "time2fa": "1.4.2",
"tmp": "0.2.5", "tmp": "0.2.5",
"turndown": "7.2.2", "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 <p>ETAPI is Trilium's public/external REST API. It is available since Trilium
v0.50.</p> 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> <h2>API clients</h2>
<p>As an alternative to calling the API directly, there are client libraries <p>As an alternative to calling the API directly, there are client libraries
to simplify this</p> to simplify this</p>
<ul> <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> use Python to communicate with Trilium.</li>
</ul> </ul>
<h2>Obtaining a token</h2> <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 <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> Authorization: Basic BATOKEN</code></pre>
<ul> <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> a standard Basic Auth serialization</li>
<li>Where <code>username</code> is "etapi"</li> <li data-list-item-id="e18e2e73ebecc949dd4a51cd9f8bb0b91">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="ee892223f95cef4a53caec5477ab31edb">And <code>password</code> is the generated ETAPI token described above.</li>
</ul> </ul>
<p>Basic Auth is meant to be used with tools which support only basic auth.</p> <p>Basic Auth is meant to be used with tools which support only basic auth.</p>
<h2>Interaction using Bash scripts</h2> <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> curl "$SERVER/etapi/notes/$NOTE_ID/content" -H "Authorization: $TOKEN" </code></pre>
<p>Make sure to replace the values of:</p> <p>Make sure to replace the values of:</p>
<ul> <ul>
<li><code>TOKEN</code> with your ETAPI token.</li> <li data-list-item-id="e68020f83acc951e180bb405d149a64a5"><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="ef4c31df5f6d18811e7de0ee8ff95f3a7"><code>SERVER</code> with the correct protocol, host name and port to your
Trilium instance.</li> 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> </ul>
<p>As another example, to obtain a .zip export of a note and place it in <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 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"> <figure class="image image-style-align-center">
<img style="aspect-ratio:886/663;" src="2_Mermaid Diagrams_image.png" <img style="aspect-ratio:886/663;" src="2_Mermaid Diagrams_image.png"
width="886" height="663"> width="886" height="663">
@ -6,14 +11,13 @@
as flowchart, sequence diagram, class diagram, state diagram, pie charts, as flowchart, sequence diagram, class diagram, state diagram, pie charts,
etc., all using a text description of the chart instead of manually drawing etc., all using a text description of the chart instead of manually drawing
the diagram.</p> 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> <h2>Layouts</h2>
<p>Depending on the chart being edited and user preference, there are two <p>Depending on the chart being edited and user preference, there are two
layouts supported by the Mermaid note type:</p> layouts supported by the Mermaid note type:</p>
<ul> <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> 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> preview is at the top.</li>
</ul> </ul>
<p>It's possible to switch between the two layouts at any time by pressing <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> <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> <h2>Interaction</h2>
<ul> <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). left or bottom side of the note (depending on the layout).
<ul> <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> </ul>
</li> </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): note (depending on the layout):
<ul> <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: the zoom in, zoom out or re-center the diagram:
<img src="1_Mermaid Diagrams_image.png"> <img src="1_Mermaid Diagrams_image.png">
</li> </li>
<li>The preview can be moved around by holding the left mouse button and dragging.</li> <li data-list-item-id="e51812ca016db170ceb6814007a60eb10">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
<li>The zoom and position on the preview will remain fixed as the diagram data-list-item-id="e617128e494ed43ca5d0f5c749a8c9208">Zooming can also be done by using the scroll wheel.</li>
changes, to be able to work more easily with large diagrams.</li> <li data-list-item-id="e7b87c55d329003996861f24d8d162b85">The zoom and position on the preview will remain fixed as the diagram
</ul> changes, to be able to work more easily with large diagrams.</li>
</ul>
</li> </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> 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> <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 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>Press <em>Lock editing</em> to automatically mark the note as read-only. <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. 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> 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 <li
the image representation of the diagram into a text note. See&nbsp;<a class="reference-link" data-list-item-id="e2bc7d5d8d1f8f02e61a6d86a3faae3b4">Press the <em>Copy image reference to the clipboard</em> to be able to insert
href="#root/_help_0Ofbk1aSuVRu">Image references</a>&nbsp;for more information.</li> the image representation of the diagram into a text note. See&nbsp;<a class="reference-link"
<li>Press the <em>Export diagram as SVG</em> to download a scalable/vector rendering href="#root/_help_0Ofbk1aSuVRu">Image references</a>&nbsp;for more information.</li>
of the diagram. Can be used to present the diagram without degrading when <li
zooming.</li> data-list-item-id="ecaac01dc52bce394f720be2826e82026">Press the <em>Export diagram as SVG</em> to download a scalable/vector rendering
<li>Press the <em>Export diagram as PNG</em> to download a normal image (at 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 1x scale, raster) of the diagram. Can be used to send the diagram in more
traditional channels such as e-mail.</li> traditional channels such as e-mail.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<h2>Errors in the diagram</h2> <h2>Errors in the diagram</h2>
<p>If there is an error in the source code, the error will be displayed in <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 cls from "../../services/cls";
import { buildNote } from "../../test/becca_easy_mocking"; import { buildNote } from "../../test/becca_easy_mocking";
import { processContent } from "./clipper"; 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 etapiSpecRoute from "../etapi/spec.js";
import etapiBackupRoute from "../etapi/backup.js"; import etapiBackupRoute from "../etapi/backup.js";
import etapiMetricsRoute from "../etapi/metrics.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"; import { apiResultHandler, apiRoute, asyncApiRoute, asyncRoute, route, router, uploadMiddlewareWithErrorHandling } from "./route_api.js";
const GET = "get", 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/openai/models", openaiRoute.listModels);
asyncApiRoute(GET, "/api/llm/providers/anthropic/models", anthropicRoute.listModels); asyncApiRoute(GET, "/api/llm/providers/anthropic/models", anthropicRoute.listModels);
// API Documentation
apiDocsRoute(app);
app.use("", router); 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"); 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", () => { it("maintains launchers hidden, if they were shown by default but moved by the user", () => {
const launcher = becca.getNote("_lbLlmChat"); const launcher = becca.getNote("_lbLlmChat");
const branch = launcher?.getParentBranches()[0]; const branch = launcher?.getParentBranches()[0];

View File

@ -451,8 +451,16 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
// Enforce attribute structure if needed. // Enforce attribute structure if needed.
if (item.enforceAttributes) { if (item.enforceAttributes) {
for (const attribute of note.getAttributes()) { 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(); 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 // Handle web views
if (noteMeta.type === "webView") { if (noteMeta.type === "webView") {
item.type = "webView"; item.type = "webView";
item.enforceAttributes = true;
} }
// Handle children // Handle children

View File

@ -9,7 +9,7 @@ import log from '../../log.js';
import becca from '../../../becca/becca.js'; import becca from '../../../becca/becca.js';
import notes from '../../notes.js'; import notes from '../../notes.js';
import attributes from '../../attributes.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 * 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 SearchContext from "./search/search_context.js";
import { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } from "./hidden_subtree.js"; import { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } from "./hidden_subtree.js";
import { t } from "i18next"; import { t } from "i18next";
import { BNote } from "./backend_script_entrypoint.js"; import BNote from '../becca/entities/bnote.js';
import { SaveSearchNoteResponse, SaveSqlConsoleResponse } from "@triliumnext/commons"; import { SaveSearchNoteResponse, SaveSqlConsoleResponse } from "@triliumnext/commons";
function getInboxNote(date: string) { function getInboxNote(date: string) {

View File

@ -16,7 +16,7 @@ import { join } from "path";
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import { highlightAuto } from "@triliumnext/highlightjs"; import { highlightAuto } from "@triliumnext/highlightjs";
import becca from "../becca/becca.js"; 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 SAttachment from "./shaca/entities/sattachment.js";
import { sanitizeUrl } from "@braintree/sanitize-url"; 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 # Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![Спонсоры GitHub](https://img.shields.io/github/sponsors/eliandoran) ![Меценаты
![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ LiberaPay ](https://img.shields.io/liberapay/patrons/ElianDoran)\
![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) ![Загрузок Docker](https://img.shields.io/docker/pulls/triliumnext/trilium)
![GitHub Downloads (all assets, all ![Загрузок GitHub (all assets, all
releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ 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) [![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) | [Английский](./README.md) | [Китайский (Упрощенный)](./docs/README-ZH_CN.md) |
[Chinese (Traditional)](./docs/README-ZH_TW.md) | [Russian](./docs/README-ru.md) [Китайский (Традиционный)](./docs/README-ZH_TW.md) |
| [Japanese](./docs/README-ja.md) | [Italian](./docs/README-it.md) | [Русский](./docs/README-ru.md) | [Японский](./docs/README-ja.md) |
[Spanish](./docs/README-es.md) [Итальянский](./docs/README-it.md) | [Испанский](./docs/README-es.md)
Trilium Notes это приложение для заметок с иерархической структурой, 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> <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) - [Последний релиз](https://github.com/TriliumNext/Trilium/releases/latest)
stable version, recommended for most users. стабильная версия, подойдёт для большинства пользователей.
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) - [Ночной билд](https://github.com/TriliumNext/Trilium/releases/tag/nightly)
unstable development version, updated daily with the latest features and нестабильная разрабатываемая версия, ежедневно получает новые функции и
fixes. исправления.
## 📚 Документация ## 📚 Документация
**Visit our comprehensive documentation at **Полная документация по адресу
[docs.triliumnotes.org](https://docs.triliumnotes.org/)** [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/) [docs.triliumnotes.org](https://docs.triliumnotes.org/)
- **In-App Help**: Press `F1` within Trilium to access the same documentation - **Справка в приложении**: Нажмите`F1` в Trilium для доступа к этой
directly in the application документации прямо в приложении
- **GitHub**: Navigate through the [User - **GitHub**: Navigate through the [User
Guide](./docs/User%20Guide/User%20Guide/) in this repository Guide](./docs/User%20Guide/User%20Guide/) in this repository
### Quick Links ### Важные Ссылки
- [Getting Started Guide](https://docs.triliumnotes.org/) - [Руководство по началу работы](https://docs.triliumnotes.org/)
- [Installation - [Инструкция по
Instructions](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md) установке](./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) Docker](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
- [Upgrading - [Обновление
TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.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) возможности](./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) Знаний](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/attributes)
позволяют гибко организовать структуру, используются для поиска и продвинутого позволяют гибко организовать структуру, используются для поиска и продвинутого
[скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts) [скриптинга](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) 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) * [Синхронизация](https://triliumnext.github.io/Docs/Wiki/synchronization)
заметок со своим сервером заметок со своим сервером
* there's a [3rd party service for hosting synchronisation * 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 Если вы являетесь носителем языка, помогите нам перевести Trilium, перейдя на
[Weblate page](https://hosted.weblate.org/engage/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 Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем запустите
server (available at http://localhost:8080): сервер (доступен по адресу http://localhost:8080):
```shell ```shell
git clone https://github.com/TriliumNext/Trilium.git git clone https://github.com/TriliumNext/Trilium.git
cd Trilium cd Trilium
@ -244,10 +244,10 @@ pnpm install
pnpm run server:start pnpm run server:start
``` ```
### Documentation ### Документация
Download the repository, install dependencies using `pnpm` and then run the Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем запустите
environment required to edit the documentation: окружение, необходимое для редактирование документации:
```shell ```shell
git clone https://github.com/TriliumNext/Trilium.git git clone https://github.com/TriliumNext/Trilium.git
cd Trilium cd Trilium
@ -255,9 +255,9 @@ pnpm install
pnpm edit-docs:edit-docs pnpm edit-docs:edit-docs
``` ```
### Building the Executable ### Сборка исполняемого файла
Download the repository, install dependencies using `pnpm` and then build the Скачайте репозиторий, установите зависимости с помощью `pnpm`, затем соберите
desktop app for Windows: приложение для Windows:
```shell ```shell
git clone https://github.com/TriliumNext/Trilium.git git clone https://github.com/TriliumNext/Trilium.git
cd Trilium cd Trilium
@ -265,10 +265,10 @@ pnpm install
pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 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 Please view the [documentation
guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) 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 * [zadam](https://github.com/zadam) за оригинальный концепт и реализацию
of the application. приложения.
* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the * [Sarah Hussein](https://github.com/Sarah-Hussein) за создание иконки
application icon. приложения.
* [nriver](https://github.com/nriver) for his work on internationalization. * [nriver](https://github.com/nriver) за работу по интернационализации.
* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. * [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas.
* [antoniotejada](https://github.com/nriver) for the original syntax highlight * [antoniotejada](https://github.com/nriver) за оригинальный виджет подсветки
widget. синтаксиса.
* [Dosu](https://dosu.dev/) for providing us with the automated responses to * [Dosu](https://dosu.dev/) за обеспечение автоматических ответов на вопросы и
GitHub issues and discussions. обсуждения GitHub.
* [Tabler Icons](https://tabler.io/icons) for the system tray icons. * [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 * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - визуальный редактор
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. * [CodeMirror](https://github.com/codemirror/CodeMirror) - редактор кода с
* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite поддержкой огромного количества языков.
whiteboard used in Canvas notes. * [Excalidraw](https://github.com/excalidraw/excalidraw) - бесконечная белая
* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the доска, используемая в заметках Canvas.
mind map functionality. * [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - обеспечивает
* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical функционирование ментальной карты.
maps. * [Leaflet](https://github.com/Leaflet/Leaflet) - отображение географических
* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive карт.
table used in collections. * [Tabulator](https://github.com/olifolkerd/tabulator) - интерактивные таблицы,
* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library используемые в коллекциях.
without real competition. * [FancyTree](https://github.com/mar10/fancytree) - многофункциональная
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. библиотека деревьев, не имеющая себе равных.
Used in [relation * [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека визуальных связей.
maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link Используется в [картах
maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map) связей](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 На создание и поддержку Trilium затрачены [сотни часов
work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your работы](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Ваша
support keeps it open-source, improves features, and covers costs such as поддержка помогает ему оставаться open-source, улучшает функции и покрывает
hosting. расходы, такие как хостинг.
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) - [GitHub Sponsors](https://github.com/sponsors/eliandoran)
- [PayPal](https://paypal.me/eliandoran) - [PayPal](https://paypal.me/eliandoran)

View File

@ -8838,6 +8838,13 @@
"value": "bx bx-selection", "value": "bx bx-selection",
"isInheritable": false, "isInheritable": false,
"position": 20 "position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "WWgeUaBb7UfC",
"isInheritable": false,
"position": 30
} }
], ],
"format": "markdown", "format": "markdown",
@ -8921,6 +8928,33 @@
"dataFileName": "ELK layout_ELK on.svg" "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", "value": "bx bx-extension",
"isInheritable": false, "isInheritable": false,
"position": 30 "position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "9qPsTWBorUhQ",
"isInheritable": false,
"position": 40
} }
], ],
"format": "markdown", "format": "markdown",
@ -12594,7 +12635,7 @@
{ {
"type": "label", "type": "label",
"name": "webViewSrc", "name": "webViewSrc",
"value": "/etapi/docs", "value": "/rest-api/etapi/",
"isInheritable": false, "isInheritable": false,
"position": 10 "position": 10
}, },
@ -13612,7 +13653,7 @@
{ {
"type": "label", "type": "label",
"name": "webViewSrc", "name": "webViewSrc",
"value": "/api/docs", "value": "/rest-api/internal/",
"isInheritable": false, "isInheritable": false,
"position": 10 "position": 10
}, },
@ -14968,7 +15009,7 @@
{ {
"type": "label", "type": "label",
"name": "webViewSrc", "name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html", "value": "/script-api/frontend",
"isInheritable": false, "isInheritable": false,
"position": 10 "position": 10
}, },
@ -15003,7 +15044,7 @@
{ {
"type": "label", "type": "label",
"name": "webViewSrc", "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, "isInheritable": false,
"position": 10 "position": 10
}, },
@ -15039,7 +15080,7 @@
{ {
"type": "label", "type": "label",
"name": "webViewSrc", "name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html", "value": "/script-api/backend",
"isInheritable": false, "isInheritable": false,
"position": 10 "position": 10
}, },

View File

@ -1,7 +1,8 @@
# ETAPI (REST API) # 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 ## API clients

View File

@ -1,10 +1,11 @@
# Mermaid Diagrams # 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> <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. 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 ## Layouts
Depending on the chart being edited and user preference, there are two layouts supported by the Mermaid note type: 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:generate-openapi": "tsx ./scripts/generate-openapi.ts",
"chore:update-build-info": "tsx ./scripts/update-build-info.ts", "chore:update-build-info": "tsx ./scripts/update-build-info.ts",
"chore:update-version": "tsx ./scripts/update-version.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-docs": "pnpm run --filter edit-docs edit-docs",
"edit-docs:edit-demo": "pnpm run --filter edit-docs edit-demo", "edit-docs:edit-demo": "pnpm run --filter edit-docs edit-demo",
"test:all": "pnpm test:parallel && pnpm test:sequential", "test:all": "pnpm test:parallel && pnpm test:sequential",

View File

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

View File

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

1478
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff