Merge remote-tracking branch 'origin/develop' into port/client_ts
10
.github/actions/build-electron/action.yml
vendored
@ -6,7 +6,7 @@ inputs:
|
|||||||
description: "The architecture to build for: x64, arm64"
|
description: "The architecture to build for: x64, arm64"
|
||||||
required: true
|
required: true
|
||||||
extension:
|
extension:
|
||||||
description: "Platform specific extensions to copy in the output: dmg, deb, rpm, exe"
|
description: "Platform specific extensions to copy in the output: dmg, deb, rpm, exe, zip"
|
||||||
required: true
|
required: true
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
@ -27,16 +27,12 @@ runs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Temporary Flatpak arm64 workaround till https://github.com/electron/forge/pull/3839 is merged
|
|
||||||
if: ${{ inputs.os == 'linux' && inputs.arch == 'arm64' }}
|
|
||||||
shell: bash
|
|
||||||
run: sed -e "s/case 'armv7l'/case 'arm64'/g" -e "s/return 'arm'/return 'aarch64'/g" -i node_modules/@electron-forge/maker-flatpak/dist/MakerFlatpak.js
|
|
||||||
- name: Update build info
|
- name: Update build info
|
||||||
shell: bash
|
shell: bash
|
||||||
run: npm run update-build-info
|
run: npm run chore:update-build-info
|
||||||
- name: Run electron-forge
|
- name: Run electron-forge
|
||||||
shell: bash
|
shell: bash
|
||||||
run: npm run make-electron -- --arch=${{ inputs.arch }}
|
run: npm run electron-forge:make -- --arch=${{ inputs.arch }}
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
5
.github/actions/build-server/action.yml
vendored
@ -1,4 +1,7 @@
|
|||||||
inputs:
|
inputs:
|
||||||
|
os:
|
||||||
|
description: "One of the supported platforms: windows"
|
||||||
|
required: true
|
||||||
arch:
|
arch:
|
||||||
description: "The architecture to build for: x64, arm64"
|
description: "The architecture to build for: x64, arm64"
|
||||||
required: true
|
required: true
|
||||||
@ -18,7 +21,7 @@ runs:
|
|||||||
MATRIX_ARCH: ${{ inputs.arch }}
|
MATRIX_ARCH: ${{ inputs.arch }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
npm run update-build-info
|
npm run chore:update-build-info
|
||||||
./bin/build-server.sh
|
./bin/build-server.sh
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
shell: bash
|
shell: bash
|
||||||
|
25
.github/workflows/main-docker.yml
vendored
@ -100,7 +100,20 @@ jobs:
|
|||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build Docker images
|
name: Build Docker images
|
||||||
runs-on: ubuntu-latest
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- dockerfile: Dockerfile.alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
image: ubuntu-latest
|
||||||
|
- dockerfile: Dockerfile
|
||||||
|
platform: linux/arm64
|
||||||
|
image: ubuntu-24.04-arm
|
||||||
|
- dockerfile: Dockerfile
|
||||||
|
platform: linux/arm/v7
|
||||||
|
image: ubuntu-24.04-arm
|
||||||
|
runs-on: ${{ matrix.image }}
|
||||||
needs:
|
needs:
|
||||||
- test_docker
|
- test_docker
|
||||||
permissions:
|
permissions:
|
||||||
@ -108,16 +121,6 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
attestations: write
|
attestations: write
|
||||||
id-token: write
|
id-token: write
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- dockerfile: Dockerfile.alpine
|
|
||||||
platform: linux/amd64
|
|
||||||
- dockerfile: Dockerfile
|
|
||||||
platform: linux/arm64
|
|
||||||
- dockerfile: Dockerfile
|
|
||||||
platform: linux/arm/v7
|
|
||||||
steps:
|
steps:
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
2
.github/workflows/main.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
extension: [deb, rpm, zip, flatpak]
|
extension: [deb, rpm, zip, flatpak]
|
||||||
- name: windows
|
- name: windows
|
||||||
image: windows-latest
|
image: windows-latest
|
||||||
extension: exe
|
extension: [exe, zip]
|
||||||
runs-on: ${{ matrix.os.image }}
|
runs-on: ${{ matrix.os.image }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
5
.github/workflows/nightly.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
extension: [deb, rpm, zip, flatpak]
|
extension: [deb, rpm, zip, flatpak]
|
||||||
- name: windows
|
- name: windows
|
||||||
image: windows-latest
|
image: windows-latest
|
||||||
extension: exe
|
extension: [exe, zip]
|
||||||
runs-on: ${{ matrix.os.image }}
|
runs-on: ${{ matrix.os.image }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Update nightly version
|
- name: Update nightly version
|
||||||
run: npm run ci-update-nightly-version
|
run: npm run chore:ci-update-nightly-version
|
||||||
- name: Run the build
|
- name: Run the build
|
||||||
uses: ./.github/actions/build-electron
|
uses: ./.github/actions/build-electron
|
||||||
with:
|
with:
|
||||||
@ -75,6 +75,7 @@ jobs:
|
|||||||
- name: Run the build
|
- name: Run the build
|
||||||
uses: ./.github/actions/build-server
|
uses: ./.github/actions/build-server
|
||||||
with:
|
with:
|
||||||
|
os: linux
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Publish release
|
- name: Publish release
|
||||||
|
3
.github/workflows/release.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
extension: [deb, rpm, zip, flatpak]
|
extension: [deb, rpm, zip, flatpak]
|
||||||
- name: windows
|
- name: windows
|
||||||
image: windows-latest
|
image: windows-latest
|
||||||
extension: exe
|
extension: [exe, zip]
|
||||||
runs-on: ${{ matrix.os.image }}
|
runs-on: ${{ matrix.os.image }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -65,6 +65,7 @@ jobs:
|
|||||||
- name: Run the build
|
- name: Run the build
|
||||||
uses: ./.github/actions/build-server
|
uses: ./.github/actions/build-server
|
||||||
with:
|
with:
|
||||||
|
os: linux
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Publish release
|
- name: Publish release
|
||||||
|
@ -4,7 +4,7 @@ image:
|
|||||||
tasks:
|
tasks:
|
||||||
- before: nvm install 20.15.1 && nvm use 20.15.1
|
- before: nvm install 20.15.1 && nvm use 20.15.1
|
||||||
init: npm install
|
init: npm install
|
||||||
command: npm run start-server
|
command: npm run server:start
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- port: 8080
|
- port: 8080
|
||||||
|
4
.vscode/launch.json
vendored
@ -5,8 +5,8 @@
|
|||||||
{
|
{
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"internalConsoleOptions": "neverOpen",
|
"internalConsoleOptions": "neverOpen",
|
||||||
"name": "nodemon start-server",
|
"name": "nodemon server:start",
|
||||||
"program": "${workspaceFolder}/src/www",
|
"program": "${workspaceFolder}/src/main",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"restart": true,
|
"restart": true,
|
||||||
"runtimeExecutable": "nodemon",
|
"runtimeExecutable": "nodemon",
|
||||||
|
3
.vscode/settings.json
vendored
@ -18,5 +18,6 @@
|
|||||||
"github-actions.workflows.pinned.workflows": [".github/workflows/nightly.yml"],
|
"github-actions.workflows.pinned.workflows": [".github/workflows/nightly.yml"],
|
||||||
"[css]": {
|
"[css]": {
|
||||||
"editor.defaultFormatter": "vscode.css-language-features"
|
"editor.defaultFormatter": "vscode.css-language-features"
|
||||||
}
|
},
|
||||||
|
"npm.exclude": ["**/build", "**/dist", "**/out/**"]
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Build stage
|
# Build stage
|
||||||
FROM node:22.13.1-bullseye-slim AS builder
|
FROM node:22.14.0-bullseye-slim AS builder
|
||||||
|
|
||||||
# Configure build dependencies in a single layer
|
# Configure build dependencies in a single layer
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
@ -25,7 +25,7 @@ RUN cp -R build/src/* src/. && \
|
|||||||
cp build/docker_healthcheck.js . && \
|
cp build/docker_healthcheck.js . && \
|
||||||
rm docker_healthcheck.ts && \
|
rm docker_healthcheck.ts && \
|
||||||
npm install && \
|
npm install && \
|
||||||
npm run webpack && \
|
npm run build:webpack && \
|
||||||
npm prune --omit=dev && \
|
npm prune --omit=dev && \
|
||||||
npm cache clean --force && \
|
npm cache clean --force && \
|
||||||
cp -r src/public/app/doc_notes src/public/app-dist/. && \
|
cp -r src/public/app/doc_notes src/public/app-dist/. && \
|
||||||
@ -36,7 +36,7 @@ RUN cp -R build/src/* src/. && \
|
|||||||
rm -r build
|
rm -r build
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM node:22.13.1-bullseye-slim
|
FROM node:22.14.0-bullseye-slim
|
||||||
|
|
||||||
# Install only runtime dependencies
|
# Install only runtime dependencies
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Build stage
|
# Build stage
|
||||||
FROM node:22.13.1-alpine AS builder
|
FROM node:22.14.0-alpine AS builder
|
||||||
|
|
||||||
# Configure build dependencies
|
# Configure build dependencies
|
||||||
RUN apk add --no-cache --virtual .build-dependencies \
|
RUN apk add --no-cache --virtual .build-dependencies \
|
||||||
@ -24,7 +24,7 @@ RUN cp -R build/src/* src/. && \
|
|||||||
cp build/docker_healthcheck.js . && \
|
cp build/docker_healthcheck.js . && \
|
||||||
rm docker_healthcheck.ts && \
|
rm docker_healthcheck.ts && \
|
||||||
npm install && \
|
npm install && \
|
||||||
npm run webpack && \
|
npm run build:webpack && \
|
||||||
npm prune --omit=dev && \
|
npm prune --omit=dev && \
|
||||||
npm cache clean --force && \
|
npm cache clean --force && \
|
||||||
cp -r src/public/app/doc_notes src/public/app-dist/. && \
|
cp -r src/public/app/doc_notes src/public/app-dist/. && \
|
||||||
@ -35,7 +35,7 @@ RUN cp -R build/src/* src/. && \
|
|||||||
rm -r build
|
rm -r build
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM node:22.13.1-alpine
|
FROM node:22.14.0-alpine
|
||||||
|
|
||||||
# Install runtime dependencies
|
# Install runtime dependencies
|
||||||
RUN apk add --no-cache su-exec shadow
|
RUN apk add --no-cache su-exec shadow
|
||||||
|
@ -78,7 +78,7 @@ Trilium 也提供 Flatpak:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 致谢
|
## 👏 致谢
|
||||||
|
@ -86,7 +86,7 @@ Clone localmente y ejecute
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Reconocimientos
|
## 👏 Reconocimientos
|
||||||
|
@ -73,7 +73,7 @@ Clona localmente ed esegui
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Riconoscimenti
|
## 👏 Riconoscimenti
|
||||||
|
@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📢 シャウトアウト
|
## 📢 シャウトアウト
|
||||||
|
@ -102,7 +102,7 @@ You can also read [Patterns of personal knowledge base](https://triliumnext.gith
|
|||||||
git clone https://github.com/TriliumNext/Notes.git
|
git clone https://github.com/TriliumNext/Notes.git
|
||||||
cd Notes
|
cd Notes
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Благодарности
|
## 👏 Благодарности
|
||||||
|
@ -7,9 +7,9 @@ const DEST_DIR_NODE_MODULES = path.join(DEST_DIR, "node_modules");
|
|||||||
|
|
||||||
const VERBOSE = process.env.VERBOSE;
|
const VERBOSE = process.env.VERBOSE;
|
||||||
|
|
||||||
function log(...args) {
|
function log(...args: any[]) {
|
||||||
if (VERBOSE) {
|
if (VERBOSE) {
|
||||||
console.log(args);
|
console.log(...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,12 @@ const copy = async () => {
|
|||||||
fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
|
fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesToCopy = ["config-sample.ini", "tsconfig.webpack.json"];
|
const filesToCopy = [
|
||||||
|
"config-sample.ini",
|
||||||
|
"tsconfig.webpack.json",
|
||||||
|
"./src/etapi/etapi.openapi.yaml",
|
||||||
|
"./src/routes/api/openapi.json"
|
||||||
|
];
|
||||||
for (const file of filesToCopy) {
|
for (const file of filesToCopy) {
|
||||||
log(`Copying ${file}`);
|
log(`Copying ${file}`);
|
||||||
await fs.copy(file, path.join(DEST_DIR, file));
|
await fs.copy(file, path.join(DEST_DIR, file));
|
||||||
@ -90,7 +95,6 @@ const copy = async () => {
|
|||||||
"node_modules/mark.js/dist/",
|
"node_modules/mark.js/dist/",
|
||||||
"node_modules/normalize.css/",
|
"node_modules/normalize.css/",
|
||||||
"node_modules/jquery.fancytree/dist/",
|
"node_modules/jquery.fancytree/dist/",
|
||||||
"node_modules/bootstrap/dist/",
|
|
||||||
"node_modules/autocomplete.js/dist/",
|
"node_modules/autocomplete.js/dist/",
|
||||||
"node_modules/codemirror/lib/",
|
"node_modules/codemirror/lib/",
|
||||||
"node_modules/codemirror/addon/",
|
"node_modules/codemirror/addon/",
|
||||||
|
@ -23,7 +23,7 @@ rm -rf "$DIR"
|
|||||||
mkdir -pv "$DIR"
|
mkdir -pv "$DIR"
|
||||||
|
|
||||||
echo Webpack start
|
echo Webpack start
|
||||||
npm run webpack
|
npm run build:webpack
|
||||||
echo Webpack finish
|
echo Webpack finish
|
||||||
|
|
||||||
echo "Copying Trilium to build directory $DIR"
|
echo "Copying Trilium to build directory $DIR"
|
||||||
|
189
bin/generate-openapi.ts
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import { dirname, join } from "path";
|
||||||
|
import swaggerJsdoc from 'swagger-jsdoc';
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage: npm run generate-openapi | tail -n1 > x.json
|
||||||
|
*
|
||||||
|
* Inspect generated file by opening it in https://editor-next.swagger.io/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
definition: {
|
||||||
|
openapi: '3.1.1',
|
||||||
|
info: {
|
||||||
|
title: 'Trilium Notes - Sync server API',
|
||||||
|
version: '0.96.6',
|
||||||
|
description: "This is the internal sync server API used by Trilium Notes / TriliumNext Notes.\n\n_If you're looking for the officially supported External Trilium API, see [here](https://triliumnext.github.io/Docs/Wiki/etapi.html)._\n\nThis page does not yet list all routes. For a full list, see the [route controller](https://github.com/TriliumNext/Notes/blob/v0.91.6/src/routes/routes.ts).",
|
||||||
|
contact: {
|
||||||
|
name: "TriliumNext issue tracker",
|
||||||
|
url: "https://github.com/TriliumNext/Notes/issues",
|
||||||
|
},
|
||||||
|
license: {
|
||||||
|
name: "GNU Free Documentation License 1.3 (or later)",
|
||||||
|
url: "https://www.gnu.org/licenses/fdl-1.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apis: [
|
||||||
|
// Put individual files here to have them ordered first.
|
||||||
|
'./src/routes/api/setup.ts',
|
||||||
|
// all other files
|
||||||
|
'./src/routes/api/*.ts', './bin/generate-openapi.js'
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const openapiSpecification = swaggerJsdoc(options);
|
||||||
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const outputPath = join(scriptDir, "..", "src", "routes", "api", "openapi.json");
|
||||||
|
fs.writeFileSync(outputPath, JSON.stringify(openapiSpecification));
|
||||||
|
console.log("Saved to ", outputPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* tags:
|
||||||
|
* - name: auth
|
||||||
|
* description: Authentication
|
||||||
|
* - name: sync
|
||||||
|
* description: Synchronization
|
||||||
|
* - name: data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* components:
|
||||||
|
* schemas:
|
||||||
|
* Attribute:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* attributeId:
|
||||||
|
* type: string
|
||||||
|
* example: "4G1DPrI58PAb"
|
||||||
|
* noteId:
|
||||||
|
* $ref: "#/components/schemas/NoteId"
|
||||||
|
* type:
|
||||||
|
* type: string
|
||||||
|
* enum: ["attribute", "relation"]
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* example: "internalLink"
|
||||||
|
* value:
|
||||||
|
* type: string
|
||||||
|
* example: "hA8aHSpTRdZ6"
|
||||||
|
* description: "If type = \"relation\", a note ID. Otherwise, the attribute content."
|
||||||
|
* position:
|
||||||
|
* type: integer
|
||||||
|
* example: 20
|
||||||
|
* isInheritable:
|
||||||
|
* type: boolean
|
||||||
|
* Blob:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* blobId:
|
||||||
|
* type: string
|
||||||
|
* example: "8iqMIB8eiY1tPYmElfjm"
|
||||||
|
* content:
|
||||||
|
* type:
|
||||||
|
* - string
|
||||||
|
* - 'null'
|
||||||
|
* description: "`null` if not text."
|
||||||
|
* contentLength:
|
||||||
|
* type: integer
|
||||||
|
* dateModified:
|
||||||
|
* $ref: "#/components/schemas/DateTime"
|
||||||
|
* utcDateModified:
|
||||||
|
* $ref: "#/components/schemas/UtcDateTime"
|
||||||
|
* Branch:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* branchId:
|
||||||
|
* $ref: "#/components/schemas/BranchId"
|
||||||
|
* noteId:
|
||||||
|
* $ref: "#/components/schemas/NoteId"
|
||||||
|
* parentNoteId:
|
||||||
|
* $ref: "#/components/schemas/NoteId"
|
||||||
|
* notePosition:
|
||||||
|
* type: integer
|
||||||
|
* example: 20
|
||||||
|
* prefix:
|
||||||
|
* type:
|
||||||
|
* - string
|
||||||
|
* - 'null'
|
||||||
|
* isExpanded:
|
||||||
|
* type: boolean
|
||||||
|
* BranchId:
|
||||||
|
* type: string
|
||||||
|
* example: "WUjhaGp4EKah_ur11rSfHkzeV"
|
||||||
|
* description: Equal to `{parentNoteId}_{noteId}`
|
||||||
|
* DateTime:
|
||||||
|
* type: string
|
||||||
|
* example: "2025-02-14 08:19:59.203+0100"
|
||||||
|
* EntityChange:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* entityChange:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* entityName:
|
||||||
|
* type: string
|
||||||
|
* example: "notes"
|
||||||
|
* description: Database table for this entity.
|
||||||
|
* changeId:
|
||||||
|
* type: string
|
||||||
|
* example: "changeId9630"
|
||||||
|
* description: ID, referenced in `entity_changes` table.
|
||||||
|
* entity:
|
||||||
|
* type: object
|
||||||
|
* description: Encoded entity data. Object has one property for each database column.
|
||||||
|
* Note:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* noteId:
|
||||||
|
* $ref: "#/components/schemas/NoteId"
|
||||||
|
* title:
|
||||||
|
* type: string
|
||||||
|
* isProtected:
|
||||||
|
* type: boolean
|
||||||
|
* type:
|
||||||
|
* type: string
|
||||||
|
* example: "text"
|
||||||
|
* enum: ["text", "code", "render", "file", "image", "search", "relationMap", "book", "noteMap", "mermaid", "canvas", "webView", "launcher", "doc", "contentWidget", "mindMap", "geoMap"]
|
||||||
|
* description: "[Reference list](https://github.com/TriliumNext/Notes/blob/v0.91.6/src/services/note_types.ts)"
|
||||||
|
* mime:
|
||||||
|
* type: string
|
||||||
|
* example: "text/html"
|
||||||
|
* blobId:
|
||||||
|
* type: string
|
||||||
|
* example: "z4PhNX7vuL3xVChQ1m2A"
|
||||||
|
* NoteId:
|
||||||
|
* type: string
|
||||||
|
* example: "ur11rSfHkzeV"
|
||||||
|
* description: "12-character note ID. Special values: \"none\"`, `\"root\"."
|
||||||
|
* Timestamps:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* dateCreated:
|
||||||
|
* $ref: "#/components/schemas/DateTime"
|
||||||
|
* dateModified:
|
||||||
|
* $ref: "#/components/schemas/DateTime"
|
||||||
|
* utcDateCreated:
|
||||||
|
* $ref: "#/components/schemas/UtcDateTime"
|
||||||
|
* utcDateModified:
|
||||||
|
* $ref: "#/components/schemas/UtcDateTime"
|
||||||
|
* UtcDateTime:
|
||||||
|
* type: string
|
||||||
|
* example: "2025-02-13T07:42:47.698Z"
|
||||||
|
* description: "Result of `new Date().toISOString().replace('T', ' ')`"
|
||||||
|
* securitySchemes:
|
||||||
|
* user-password:
|
||||||
|
* type: apiKey
|
||||||
|
* name: trilium-cred
|
||||||
|
* in: header
|
||||||
|
* description: "Username and password, formatted as `user:password`"
|
||||||
|
* session:
|
||||||
|
* type: apiKey
|
||||||
|
* in: cookie
|
||||||
|
* name: trilium.sid
|
||||||
|
*/
|
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
export GITHUB_REPO=trilium
|
|
||||||
|
|
||||||
if [[ $# -eq 0 ]] ; then
|
if [[ $# -eq 0 ]] ; then
|
||||||
echo "Missing argument of new version"
|
echo "Missing argument of new version"
|
||||||
exit 1
|
exit 1
|
||||||
@ -32,7 +30,7 @@ mv package.json.tmp package.json
|
|||||||
|
|
||||||
git add package.json
|
git add package.json
|
||||||
|
|
||||||
npm run update-build-info
|
npm run chore:update-build-info
|
||||||
|
|
||||||
git add src/services/build.ts
|
git add src/services/build.ts
|
||||||
|
|
||||||
@ -40,10 +38,18 @@ TAG=v$VERSION
|
|||||||
|
|
||||||
echo "Committing package.json version change"
|
echo "Committing package.json version change"
|
||||||
|
|
||||||
git commit -m "release $VERSION"
|
git commit -m "chore(release): $VERSION"
|
||||||
git push
|
git push
|
||||||
|
|
||||||
echo "Tagging commit with $TAG"
|
echo "Tagging commit with $TAG"
|
||||||
|
|
||||||
git tag $TAG
|
git tag $TAG
|
||||||
git push origin $TAG
|
git push origin $TAG
|
||||||
|
|
||||||
|
echo "Updating master"
|
||||||
|
|
||||||
|
git fetch
|
||||||
|
git checkout master
|
||||||
|
git reset --hard origin/master
|
||||||
|
git merge origin/develop
|
||||||
|
git push
|
@ -30,13 +30,19 @@ trustedReverseProxy=false
|
|||||||
|
|
||||||
|
|
||||||
[Session]
|
[Session]
|
||||||
# Use this setting to constrain the current instance's "Path" value for the set cookies
|
# Use this setting to set a custom value for the "Path" Attribute value of the session cookie.
|
||||||
# This can be useful, when you have several instances running on the same domain, under different paths (e.g. by using a reverse proxy).
|
# This can be useful, when you have several instances running on the same domain, under different paths (e.g. by using a reverse proxy).
|
||||||
# It prevents your instances from overwriting each others' cookies.
|
# It prevents your instances from overwriting each others' cookies, allowing you to stay logged in multiple instances simultanteously.
|
||||||
# e.g. if you have https://your-domain.com/triliumNext/instanceA and https://your-domain.com/triliumNext/instanceB
|
# E.g. if you have instances running under https://your-domain.com/triliumNext/instanceA and https://your-domain.com/triliumNext/instanceB
|
||||||
# you would want to set the cookiePath value to "/triliumNext/instanceA" for your first and "/triliumNext/instanceB" for your second instance
|
# you would want to set the cookiePath value to "/triliumNext/instanceA" for your first and "/triliumNext/instanceB" for your second instance
|
||||||
cookiePath=/
|
cookiePath=/
|
||||||
|
|
||||||
|
# Use this setting to set a custom value for the "Max-Age" Attribute of the session cookie.
|
||||||
|
# This controls how long your session will be valid, before it expires and you need to log in again, when you use the "Remember Me" option.
|
||||||
|
# Value needs to be entered in Seconds.
|
||||||
|
# Default value is 1814400 Seconds, which is 21 Days.
|
||||||
|
cookieMaxAge=1814400
|
||||||
|
|
||||||
[Sync]
|
[Sync]
|
||||||
#syncServerHost=
|
#syncServerHost=
|
||||||
#syncServerTimeout=
|
#syncServerTimeout=
|
||||||
|
10
db/migrations/0229__tasks.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "tasks"
|
||||||
|
(
|
||||||
|
"taskId" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"parentNoteId" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL DEFAULT "",
|
||||||
|
"dueDate" INTEGER,
|
||||||
|
"isDone" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"isDeleted" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"utcDateModified" TEXT NOT NULL
|
||||||
|
);
|
@ -132,3 +132,14 @@ CREATE INDEX IDX_attachments_ownerId_role
|
|||||||
CREATE INDEX IDX_notes_blobId on notes (blobId);
|
CREATE INDEX IDX_notes_blobId on notes (blobId);
|
||||||
CREATE INDEX IDX_revisions_blobId on revisions (blobId);
|
CREATE INDEX IDX_revisions_blobId on revisions (blobId);
|
||||||
CREATE INDEX IDX_attachments_blobId on attachments (blobId);
|
CREATE INDEX IDX_attachments_blobId on attachments (blobId);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "tasks"
|
||||||
|
(
|
||||||
|
"taskId" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"parentNoteId" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL DEFAULT "",
|
||||||
|
"dueDate" INTEGER,
|
||||||
|
"isDone" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"isDeleted" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"utcDateModified" TEXT NOT NULL
|
||||||
|
);
|
@ -38,12 +38,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<div id="content" class="type-text ck-content">
|
<div id="content" class="type-text ck-content">
|
||||||
<h3>The native node bindings</h3><p><code>better-sqlite3</code> has native Node bindings. With updates of <code>better-sqlite3</code>, but also of Electron and Node.js versions, these bindings need to be updated.</p><p>Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.</p><p>During development, <code>npm install</code> tries to build or reuse prebuilt natives for the current Node.js version. This makes <code>npm run start-server</code> work out of the box. Trying to run <code>npm run start-electron</code> with these versions generally causes an error such as this:</p><pre><code class="language-text-plain">Uncaught Exception:
|
<h3>The native node bindings</h3><p><code>better-sqlite3</code> has native Node bindings. With updates of <code>better-sqlite3</code>, but also of Electron and Node.js versions, these bindings need to be updated.</p><p>Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js.</p><p>During development, <code>npm install</code> tries to build or reuse prebuilt natives for the current Node.js version. This makes <code>npm run server:start</code> work out of the box. Trying to run <code>npm run electron:start</code> with these versions generally causes an error such as this:</p><pre><code class="language-text-plain">Uncaught Exception:
|
||||||
Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
|
Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
|
||||||
was compiled against a different Node.js version using
|
was compiled against a different Node.js version using
|
||||||
NODE_MODULE_VERSION 108. This version of Node.js requires
|
NODE_MODULE_VERSION 108. This version of Node.js requires
|
||||||
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
|
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
|
||||||
the module (for instance, using `npm rebuild` or `npm install`).</code></pre><h3>How the natives are handled</h3><p>Locally, this can be fixed by rebuilding the binaries, which is what <code>npm run switch-electron</code> does, which uses <code>electron-rebuild</code> under the hood.</p><p>When the deliveries are built (see <a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a>), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, <code>better-sqlite3</code> provides these prebuilt binaries from us, available as artifacts on <a href="https://github.com/WiseLibs/better-sqlite3/releases/">their GitHub releases page</a>. </p><p>The build script manages the natives for <code>better-sqlite3</code> by keeping a copy of the <code>.node</code> file for every platform in <code>bin/better-sqlite3</code>.</p><p>Whenever the version of <code>better-sqlite3</code> changes, the <code>.node</code> files must also be renewed based on their releases page. To simplify this process, a script was created in <code>bin/better-sqlite3/update.sh</code>.</p><h2>How to update the natives</h2><p>The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.</p><p>If you get errors during download, check on the <a href="https://github.com/WiseLibs/better-sqlite3/releases/">releases page</a> to ensure that this particular combination of Electron/Node actually exists for the given release.</p><p>To determine the <code>NODE_MODULE_VERSION</code> that is required, look for <code>This version of Node.js requires</code><br><code>NODE_MODULE_VERSION</code> in the error when starting Trilium via:</p><ul><li><code>npm run start-electron</code> (or run any Electron <a href="UTB518X6X9Uh.html" class="type-text">delivery</a>), case in which the <span style="color:#c0bfbc;"><code>ELECTRON_VERSION</code> variable needs to be changed.</span></li><li><span style="color:#c0bfbc;"><code>npm run start-server</code></span> (or run the Linux server delivery), case in which the <code>NODE_VERSION</code> variable needs to be changed.</li></ul><p>Check which files got changed after running the update script and for each platform that got changed, test it locally via <a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a> or via the CI.</p>
|
the module (for instance, using `npm rebuild` or `npm install`).</code></pre><h3>How the natives are handled</h3><p>Locally, this can be fixed by rebuilding the binaries, which is what <code>npm run electron:switch</code> does, which uses <code>electron-rebuild</code> under the hood.</p><p>When the deliveries are built (see <a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a>), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, <code>better-sqlite3</code> provides these prebuilt binaries from us, available as artifacts on <a href="https://github.com/WiseLibs/better-sqlite3/releases/">their GitHub releases page</a>. </p><p>The build script manages the natives for <code>better-sqlite3</code> by keeping a copy of the <code>.node</code> file for every platform in <code>bin/better-sqlite3</code>.</p><p>Whenever the version of <code>better-sqlite3</code> changes, the <code>.node</code> files must also be renewed based on their releases page. To simplify this process, a script was created in <code>bin/better-sqlite3/update.sh</code>.</p><h2>How to update the natives</h2><p>The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries.</p><p>If you get errors during download, check on the <a href="https://github.com/WiseLibs/better-sqlite3/releases/">releases page</a> to ensure that this particular combination of Electron/Node actually exists for the given release.</p><p>To determine the <code>NODE_MODULE_VERSION</code> that is required, look for <code>This version of Node.js requires</code><br><code>NODE_MODULE_VERSION</code> in the error when starting Trilium via:</p><ul><li><code>npm run electron:start</code> (or run any Electron <a href="UTB518X6X9Uh.html" class="type-text">delivery</a>), case in which the <span style="color:#c0bfbc;"><code>ELECTRON_VERSION</code> variable needs to be changed.</span></li><li><span style="color:#c0bfbc;"><code>npm run server:start</code></span> (or run the Linux server delivery), case in which the <code>NODE_VERSION</code> variable needs to be changed.</li></ul><p>Check which files got changed after running the update script and for each platform that got changed, test it locally via <a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a> or via the CI.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div id="content" class="type-text ck-content">
|
<div id="content" class="type-text ck-content">
|
||||||
<h2>Server live reload</h2><p>If running the server using <code>npm run start-server</code>, the server will watch for changes in <code>src/public</code> and trigger a frontend reload if that occurs.</p><h2>Electron live reload</h2><p>Similarly, <code>npm run start-electron</code> supports live refresh as well.</p><p>However, a core difference is that Electron watches <code>dist/src/public</code> instead of <code>src/public</code> since Electron runs on its own copy of the files.</p><p>To ameliorate that, a separate watch script has been implemented which automatically copies files from <code>src/public</code> to <code>dist/src/public</code> whenever a change is detected. To run it:</p><pre><code class="language-text-plain">npm run </code></pre><h2>Technical details</h2><ul><li>This mechanism is managed at server level by watching for changes in<code>services/ws.ts</code>.</li></ul>
|
<h2>Server live reload</h2><p>If running the server using <code>npm run server:start</code>, the server will watch for changes in <code>src/public</code> and trigger a frontend reload if that occurs.</p><h2>Electron live reload</h2><p>Similarly, <code>npm run electron:start</code> supports live refresh as well.</p><p>However, a core difference is that Electron watches <code>dist/src/public</code> instead of <code>src/public</code> since Electron runs on its own copy of the files.</p><p>To ameliorate that, a separate watch script has been implemented which automatically copies files from <code>src/public</code> to <code>dist/src/public</code> whenever a change is detected. To run it:</p><pre><code class="language-text-plain">npm run </code></pre><h2>Technical details</h2><ul><li>This mechanism is managed at server level by watching for changes in<code>services/ws.ts</code>.</li></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
<a id="server" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Server<a href="#server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To install TriliumNext on your own server (including via Docker from <a href="https://hub.docker.com/r/triliumnext/notes" target="_blank" class="external">Dockerhub</a>) follow <a href="https://triliumnext.github.io/Docs/Wiki/server-installation" target="_blank" class="external">the server installation docs</a>.</p>
|
<a id="server" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Server<a href="#server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To install TriliumNext on your own server (including via Docker from <a href="https://hub.docker.com/r/triliumnext/notes" target="_blank" class="external">Dockerhub</a>) follow <a href="https://triliumnext.github.io/Docs/Wiki/server-installation" target="_blank" class="external">the server installation docs</a>.</p>
|
||||||
<a id="📝-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📝 Documentation<a href="#📝-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://triliumnext.github.io/Docs" target="_blank" class="external">See wiki for complete list of documentation pages.</a></p>
|
<a id="📝-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📝 Documentation<a href="#📝-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://triliumnext.github.io/Docs" target="_blank" class="external">See wiki for complete list of documentation pages.</a></p>
|
||||||
<p>You can also read <a href="https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge" target="_blank" class="external">Patterns of personal knowledge base</a> to get some inspiration on how you might use TriliumNext.</p>
|
<p>You can also read <a href="https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge" target="_blank" class="external">Patterns of personal knowledge base</a> to get some inspiration on how you might use TriliumNext.</p>
|
||||||
<a id="💻-contribute" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💻 Contribute<a href="#💻-contribute" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="code" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Code<a href="#code" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="shell"><span class="hl-0">git</span><span class="hl-1"> </span><span class="hl-3">clone</span><span class="hl-1"> </span><span class="hl-3">https://github.com/TriliumNext/Notes.git</span><br/><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-3">Notes</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">start-server</span>
|
<a id="💻-contribute" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💻 Contribute<a href="#💻-contribute" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="code" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Code<a href="#code" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="shell"><span class="hl-0">git</span><span class="hl-1"> </span><span class="hl-3">clone</span><span class="hl-1"> </span><span class="hl-3">https://github.com/TriliumNext/Notes.git</span><br/><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-3">Notes</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">server:start</span>
|
||||||
</code><button type="button">Copy</button></pre>
|
</code><button type="button">Copy</button></pre>
|
||||||
|
|
||||||
<a id="documentation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Head on over to our <a href="https://github.com/TriliumNext/Docs" target="_blank" class="external">Docs repo</a></p>
|
<a id="documentation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Head on over to our <a href="https://github.com/TriliumNext/Docs" target="_blank" class="external">Docs repo</a></p>
|
||||||
|
@ -78,7 +78,7 @@ Trilium 也提供 Flatpak:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 致谢
|
## 👏 致谢
|
||||||
|
@ -86,7 +86,7 @@ Clone localmente y ejecute
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Reconocimientos
|
## 👏 Reconocimientos
|
||||||
|
@ -73,7 +73,7 @@ Clona localmente ed esegui
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Riconoscimenti
|
## 👏 Riconoscimenti
|
||||||
|
@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📢 シャウトアウト
|
## 📢 シャウトアウト
|
||||||
|
@ -102,7 +102,7 @@ You can also read [Patterns of personal knowledge base](https://triliumnext.gith
|
|||||||
git clone https://github.com/TriliumNext/Notes.git
|
git clone https://github.com/TriliumNext/Notes.git
|
||||||
cd Notes
|
cd Notes
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
npm install
|
npm install
|
||||||
npm run start-server
|
npm run server:start
|
||||||
```
|
```
|
||||||
|
|
||||||
## 👏 Благодарности
|
## 👏 Благодарности
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div id="content" class="type-text ck-content">
|
<div id="content" class="type-text ck-content">
|
||||||
<h3>Run server</h3><p>Run with default settings:</p><pre><code class="language-text-plain">npm run start-server</code></pre><p>Run with custom port:</p><pre><code class="language-text-plain">TRILIUM_PORT=8082 npm run start-server</code></pre><h3>Run Electron</h3><p>Rebuild <code>better-sqlite3</code> dependency:</p><pre><code class="language-text-plain">npm run switch-electron</code></pre><p>Then run Electron:</p><pre><code class="language-text-plain">npm run start-electron</code></pre><p>To run Electron using the same data directory as the production version:</p><pre><code class="language-text-plain">npm run start-electron-no-dir</code></pre><p>When done, switch back the <code>better-sqlite3</code> dependency:</p><pre><code class="language-text-plain">npm run switch-server</code></pre>
|
<h3>Run server</h3><p>Run with default settings:</p><pre><code class="language-text-plain">npm run server:start</code></pre><p>Run with custom port:</p><pre><code class="language-text-plain">TRILIUM_PORT=8082 npm run server:start</code></pre><h3>Run Electron</h3><p>Rebuild <code>better-sqlite3</code> dependency:</p><pre><code class="language-text-plain">npm run electron:switch</code></pre><p>Then run Electron:</p><pre><code class="language-text-plain">npm run electron:start</code></pre><p>To run Electron using the same data directory as the production version:</p><pre><code class="language-text-plain">npm run electron:start-no-dir</code></pre><p>When done, switch back the <code>better-sqlite3</code> dependency:</p><pre><code class="language-text-plain">npm run server:switch</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div id="content" class="type-text ck-content">
|
<div id="content" class="type-text ck-content">
|
||||||
<ul><li>Provides context about when the build was made and the corresponding Git revision.</li><li>The information is displayed to the client when going in the about dialog.</li><li>The build information is hard-coded in <code>src/services/build.ts</code>. This file is generated automatically via <code>npm run update-build-info</code> which itself is run automatically whenever making a build in the CI, or a <a href="UTB518X6X9Uh.html" class="type-text">local delivery</a>.</li></ul>
|
<ul><li>Provides context about when the build was made and the corresponding Git revision.</li><li>The information is displayed to the client when going in the about dialog.</li><li>The build information is hard-coded in <code>src/services/build.ts</code>. This file is generated automatically via <code>npm run chore:update-build-info</code> which itself is run automatically whenever making a build in the CI, or a <a href="UTB518X6X9Uh.html" class="type-text">local delivery</a>.</li></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
2
libraries/ckeditor/ckeditor.js
vendored
2
libraries/ckeditor/ckeditor.js.map
vendored
1
libraries/codemirror/hcl.js
vendored
@ -198,6 +198,7 @@
|
|||||||
ext: [ "hcl " ],
|
ext: [ "hcl " ],
|
||||||
mime: "text/x-hcl",
|
mime: "text/x-hcl",
|
||||||
mode: "hcl",
|
mode: "hcl",
|
||||||
|
name: "Terraform (HCL)"
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
2261
package-lock.json
generated
137
package.json
@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "TriliumNext Notes",
|
"productName": "TriliumNext Notes",
|
||||||
"description": "Build your personal knowledge base with TriliumNext Notes",
|
"description": "Build your personal knowledge base with TriliumNext Notes",
|
||||||
"version": "0.91.6",
|
"version": "0.92.2-beta",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "./dist/electron-main.js",
|
"main": "./dist/electron-main.js",
|
||||||
"author": {
|
"author": {
|
||||||
@ -20,69 +20,68 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start-server": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
"server:start": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
||||||
"start-server-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
"server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
||||||
"start-server-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
"server:start-no-dir": "cross-env TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/main.ts",
|
||||||
"start-test-server": "npm run switch-server && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
|
"server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
|
||||||
"qstart-server": "npm run switch-server && npm run start-server",
|
"server:qstart": "npm run server:switch && npm run server:start",
|
||||||
"start-electron": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
|
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
|
||||||
"start-electron-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
"electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .",
|
||||||
"start-electron-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
|
"electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .",
|
||||||
"start-electron-no-dir-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
"electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_34 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
||||||
"start-electron-prod": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
|
"electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
||||||
"start-electron-prod-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
"electron:start-prod": "npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .",
|
||||||
"start-electron-prod-no-dir": "npm run prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
|
"electron:start-prod-no-dir": "npm run build:prepare-dist && cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
|
||||||
"start-electron-prod-no-dir-nix": "electron-rebuild --version 33.3.1 && npm run prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
"electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
||||||
"qstart-electron": "npm run switch-electron && npm run start-electron",
|
"electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
||||||
"switch-server": "rimraf ./node_modules/better-sqlite3 && npm install",
|
"electron:qstart": "npm run electron:switch && npm run electron:start",
|
||||||
"switch-electron": "electron-rebuild",
|
"electron:switch": "electron-rebuild",
|
||||||
"build-backend-docs": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
|
"electron-forge:start": "npm run build:prepare-dist && electron-forge start",
|
||||||
"build-frontend-docs": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
|
"electron-forge:make": "npm run build:prepare-dist && electron-forge make",
|
||||||
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
|
"electron-forge:package": "npm run build:prepare-dist && electron-forge package",
|
||||||
"webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
|
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
|
||||||
"test-playwright": "playwright test",
|
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
|
||||||
"test": "cross-env TRILIUM_DATA_DIR=./data-test vitest",
|
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
|
||||||
"test-coverage": "cross-env TRILIUM_DATA_DIR=./data-test vitest --coverage",
|
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
|
||||||
"start-electron-forge": "npm run prepare-dist && electron-forge start",
|
"build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
|
||||||
"make-electron": "npm run webpack && npm run prepare-dist && electron-forge make",
|
"test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
|
||||||
"package-electron": "electron-forge package",
|
"test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage",
|
||||||
"prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
|
"test:playwright": "playwright test",
|
||||||
"watch-dist": "tsx ./bin/watch-dist.ts",
|
"test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||||
"update-build-info": "tsx bin/update-build-info.ts",
|
"test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||||
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
"test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||||
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
"dev:watch-dist": "tsx ./bin/watch-dist.ts",
|
||||||
"integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
"dev:prettier-check": "prettier . --check",
|
||||||
"generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
|
"dev:prettier-fix": "prettier . --write",
|
||||||
"ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
|
"chore:update-build-info": "tsx bin/update-build-info.ts",
|
||||||
"prettier-check": "prettier . --check",
|
"chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts",
|
||||||
"prettier-fix": "prettier . --write"
|
"chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
|
||||||
|
"chore:generate-openapi": "tsx bin/generate-openapi.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "7.1.1",
|
"@braintree/sanitize-url": "7.1.1",
|
||||||
"@electron/remote": "2.1.2",
|
"@electron/remote": "2.1.2",
|
||||||
"@excalidraw/excalidraw": "0.17.6",
|
"@excalidraw/excalidraw": "0.17.6",
|
||||||
|
"@fullcalendar/core": "6.1.15",
|
||||||
|
"@fullcalendar/daygrid": "6.1.15",
|
||||||
|
"@fullcalendar/interaction": "6.1.15",
|
||||||
"@highlightjs/cdn-assets": "11.11.1",
|
"@highlightjs/cdn-assets": "11.11.1",
|
||||||
"@joplin/turndown-plugin-gfm": "1.0.61",
|
"@joplin/turndown-plugin-gfm": "1.0.61",
|
||||||
"@mermaid-js/layout-elk": "0.1.7",
|
"@mermaid-js/layout-elk": "0.1.7",
|
||||||
"@mind-elixir/node-menu": "1.0.4",
|
"@mind-elixir/node-menu": "1.0.4",
|
||||||
"@triliumnext/express-partial-content": "1.0.1",
|
"@triliumnext/express-partial-content": "1.0.1",
|
||||||
"@types/jquery.fancytree": "0.0.11",
|
|
||||||
"@types/js-yaml": "4.0.9",
|
|
||||||
"@types/leaflet": "1.9.16",
|
|
||||||
"@types/react-dom": "18.3.5",
|
|
||||||
"@types/swagger-ui-express": "4.1.7",
|
|
||||||
"archiver": "7.0.1",
|
"archiver": "7.0.1",
|
||||||
"async-mutex": "0.5.0",
|
"async-mutex": "0.5.0",
|
||||||
"autocomplete.js": "0.38.1",
|
"autocomplete.js": "0.38.1",
|
||||||
"axios": "1.7.9",
|
"axios": "1.7.9",
|
||||||
"better-sqlite3": "11.8.1",
|
"better-sqlite3": "11.8.1",
|
||||||
"bootstrap": "5.3.3",
|
|
||||||
"boxicons": "2.1.4",
|
"boxicons": "2.1.4",
|
||||||
|
"chardet": "2.0.0",
|
||||||
"cheerio": "1.0.0",
|
"cheerio": "1.0.0",
|
||||||
"chokidar": "4.0.3",
|
"chokidar": "4.0.3",
|
||||||
"cls-hooked": "4.2.2",
|
"cls-hooked": "4.2.2",
|
||||||
"codemirror": "5.65.18",
|
"codemirror": "5.65.18",
|
||||||
"compression": "1.7.5",
|
"compression": "1.8.0",
|
||||||
"cookie-parser": "1.4.7",
|
"cookie-parser": "1.4.7",
|
||||||
"csrf-csrf": "3.1.0",
|
"csrf-csrf": "3.1.0",
|
||||||
"dayjs": "1.11.13",
|
"dayjs": "1.11.13",
|
||||||
@ -144,6 +143,7 @@
|
|||||||
"source-map-support": "0.5.21",
|
"source-map-support": "0.5.21",
|
||||||
"split.js": "1.6.5",
|
"split.js": "1.6.5",
|
||||||
"stream-throttle": "0.1.3",
|
"stream-throttle": "0.1.3",
|
||||||
|
"strip-bom": "5.0.0",
|
||||||
"striptags": "3.2.0",
|
"striptags": "3.2.0",
|
||||||
"swagger-ui-express": "5.0.1",
|
"swagger-ui-express": "5.0.1",
|
||||||
"tmp": "0.2.3",
|
"tmp": "0.2.3",
|
||||||
@ -151,21 +151,22 @@
|
|||||||
"turndown": "7.2.0",
|
"turndown": "7.2.0",
|
||||||
"unescape": "1.0.1",
|
"unescape": "1.0.1",
|
||||||
"vanilla-js-wheel-zoom": "9.0.4",
|
"vanilla-js-wheel-zoom": "9.0.4",
|
||||||
"ws": "8.18.0",
|
"ws": "8.18.1",
|
||||||
"xml2js": "0.6.2",
|
"xml2js": "0.6.2",
|
||||||
"yauzl": "3.2.0"
|
"yauzl": "3.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron-forge/cli": "7.6.1",
|
"@electron-forge/cli": "7.7.0",
|
||||||
"@electron-forge/maker-deb": "7.6.1",
|
"@electron-forge/maker-deb": "7.7.0",
|
||||||
"@electron-forge/maker-dmg": "7.6.1",
|
"@electron-forge/maker-dmg": "7.7.0",
|
||||||
"@electron-forge/maker-flatpak": "7.6.1",
|
"@electron-forge/maker-flatpak": "7.7.0",
|
||||||
"@electron-forge/maker-rpm": "7.6.1",
|
"@electron-forge/maker-rpm": "7.7.0",
|
||||||
"@electron-forge/maker-squirrel": "7.6.1",
|
"@electron-forge/maker-squirrel": "7.7.0",
|
||||||
"@electron-forge/maker-zip": "7.6.1",
|
"@electron-forge/maker-zip": "7.7.0",
|
||||||
"@electron-forge/plugin-auto-unpack-natives": "7.6.1",
|
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||||
"@electron/rebuild": "3.7.1",
|
"@electron/rebuild": "3.7.1",
|
||||||
"@playwright/test": "1.50.1",
|
"@playwright/test": "1.50.1",
|
||||||
|
"@popperjs/core": "2.11.8",
|
||||||
"@types/archiver": "6.0.3",
|
"@types/archiver": "6.0.3",
|
||||||
"@types/better-sqlite3": "7.6.12",
|
"@types/better-sqlite3": "7.6.12",
|
||||||
"@types/bootstrap": "5.2.10",
|
"@types/bootstrap": "5.2.10",
|
||||||
@ -182,14 +183,17 @@
|
|||||||
"@types/fs-extra": "11.0.4",
|
"@types/fs-extra": "11.0.4",
|
||||||
"@types/html": "1.0.4",
|
"@types/html": "1.0.4",
|
||||||
"@types/ini": "4.1.1",
|
"@types/ini": "4.1.1",
|
||||||
"@types/jasmine": "5.1.5",
|
|
||||||
"@types/jquery": "3.5.32",
|
"@types/jquery": "3.5.32",
|
||||||
|
"@types/jquery.fancytree": "0.0.11",
|
||||||
|
"@types/js-yaml": "4.0.9",
|
||||||
"@types/jsdom": "21.1.7",
|
"@types/jsdom": "21.1.7",
|
||||||
|
"@types/leaflet": "1.9.16",
|
||||||
"@types/leaflet-gpx": "1.3.7",
|
"@types/leaflet-gpx": "1.3.7",
|
||||||
"@types/mime-types": "2.1.4",
|
"@types/mime-types": "2.1.4",
|
||||||
"@types/multer": "1.4.12",
|
"@types/multer": "1.4.12",
|
||||||
"@types/node": "22.13.1",
|
"@types/node": "22.13.5",
|
||||||
"@types/react": "18.3.18",
|
"@types/react": "18.3.18",
|
||||||
|
"@types/react-dom": "18.3.5",
|
||||||
"@types/safe-compare": "1.1.2",
|
"@types/safe-compare": "1.1.2",
|
||||||
"@types/sanitize-html": "2.13.0",
|
"@types/sanitize-html": "2.13.0",
|
||||||
"@types/sax": "1.2.7",
|
"@types/sax": "1.2.7",
|
||||||
@ -197,27 +201,36 @@
|
|||||||
"@types/session-file-store": "1.2.5",
|
"@types/session-file-store": "1.2.5",
|
||||||
"@types/source-map-support": "0.5.10",
|
"@types/source-map-support": "0.5.10",
|
||||||
"@types/stream-throttle": "0.1.4",
|
"@types/stream-throttle": "0.1.4",
|
||||||
|
"@types/swagger-ui-express": "4.1.8",
|
||||||
"@types/tmp": "0.2.6",
|
"@types/tmp": "0.2.6",
|
||||||
"@types/turndown": "5.0.5",
|
"@types/turndown": "5.0.5",
|
||||||
"@types/ws": "8.5.14",
|
"@types/ws": "8.5.14",
|
||||||
"@types/xml2js": "0.4.14",
|
"@types/xml2js": "0.4.14",
|
||||||
"@types/yargs": "17.0.33",
|
"@types/yargs": "17.0.33",
|
||||||
"@vitest/coverage-v8": "3.0.5",
|
"@vitest/coverage-v8": "3.0.6",
|
||||||
|
"autoprefixer": "10.4.20",
|
||||||
|
"bootstrap": "5.3.3",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"electron": "34.1.1",
|
"css-loader": "7.1.2",
|
||||||
|
"electron": "34.2.0",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
"jsdoc": "4.0.4",
|
"jsdoc": "4.0.4",
|
||||||
"lorem-ipsum": "2.0.8",
|
"lorem-ipsum": "2.0.8",
|
||||||
|
"mini-css-extract-plugin": "2.9.2",
|
||||||
"nodemon": "3.1.9",
|
"nodemon": "3.1.9",
|
||||||
"prettier": "3.5.0",
|
"postcss-loader": "8.1.1",
|
||||||
|
"prettier": "3.5.2",
|
||||||
"rcedit": "4.0.1",
|
"rcedit": "4.0.1",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
|
"sass": "1.85.0",
|
||||||
|
"sass-loader": "16.0.5",
|
||||||
|
"swagger-jsdoc": "6.2.8",
|
||||||
"tslib": "2.8.1",
|
"tslib": "2.8.1",
|
||||||
"tsx": "4.19.2",
|
"tsx": "4.19.3",
|
||||||
"typedoc": "0.27.7",
|
"typedoc": "0.27.8",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.7.3",
|
||||||
"vitest": "3.0.5",
|
"vitest": "3.0.6",
|
||||||
"webpack": "5.97.1",
|
"webpack": "5.98.0",
|
||||||
"webpack-cli": "6.0.1",
|
"webpack-cli": "6.0.1",
|
||||||
"webpack-dev-middleware": "7.4.2"
|
"webpack-dev-middleware": "7.4.2"
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export default defineConfig({
|
|||||||
|
|
||||||
/* Run your local dev server before starting the tests */
|
/* Run your local dev server before starting the tests */
|
||||||
webServer: !process.env.TRILIUM_DOCKER ? {
|
webServer: !process.env.TRILIUM_DOCKER ? {
|
||||||
command: 'npm run integration-mem-db-dev',
|
command: 'npm run test:integration-mem-db-dev',
|
||||||
url: SERVER_URL,
|
url: SERVER_URL,
|
||||||
reuseExistingServer: !process.env.CI,
|
reuseExistingServer: !process.env.CI,
|
||||||
} : undefined,
|
} : undefined,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import etapi from "../support/etapi.js";
|
import etapi from "../support/etapi.js";
|
||||||
|
/* TriliumNextTODO: port to Vitest
|
||||||
etapi.describeEtapi("app_info", () => {
|
etapi.describeEtapi("app_info", () => {
|
||||||
it("get", async () => {
|
it("get", async () => {
|
||||||
const appInfo = await etapi.getEtapi("app-info");
|
const appInfo = await etapi.getEtapi("app-info");
|
||||||
expect(appInfo.clipperProtocolVersion).toEqual("1.0");
|
expect(appInfo.clipperProtocolVersion).toEqual("1.0");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
@ -1,8 +1,10 @@
|
|||||||
import etapi from "../support/etapi.js";
|
import etapi from "../support/etapi.js";
|
||||||
|
|
||||||
|
/* TriliumNextTODO: port to Vitest
|
||||||
etapi.describeEtapi("backup", () => {
|
etapi.describeEtapi("backup", () => {
|
||||||
it("create", async () => {
|
it("create", async () => {
|
||||||
const response = await etapi.putEtapiContent("backup/etapi_test");
|
const response = await etapi.putEtapiContent("backup/etapi_test");
|
||||||
expect(response.status).toEqual(204);
|
expect(response.status).toEqual(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
@ -3,6 +3,7 @@ import fs from "fs";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
/* TriliumNextTODO: port to Vitest
|
||||||
etapi.describeEtapi("import", () => {
|
etapi.describeEtapi("import", () => {
|
||||||
// temporarily skip this test since test-export.zip is missing
|
// temporarily skip this test since test-export.zip is missing
|
||||||
xit("import", async () => {
|
xit("import", async () => {
|
||||||
@ -22,3 +23,4 @@ etapi.describeEtapi("import", () => {
|
|||||||
expect(content).toContain("test export content");
|
expect(content).toContain("test export content");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
@ -1,6 +1,7 @@
|
|||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import etapi from "../support/etapi.js";
|
import etapi from "../support/etapi.js";
|
||||||
|
|
||||||
|
/* TriliumNextTODO: port to Vitest
|
||||||
etapi.describeEtapi("notes", () => {
|
etapi.describeEtapi("notes", () => {
|
||||||
it("create", async () => {
|
it("create", async () => {
|
||||||
const { note, branch } = await etapi.postEtapi("create-note", {
|
const { note, branch } = await etapi.postEtapi("create-note", {
|
||||||
@ -99,3 +100,4 @@ etapi.describeEtapi("notes", () => {
|
|||||||
expect(error.message).toEqual(`Note '${note.noteId}' not found.`);
|
expect(error.message).toEqual(`Note '${note.noteId}' not found.`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
@ -1,4 +1,5 @@
|
|||||||
import type child_process from "child_process";
|
import type child_process from "child_process";
|
||||||
|
import { describe, beforeAll, afterAll } from "vitest";
|
||||||
|
|
||||||
let etapiAuthToken: string | undefined;
|
let etapiAuthToken: string | undefined;
|
||||||
|
|
||||||
|
@ -1,3 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Reads the level of indentation of the first line and trims the identation for all the text by that amount.
|
||||||
|
*
|
||||||
|
* For example, for:
|
||||||
|
*
|
||||||
|
* ```json
|
||||||
|
* {
|
||||||
|
* "hello": "world"
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* it results in:
|
||||||
|
*
|
||||||
|
* ```json
|
||||||
|
* {
|
||||||
|
* "hello": "world"
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* This is meant to be used as a template string, where it allows the indentation of the template without affecting whitespace changes.
|
||||||
|
*
|
||||||
|
* @example const html = trimIndentation`\
|
||||||
|
* <h1>Heading 1</h1>
|
||||||
|
* <h2>Heading 2</h2>
|
||||||
|
* <h3>Heading 3</h3>
|
||||||
|
* <h4>Heading 4</h4>
|
||||||
|
* <h5>Heading 5</h5>
|
||||||
|
* <h6>Heading 6</h6>
|
||||||
|
* `;
|
||||||
|
* @param strings
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function trimIndentation(strings: TemplateStringsArray) {
|
export function trimIndentation(strings: TemplateStringsArray) {
|
||||||
const str = strings.toString();
|
const str = strings.toString();
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import type { AttachmentRow, BlobRow, RevisionRow } from "./entities/rows.js";
|
|||||||
import BBlob from "./entities/bblob.js";
|
import BBlob from "./entities/bblob.js";
|
||||||
import BRecentNote from "./entities/brecent_note.js";
|
import BRecentNote from "./entities/brecent_note.js";
|
||||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||||
|
import type BTask from "./entities/btask.js";
|
||||||
|
|
||||||
interface AttachmentOpts {
|
interface AttachmentOpts {
|
||||||
includeContentLength?: boolean;
|
includeContentLength?: boolean;
|
||||||
@ -32,6 +33,7 @@ export default class Becca {
|
|||||||
attributeIndex!: Record<string, BAttribute[]>;
|
attributeIndex!: Record<string, BAttribute[]>;
|
||||||
options!: Record<string, BOption>;
|
options!: Record<string, BOption>;
|
||||||
etapiTokens!: Record<string, BEtapiToken>;
|
etapiTokens!: Record<string, BEtapiToken>;
|
||||||
|
tasks!: Record<string, BTask>;
|
||||||
|
|
||||||
allNoteSetCache: NoteSet | null;
|
allNoteSetCache: NoteSet | null;
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ export default class Becca {
|
|||||||
this.attributeIndex = {};
|
this.attributeIndex = {};
|
||||||
this.options = {};
|
this.options = {};
|
||||||
this.etapiTokens = {};
|
this.etapiTokens = {};
|
||||||
|
this.tasks = {};
|
||||||
|
|
||||||
this.dirtyNoteSetCache();
|
this.dirtyNoteSetCache();
|
||||||
|
|
||||||
@ -213,6 +216,14 @@ export default class Becca {
|
|||||||
return this.etapiTokens[etapiTokenId];
|
return this.etapiTokens[etapiTokenId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTasks(): BTask[] {
|
||||||
|
return Object.values(this.tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTask(taskId: string): BTask | null {
|
||||||
|
return this.tasks[taskId];
|
||||||
|
}
|
||||||
|
|
||||||
getEntity<T extends AbstractBeccaEntity<T>>(entityName: string, entityId: string): AbstractBeccaEntity<T> | null {
|
getEntity<T extends AbstractBeccaEntity<T>>(entityName: string, entityId: string): AbstractBeccaEntity<T> | null {
|
||||||
if (!entityName || !entityId) {
|
if (!entityName || !entityId) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,9 +11,10 @@ import BOption from "./entities/boption.js";
|
|||||||
import BEtapiToken from "./entities/betapi_token.js";
|
import BEtapiToken from "./entities/betapi_token.js";
|
||||||
import cls from "../services/cls.js";
|
import cls from "../services/cls.js";
|
||||||
import entityConstructor from "../becca/entity_constructor.js";
|
import entityConstructor from "../becca/entity_constructor.js";
|
||||||
import type { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow } from "./entities/rows.js";
|
import type { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow, TaskRow } from "./entities/rows.js";
|
||||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||||
import ws from "../services/ws.js";
|
import ws from "../services/ws.js";
|
||||||
|
import BTask from "./entities/btask.js";
|
||||||
|
|
||||||
const beccaLoaded = new Promise<void>(async (res, rej) => {
|
const beccaLoaded = new Promise<void>(async (res, rej) => {
|
||||||
const sqlInit = (await import("../services/sql_init.js")).default;
|
const sqlInit = (await import("../services/sql_init.js")).default;
|
||||||
@ -63,6 +64,10 @@ function load() {
|
|||||||
for (const row of sql.getRows<EtapiTokenRow>(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
|
for (const row of sql.getRows<EtapiTokenRow>(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
|
||||||
new BEtapiToken(row);
|
new BEtapiToken(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const row of sql.getRows<TaskRow>(`SELECT taskId, parentNoteId, title, dueDate, isDone, isDeleted FROM tasks WHERE isDeleted = 0`)) {
|
||||||
|
new BTask(row);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const noteId in becca.notes) {
|
for (const noteId in becca.notes) {
|
||||||
|
@ -159,7 +159,7 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.noteId === "root" || this.noteId === cls.getHoistedNoteId()) {
|
if ((this.noteId === "root" || this.noteId === cls.getHoistedNoteId()) && !this.isWeak) {
|
||||||
throw new Error("Can't delete root or hoisted branch/note");
|
throw new Error("Can't delete root or hoisted branch/note");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
84
src/becca/entities/btask.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import date_utils from "../../services/date_utils.js";
|
||||||
|
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||||
|
import type BOption from "./boption.js";
|
||||||
|
import type { TaskRow } from "./rows.js";
|
||||||
|
|
||||||
|
export default class BTask extends AbstractBeccaEntity<BOption> {
|
||||||
|
|
||||||
|
static get entityName() {
|
||||||
|
return "tasks";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get primaryKeyName() {
|
||||||
|
return "taskId";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get hashedProperties() {
|
||||||
|
return [ "taskId", "parentNoteId", "title", "dueDate", "isDone", "isDeleted" ];
|
||||||
|
}
|
||||||
|
|
||||||
|
taskId?: string;
|
||||||
|
parentNoteId!: string;
|
||||||
|
title!: string;
|
||||||
|
dueDate?: string;
|
||||||
|
isDone!: boolean;
|
||||||
|
private _isDeleted?: boolean;
|
||||||
|
|
||||||
|
constructor(row?: TaskRow) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
if (!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateFromRow(row);
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
get isDeleted() {
|
||||||
|
return !!this._isDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFromRow(row: TaskRow) {
|
||||||
|
this.taskId = row.taskId;
|
||||||
|
this.parentNoteId = row.parentNoteId;
|
||||||
|
this.title = row.title;
|
||||||
|
this.dueDate = row.dueDate;
|
||||||
|
this.isDone = !!row.isDone;
|
||||||
|
this._isDeleted = !!row.isDeleted;
|
||||||
|
this.utcDateModified = row.utcDateModified;
|
||||||
|
|
||||||
|
if (this.taskId) {
|
||||||
|
this.becca.tasks[this.taskId] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (this.taskId) {
|
||||||
|
this.becca.tasks[this.taskId] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected beforeSaving(opts?: {}): void {
|
||||||
|
super.beforeSaving();
|
||||||
|
|
||||||
|
this.utcDateModified = date_utils.utcNowDateTime();
|
||||||
|
|
||||||
|
if (this.taskId) {
|
||||||
|
this.becca.tasks[this.taskId] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPojo() {
|
||||||
|
return {
|
||||||
|
taskId: this.taskId,
|
||||||
|
parentNoteId: this.parentNoteId,
|
||||||
|
title: this.title,
|
||||||
|
dueDate: this.dueDate,
|
||||||
|
isDone: this.isDone,
|
||||||
|
isDeleted: this.isDeleted,
|
||||||
|
utcDateModified: this.utcDateModified
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
// TODO: Booleans should probably be numbers instead (as SQLite does not have booleans.);
|
// TODO: Booleans should probably be numbers instead (as SQLite does not have booleans.);
|
||||||
|
// TODO: check against schema.sql which properties really are "optional"
|
||||||
|
|
||||||
export interface AttachmentRow {
|
export interface AttachmentRow {
|
||||||
attachmentId?: string;
|
attachmentId?: string;
|
||||||
@ -12,6 +13,8 @@ export interface AttachmentRow {
|
|||||||
dateModified?: string;
|
dateModified?: string;
|
||||||
utcDateModified?: string;
|
utcDateModified?: string;
|
||||||
utcDateScheduledForErasureSince?: string;
|
utcDateScheduledForErasureSince?: string;
|
||||||
|
isDeleted?: boolean;
|
||||||
|
deleteId?: string;
|
||||||
contentLength?: number;
|
contentLength?: number;
|
||||||
content?: Buffer | string;
|
content?: Buffer | string;
|
||||||
}
|
}
|
||||||
@ -136,3 +139,13 @@ export interface NoteRow {
|
|||||||
utcDateModified: string;
|
utcDateModified: string;
|
||||||
content?: string | Buffer;
|
content?: string | Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TaskRow {
|
||||||
|
taskId?: string;
|
||||||
|
parentNoteId: string;
|
||||||
|
title: string;
|
||||||
|
dueDate?: string;
|
||||||
|
isDone?: boolean;
|
||||||
|
isDeleted?: boolean;
|
||||||
|
utcDateModified?: string;
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ import BNote from "./entities/bnote.js";
|
|||||||
import BOption from "./entities/boption.js";
|
import BOption from "./entities/boption.js";
|
||||||
import BRecentNote from "./entities/brecent_note.js";
|
import BRecentNote from "./entities/brecent_note.js";
|
||||||
import BRevision from "./entities/brevision.js";
|
import BRevision from "./entities/brevision.js";
|
||||||
|
import BTask from "./entities/btask.js";
|
||||||
|
|
||||||
type EntityClass = new (row?: any) => AbstractBeccaEntity<any>;
|
type EntityClass = new (row?: any) => AbstractBeccaEntity<any>;
|
||||||
|
|
||||||
@ -21,7 +22,8 @@ const ENTITY_NAME_TO_ENTITY: Record<string, ConstructorData<any> & EntityClass>
|
|||||||
notes: BNote,
|
notes: BNote,
|
||||||
options: BOption,
|
options: BOption,
|
||||||
recent_notes: BRecentNote,
|
recent_notes: BRecentNote,
|
||||||
revisions: BRevision
|
revisions: BRevision,
|
||||||
|
tasks: BTask
|
||||||
};
|
};
|
||||||
|
|
||||||
function getEntityFromEntityName(entityName: keyof typeof ENTITY_NAME_TO_ENTITY) {
|
function getEntityFromEntityName(entityName: keyof typeof ENTITY_NAME_TO_ENTITY) {
|
||||||
|
@ -80,6 +80,7 @@ export type CommandMappings = {
|
|||||||
};
|
};
|
||||||
closeTocCommand: CommandData;
|
closeTocCommand: CommandData;
|
||||||
showLaunchBarSubtree: CommandData;
|
showLaunchBarSubtree: CommandData;
|
||||||
|
showRevisions: CommandData;
|
||||||
showOptions: CommandData & {
|
showOptions: CommandData & {
|
||||||
section: string;
|
section: string;
|
||||||
};
|
};
|
||||||
@ -106,10 +107,6 @@ export type CommandMappings = {
|
|||||||
showInfoDialog: ConfirmWithMessageOptions;
|
showInfoDialog: ConfirmWithMessageOptions;
|
||||||
showConfirmDialog: ConfirmWithMessageOptions;
|
showConfirmDialog: ConfirmWithMessageOptions;
|
||||||
showRecentChanges: CommandData & { ancestorNoteId: string };
|
showRecentChanges: CommandData & { ancestorNoteId: string };
|
||||||
showExportDialog: CommandData & {
|
|
||||||
notePath: string;
|
|
||||||
defaultType: "subtree"
|
|
||||||
};
|
|
||||||
showImportDialog: CommandData & { noteId: string; };
|
showImportDialog: CommandData & { noteId: string; };
|
||||||
openNewNoteSplit: NoteCommandData;
|
openNewNoteSplit: NoteCommandData;
|
||||||
openInWindow: NoteCommandData;
|
openInWindow: NoteCommandData;
|
||||||
@ -119,6 +116,8 @@ export type CommandMappings = {
|
|||||||
hideLeftPane: CommandData;
|
hideLeftPane: CommandData;
|
||||||
showLeftPane: CommandData;
|
showLeftPane: CommandData;
|
||||||
hoistNote: CommandData & { noteId: string };
|
hoistNote: CommandData & { noteId: string };
|
||||||
|
leaveProtectedSession: CommandData;
|
||||||
|
enterProtectedSession: CommandData;
|
||||||
|
|
||||||
openInTab: ContextMenuCommandData;
|
openInTab: ContextMenuCommandData;
|
||||||
openNoteInSplit: ContextMenuCommandData;
|
openNoteInSplit: ContextMenuCommandData;
|
||||||
@ -225,10 +224,18 @@ export type CommandMappings = {
|
|||||||
|
|
||||||
reEvaluateRightPaneVisibility: CommandData;
|
reEvaluateRightPaneVisibility: CommandData;
|
||||||
runActiveNote: CommandData;
|
runActiveNote: CommandData;
|
||||||
|
scrollContainerToCommand: CommandData & {
|
||||||
|
position: number;
|
||||||
|
};
|
||||||
|
moveThisNoteSplit: CommandData & {
|
||||||
|
isMovingLeft: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
// Geomap
|
// Geomap
|
||||||
deleteFromMap: { noteId: string },
|
deleteFromMap: { noteId: string },
|
||||||
openGeoLocation: { noteId: string, event: JQuery.MouseDownEvent }
|
openGeoLocation: { noteId: string, event: JQuery.MouseDownEvent }
|
||||||
|
|
||||||
|
toggleZenMode: CommandData;
|
||||||
};
|
};
|
||||||
|
|
||||||
type EventMappings = {
|
type EventMappings = {
|
||||||
@ -306,6 +313,7 @@ type EventMappings = {
|
|||||||
noteContextReorderEvent: {
|
noteContextReorderEvent: {
|
||||||
oldMainNtxId: string;
|
oldMainNtxId: string;
|
||||||
newMainNtxId: string;
|
newMainNtxId: string;
|
||||||
|
ntxIdsInOrder: string[];
|
||||||
};
|
};
|
||||||
newNoteContextCreated: {
|
newNoteContextCreated: {
|
||||||
noteContext: NoteContext;
|
noteContext: NoteContext;
|
||||||
@ -314,7 +322,7 @@ type EventMappings = {
|
|||||||
ntxIds: string[];
|
ntxIds: string[];
|
||||||
};
|
};
|
||||||
exportSvg: {
|
exportSvg: {
|
||||||
ntxId: string;
|
ntxId: string | null | undefined;
|
||||||
};
|
};
|
||||||
geoMapCreateChildNote: {
|
geoMapCreateChildNote: {
|
||||||
ntxId: string | null | undefined; // TODO: deduplicate ntxId
|
ntxId: string | null | undefined; // TODO: deduplicate ntxId
|
||||||
@ -330,6 +338,7 @@ type EventMappings = {
|
|||||||
};
|
};
|
||||||
scrollToEnd: { ntxId: string };
|
scrollToEnd: { ntxId: string };
|
||||||
noteTypeMimeChanged: { noteId: string };
|
noteTypeMimeChanged: { noteId: string };
|
||||||
|
zenModeChanged: { isEnabled: boolean };
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EventListener<T extends EventNames> = {
|
export type EventListener<T extends EventNames> = {
|
||||||
|
@ -290,7 +290,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
|
|||||||
return (
|
return (
|
||||||
this.note &&
|
this.note &&
|
||||||
["default", "contextual-help"].includes(this.viewScope?.viewMode ?? "") &&
|
["default", "contextual-help"].includes(this.viewScope?.viewMode ?? "") &&
|
||||||
this.note.hasChildren() &&
|
(this.note.hasChildren() || this.note.getLabelValue("viewType") === "calendar") &&
|
||||||
["book", "text", "code"].includes(this.note.type) &&
|
["book", "text", "code"].includes(this.note.type) &&
|
||||||
this.note.mime !== "text/x-sqlite;schema=trilium" &&
|
this.note.mime !== "text/x-sqlite;schema=trilium" &&
|
||||||
!this.note.isLabelTruthy("hideChildrenOverview")
|
!this.note.isLabelTruthy("hideChildrenOverview")
|
||||||
|
@ -178,6 +178,13 @@ export default class RootCommandExecutor extends Component {
|
|||||||
for (const window of windows) window[action]();
|
for (const window of windows) window[action]();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleZenModeCommand() {
|
||||||
|
const $body = $("body");
|
||||||
|
$body.toggleClass("zen");
|
||||||
|
const isEnabled = $body.hasClass("zen");
|
||||||
|
appContext.triggerEvent("zenModeChanged", { isEnabled });
|
||||||
|
}
|
||||||
|
|
||||||
firstTabCommand() {
|
firstTabCommand() {
|
||||||
this.#goToTab(1);
|
this.#goToTab(1);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { t } from "./services/i18n.js";
|
|||||||
import options from "./services/options.js";
|
import options from "./services/options.js";
|
||||||
import type ElectronRemote from "@electron/remote";
|
import type ElectronRemote from "@electron/remote";
|
||||||
import type Electron from "electron";
|
import type Electron from "electron";
|
||||||
|
import "../stylesheets/bootstrap.scss";
|
||||||
|
|
||||||
await appContext.earlyInit();
|
await appContext.earlyInit();
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ function initOnElectron() {
|
|||||||
const currentWindow = electronRemote.getCurrentWindow();
|
const currentWindow = electronRemote.getCurrentWindow();
|
||||||
const style = window.getComputedStyle(document.body);
|
const style = window.getComputedStyle(document.body);
|
||||||
|
|
||||||
|
initDarkOrLightMode(style);
|
||||||
initTransparencyEffects(style, currentWindow);
|
initTransparencyEffects(style, currentWindow);
|
||||||
|
|
||||||
if (options.get("nativeTitleBarVisible") !== "true") {
|
if (options.get("nativeTitleBarVisible") !== "true") {
|
||||||
@ -91,3 +93,21 @@ function initTransparencyEffects(style: CSSStyleDeclaration, currentWindow: Elec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs Electron that we prefer a dark or light theme. Apart from changing prefers-color-scheme at CSS level which is a side effect,
|
||||||
|
* this fixes color issues with background effects or native title bars.
|
||||||
|
*
|
||||||
|
* @param style the root CSS element to read variables from.
|
||||||
|
*/
|
||||||
|
function initDarkOrLightMode(style: CSSStyleDeclaration) {
|
||||||
|
let themeSource: typeof nativeTheme.themeSource = "system";
|
||||||
|
|
||||||
|
const themeStyle = style.getPropertyValue("--theme-style");
|
||||||
|
if (style.getPropertyValue("--theme-style-auto") !== "true" && (themeStyle === "light" || themeStyle === "dark")) {
|
||||||
|
themeSource = themeStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { nativeTheme } = utils.dynamicRequire("@electron/remote") as typeof ElectronRemote;
|
||||||
|
nativeTheme.themeSource = themeSource;
|
||||||
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../../style.css">
|
||||||
|
<base target="_parent">
|
||||||
|
<title data-trilium-title>Custom resource providers</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1 data-trilium-h1>Custom resource providers</h1>
|
||||||
|
|
||||||
|
<div class="ck-content">
|
||||||
|
<p>A custom resource provider allows any file imported into Trilium (images,
|
||||||
|
fonts, stylesheets) to be publicly accessible via a URL.</p>
|
||||||
|
<p>A potential use case for this is to add embed a custom font alongside
|
||||||
|
a theme.</p>
|
||||||
|
<h2>Steps for creating a custom resource provider</h2>
|
||||||
|
<ol>
|
||||||
|
<li>Import a file such as an image or a font into Trilium by drag & drop.</li>
|
||||||
|
<li>Select the file and go to the <i>Owned Attributes</i> section.</li>
|
||||||
|
<li>Add the label <code>#customResourceProvider=hello</code>.</li>
|
||||||
|
<li>To test if it is working, use a browser to navigate to <code><protocol>://<host>/custom/hello</code> (where <code><protocol></code> is
|
||||||
|
either <code>http</code> or <code>https</code> based on your setup, and <code><host></code> is
|
||||||
|
the host or IP to your Trilium server instance). If you are running the
|
||||||
|
TriliumNext application without a server, use <code>http://localhost:37840</code> as
|
||||||
|
the base URL.</li>
|
||||||
|
<li>If everything went well, at the previous step the browser should have
|
||||||
|
downloaded the file uploaded in the first step.</li>
|
||||||
|
</ol>
|
||||||
|
<p>Instead of <code>hello</code>, the name can be:</p>
|
||||||
|
<ul>
|
||||||
|
<li>A path, such as <code>fonts/Roboto.ttf</code>, which would be accessible
|
||||||
|
via <code><host>/custom/fonts/Roboto.ttf</code>.</li>
|
||||||
|
<li>As a more advanced use case, a regular expression to match multiple routes,
|
||||||
|
such as <code>hello/.*</code> which will be accessible via <code>/custom/hello/1</code>, <code>/custom/hello/2</code>, <code>/custom/hello/world</code>,
|
||||||
|
etc.</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Using it in a theme</h2>
|
||||||
|
<p>For example, if you have a custom font to be imported by the theme, first
|
||||||
|
upload a font file into Trilium and assign it the <code>#customResourceProvider=fonts/myfont.ttf</code> attribute.</p>
|
||||||
|
<p>Then modify the theme CSS to point to:</p><pre><code class="language-text-css">@font-face {
|
||||||
|
font-family: customFont;
|
||||||
|
src: url("/custom/fonts/myfont.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-family: customFont;
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 125 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 79 KiB |
@ -5,32 +5,35 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="../../style.css">
|
<link rel="stylesheet" href="../../style.css">
|
||||||
<base target="_parent">
|
<base target="_parent">
|
||||||
<title data-trilium-title>Exporting as PDF</title>
|
<title data-trilium-title>Export as PDF</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1 data-trilium-h1>Exporting as PDF</h1>
|
<h1 data-trilium-h1>Export as PDF</h1>
|
||||||
|
|
||||||
<div class="ck-content">
|
<div class="ck-content">
|
||||||
<figure class="image image-style-align-right image_resized" style="width:47.17%;">
|
<figure class="image image-style-align-right image_resized" style="width:50.63%;">
|
||||||
<img style="aspect-ratio:951/432;" src="1_Exporting as PDF_image.png"
|
<img style="aspect-ratio:951/432;" src="Export as PDF_image.png" width="951"
|
||||||
width="951" height="432">
|
height="432">
|
||||||
|
<figcaption>Screenshot of the note contextual menu indicating the “Export as PDF”
|
||||||
|
option.</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
<p>On the desktop application of Trilium it is possible to export a note
|
<p>On the desktop application of Trilium it is possible to export a note
|
||||||
as PDF. On the server or PWA (mobile), the option is not available due
|
as PDF. On the server or PWA (mobile), the option is not available due
|
||||||
to technical constraints and it will be hidden.</p>
|
to technical constraints and it will be hidden.</p>
|
||||||
<p>To print a note, select the
|
<p>To print a note, select the
|
||||||
<img src="Exporting as PDF_image.png" width="29"
|
<img src="2_Export as PDF_image.png" width="29"
|
||||||
height="31">button to the right of the note and select <i>Export as PDF</i>.</p>
|
height="31">button to the right of the note and select <i>Export as PDF</i>.</p>
|
||||||
<p>Afterwards you will be prompted to select where to save the PDF file.
|
<p>Afterwards you will be prompted to select where to save the PDF file.
|
||||||
Upon confirmation, the resulting PDF will be opened automatically.</p>
|
Upon confirmation, the resulting PDF will be opened automatically using
|
||||||
|
the default/system application configured for PDFs.</p>
|
||||||
<p>Should you encounter any visual issues in the resulting PDF file (e.g.
|
<p>Should you encounter any visual issues in the resulting PDF file (e.g.
|
||||||
a table does not fit properly, there is cut off text, etc.) feel free to
|
a table does not fit properly, there is cut off text, etc.) feel free to
|
||||||
<a
|
<a
|
||||||
href="#root/OeKBfN6JbMIq/jRV1MPt4mNSP/hrC6xn7hnDq5">report the issue</a>. In this case, it's best to offer a sample note (click
|
href="#root/OeKBfN6JbMIq/jRV1MPt4mNSP/hrC6xn7hnDq5">report the issue</a>. In this case, it's best to offer a sample note (click
|
||||||
on the
|
on the
|
||||||
<img src="Exporting as PDF_image.png" width="29" height="31">button, select Export note → This note and all of its descendants → HTML
|
<img src="2_Export as PDF_image.png" width="29" height="31">button, select Export note → This note and all of its descendants → HTML
|
||||||
in ZIP archive). Make sure not to accidentally leak any personal information.</p>
|
in ZIP archive). Make sure not to accidentally leak any personal information.</p>
|
||||||
<h2>Landscape mode</h2>
|
<h2>Landscape mode</h2>
|
||||||
<p>When exporting to PDF, there are no customizable settings such as page
|
<p>When exporting to PDF, there are no customizable settings such as page
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
@ -0,0 +1,73 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../../style.css">
|
||||||
|
<base target="_parent">
|
||||||
|
<title data-trilium-title>Zen mode</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<h1 data-trilium-h1>Zen mode</h1>
|
||||||
|
|
||||||
|
<div class="ck-content">
|
||||||
|
<figure class="image image-style-align-center image_resized" style="width:62.15%;">
|
||||||
|
<img style="aspect-ratio:855/677;" src="5_Zen mode_image.png" width="855"
|
||||||
|
height="677">
|
||||||
|
<figcaption>Screenshot of Zen Mode activated on a Windows 11 system with native title
|
||||||
|
bar off and background effects on.</figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>When Zen Mode is activated (pictured on the side), most of the user interface
|
||||||
|
of Trilium is hidden away in order to be able to focus on the content,
|
||||||
|
whether it's for reading or writing.</p>
|
||||||
|
<figure class="image image-style-align-right image_resized"
|
||||||
|
style="width:17.65%;">
|
||||||
|
<img style="aspect-ratio:265/386;" src="3_Zen mode_image.png" width="265"
|
||||||
|
height="386">
|
||||||
|
<figcaption>Screenshot of the Zen Mode option in the global menu.</figcaption>
|
||||||
|
</figure>
|
||||||
|
<h2>Activating & deactivating</h2>
|
||||||
|
<p>The Zen Mode can be activated by accessing the global menu and selecting
|
||||||
|
the “Zen Mode” option:</p>
|
||||||
|
<p>Aside from the global menu, it's also possible to activate this mode by
|
||||||
|
using a keyboard shortcut which is Alt+Z by default. Look for <code>toggleZenMode</code> in
|
||||||
|
the shortcut configuration.</p>
|
||||||
|
<p>Once Zen Mode is activated, all the UI elements of the application will
|
||||||
|
be hidden away, including the global menu. In that case, the Zen Mode can
|
||||||
|
be deactivated either by pressing the
|
||||||
|
<img src="6_Zen mode_image.png" width="29"
|
||||||
|
height="31">icon in the top-right corner of the window or by pressing the keyboard
|
||||||
|
combination again.</p>
|
||||||
|
<p>Do note that, by design, activating or deactivating the Zen Mode applies
|
||||||
|
only to the current window. Restarting the application will also disable
|
||||||
|
the Zen Mode.</p>
|
||||||
|
<h2>Moving the window around</h2>
|
||||||
|
<p>If “Native title bar” is activated, then the operating system's default
|
||||||
|
title bar can be used to drag the window around. If deactivated, the window
|
||||||
|
can still be moved by dragging the mouse across the top part of the window
|
||||||
|
where the note titles are.</p>
|
||||||
|
<figure class="image image-style-align-left image_resized"
|
||||||
|
style="width:50%;">
|
||||||
|
<img style="aspect-ratio:1060/707;" src="7_Zen mode_image.png" width="1060"
|
||||||
|
height="707">
|
||||||
|
<figcaption>Screenshot of two notes side-by-side while Zen Mode is active, on Windows
|
||||||
|
11 with background effects off.</figcaption>
|
||||||
|
</figure>
|
||||||
|
<h2>Split windows and tabs</h2>
|
||||||
|
<p>Tabs are completely hidden, however it's still possible to use keyboard
|
||||||
|
shortcuts such as <code>firstTab</code> (Ctrl+1 by default), <code>secondTab</code> (Ctrl+2
|
||||||
|
by default). There are also some newer shortcuts such as <code>activateNextTab</code> (Ctrl+Tab)
|
||||||
|
or <code>activatePreviousTab</code> (Ctrl+Shift+Tab) that allow easy navigation,
|
||||||
|
however make sure that they are configured properly in the settings.</p>
|
||||||
|
<p>For the split view of notes, there are no keyboard shortcuts at the time
|
||||||
|
of writing, but it's still possible to have them in Zen Mode by creating
|
||||||
|
the split while the Zen Mode is off and then reactivating it afterwards.</p>
|
||||||
|
<p> </p>
|
||||||
|
<p> </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 323 KiB After Width: | Height: | Size: 323 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 515 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 397 KiB After Width: | Height: | Size: 397 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 7.3 KiB |