Merge remote-tracking branch 'origin/develop' into feature/i18n

This commit is contained in:
Elian Doran 2024-08-11 06:26:32 +03:00
commit 3a837cf663
No known key found for this signature in database
69 changed files with 3605 additions and 1101 deletions

View File

@ -16,140 +16,137 @@ env:
DOCKERHUB_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository }}
TEST_TAG: triliumnext/notes:test
PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7,linux/arm64/v8
PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7
jobs:
test_docker:
name: Check Docker build
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
name: Check Docker build
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- name: Run the TypeScript build
run: npx tsc
- name: Create server-package.json
run: cat package.json | grep -v electron > server-package.json
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- name: Run the TypeScript build
run: npx tsc
- name: Create server-package.json
run: cat package.json | grep -v electron > server-package.json
- name: Build and export to Docker
uses: docker/build-push-action@v6
with:
context: .
load: true
tags: ${{ env.TEST_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and export to Docker
uses: docker/build-push-action@v6
with:
context: .
load: true
tags: ${{ env.TEST_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run the container in the background
run: docker run -d --rm --name trilium_local ${{ env.TEST_TAG }}
- name: Run the container in the background
run: docker run -d --rm --name trilium_local ${{ env.TEST_TAG }}
- name: Wait for the healthchecks to pass
uses: stringbean/docker-healthcheck-action@v1
with:
container: trilium_local
wait-time: 50
require-status: running
require-healthy: true
- name: Wait for the healthchecks to pass
uses: stringbean/docker-healthcheck-action@v1
with:
container: trilium_local
wait-time: 50
require-status: running
require-healthy: true
build_docker:
name: Build Docker images
runs-on: ubuntu-latest
needs:
- test_docker
permissions:
contents: read
packages: write
attestations: write
id-token: write
strategy:
matrix:
architecture: [linux/amd64, linux/arm64, linux/arm/v7, linux/arm64/v8]
steps:
- uses: actions/checkout@v4
- name: Extract metadata (tags, labels) for GHCR image
id: ghcr-meta
uses: docker/metadata-action@v4
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha
- name: Extract metadata (tags, labels) for DockerHub image
id: dh-meta
uses: docker/metadata-action@v4
with:
images: ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- name: Run the TypeScript build
run: npx tsc
- name: Create server-package.json
run: cat package.json | grep -v electron > server-package.json
- name: Log in to the GHCR container registry
uses: docker/login-action@v2
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- name: Build and push container image to GHCR
uses: docker/build-push-action@v6
id: ghcr-push
with:
context: .
platforms: ${{ matrix.architecture }}
push: true
tags: ${{ steps.ghcr-meta.outputs.tags }}
labels: ${{ steps.ghcr-meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate and push artifact attestation to GHCR
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.ghcr-push.outputs.digest }}
push-to-registry: true
- name: Log in to the DockerHub container registry
uses: docker/login-action@v2
with:
registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push image to DockerHub
uses: docker/build-push-action@v6
id: dh-push
with:
context: .
platforms: ${{ matrix.architecture }}
push: true
tags: ${{ steps.dh-meta.outputs.tags }}
labels: ${{ steps.dh-meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate and push artifact attestation to DockerHub
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.dh-push.outputs.digest }}
push-to-registry: true
name: Build Docker images
runs-on: ubuntu-latest
needs:
- test_docker
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: Extract metadata (tags, labels) for GHCR image
id: ghcr-meta
uses: docker/metadata-action@v4
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha
- name: Extract metadata (tags, labels) for DockerHub image
id: dh-meta
uses: docker/metadata-action@v4
with:
images: ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- name: Run the TypeScript build
run: npx tsc
- name: Create server-package.json
run: cat package.json | grep -v electron > server-package.json
- name: Log in to the GHCR container registry
uses: docker/login-action@v2
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- name: Build and push container image to GHCR
uses: docker/build-push-action@v6
id: ghcr-push
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
tags: ${{ steps.ghcr-meta.outputs.tags }}
labels: ${{ steps.ghcr-meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate and push artifact attestation to GHCR
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.ghcr-push.outputs.digest }}
push-to-registry: true
- name: Log in to the DockerHub container registry
uses: docker/login-action@v2
with:
registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push image to DockerHub
uses: docker/build-push-action@v6
id: dh-push
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
tags: ${{ steps.dh-meta.outputs.tags }}
labels: ${{ steps.dh-meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate and push artifact attestation to DockerHub
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.dh-push.outputs.digest }}
push-to-registry: true

View File

@ -18,64 +18,64 @@ concurrency:
cancel-in-progress: true
jobs:
build_darwin-x64:
name: Build macOS x86_64
runs-on: ubuntu-latest
make-electron:
name: Make Electron
strategy:
fail-fast: false
matrix:
arch: [x64, arm64]
os:
- name: macos
image: macos-latest
extension: dmg
- name: linux
image: ubuntu-latest
extension: deb
- name: windows
image: windows-latest
extension: exe
runs-on: ${{ matrix.os.image }}
steps:
- uses: actions/checkout@v4
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: |
npm run update-build-info
./bin/build-mac-x64.sh
- uses: actions/upload-artifact@v4
- name: Set up Python for appdmg to be installed
if: ${{ matrix.os.name == 'macos' }}
run: brew install python-setuptools
- name: Install dependencies
run: npm ci
- name: Update build info
run: npm run update-build-info
- name: Run electron-forge
run: npm run make-electron -- --arch=${{ matrix.arch }}
- name: Prepare artifacts (Unix)
if: runner.os != 'windows'
run: |
mkdir -p upload
file=$(find out/make -name '*.zip' -print -quit)
cp "$file" "upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-${{ github.ref_name }}.zip"
file=$(find out/make -name '*.${{ matrix.os.extension }}' -print -quit)
cp "$file" "upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-${{ github.ref_name }}.${{ matrix.os.extension }}"
- name: Prepare artifacts (Windows)
if: runner.os == 'windows'
run: |
mkdir upload
$file = Get-ChildItem -Path out/make -Filter '*.zip' -Recurse | Select-Object -First 1
Copy-Item -Path $file.FullName -Destination "upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-${{ github.ref_name }}.zip"
$file = Get-ChildItem -Path out/make -Filter '*.${{ matrix.os.extension }}' -Recurse | Select-Object -First 1
Copy-Item -Path $file.FullName -Destination "upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-${{ github.ref_name }}.${{ matrix.os.extension }}"
- name: Publish artifacts
uses: actions/upload-artifact@v4
with:
name: trilium-mac-x64.zip
path: dist/trilium-mac-x64*.zip
build_darwin-arm64:
name: Build macOS aarch64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up node & dependencies
uses: actions/setup-node@v4
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.zip
path: upload/*.zip
- name: Publish installer artifacts
uses: actions/upload-artifact@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: |
npm run update-build-info
./bin/build-mac-arm64.sh
- uses: actions/upload-artifact@v4
with:
name: trilium-mac-arm64.zip
path: dist/trilium-mac-arm64*.zip
build_linux-x64:
name: Build Linux x86_64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: |
npm run update-build-info
./bin/build-linux-x64.sh
- uses: actions/upload-artifact@v4
with:
name: trilium-linux-x64.tar.xz
path: dist/trilium-linux-x64-*.tar.xz
- uses: actions/upload-artifact@v4
with:
name: trilium_amd64.deb
path: dist/trilium_*.deb
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.${{matrix.os.extension}}
path: upload/*.${{ matrix.os.extension }}
build_linux_server-x64:
name: Build Linux Server x86_64
runs-on: ubuntu-latest
@ -86,56 +86,19 @@ jobs:
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: |
- name: Install dependencies
run: npm ci
- name: Run Linux server build (x86_64)
run: |
npm run update-build-info
./bin/build-server.sh
- name: Prepare artifacts
if: runner.os != 'windows'
run: |
mkdir -p upload
file=$(find dist -name '*.tar.xz' -print -quit)
cp "$file" "upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz"
- uses: actions/upload-artifact@v4
with:
name: trilium-linux-x64-server.tar.xz
path: dist/trilium-linux-x64-server-*.tar.xz
build_windows-x64:
name: Build Windows x86_64
runs-on: ubuntu-latest
steps:
- name: Set up Wine
run: |
sudo dpkg --add-architecture i386
wget -qO - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add -
sudo add-apt-repository ppa:cybermax-dexter/sdl2-backport
sudo apt-add-repository "deb https://dl.winehq.org/wine-builds/ubuntu $(lsb_release -cs) main"
sudo apt install --install-recommends winehq-stable
- uses: actions/checkout@v4
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: |
npm run update-build-info
./bin/build-win-x64.sh DONTPACK
- uses: actions/upload-artifact@v4
with:
name: trilium-windows-x64
path: dist/trilium-windows-x64
build_windows-installer:
name: Build Windows x86_64 (Setup)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- name: Run installer build
run: |
npm run update-build-info
npm run make-electron
- name: Publish installer artifact
uses: actions/upload-artifact@v4
with:
name: TriliumNext Notes for Windows (Setup)
path: out/make/squirrel.windows/x64/*.exe
name: TriliumNextNotes linux server x64
path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz

7
.gitignore vendored
View File

@ -5,7 +5,14 @@ build/
src/public/app-dist/
npm-debug.log
yarn-error.log
*.db
!integration-tests/db/document.db
integration-tests/db/log
integration-tests/db/sessions
integration-tests/db/backup
integration-tests/db/session_secret.txt
config.ini
cert.key
cert.crt

View File

@ -11,4 +11,7 @@
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
}

View File

@ -20,22 +20,16 @@ WORKDIR /usr/src/app
# Bundle app source
COPY . .
COPY server-package.json package.json
# Copy TypeScript build artifacts into the original directory structure.
RUN ls
RUN cp -R build/src/* src/.
# Copy the healthcheck
RUN cp build/docker_healthcheck.js .
RUN rm docker_healthcheck.ts
RUN rm -r build
RUN cp -R build/src/* src/. && \
cp build/docker_healthcheck.js . && \
rm -r build && \
rm docker_healthcheck.ts
# Install app dependencies
RUN set -x
RUN npm install
RUN apt-get purge -y --auto-remove \
autoconf \
automake \
@ -47,12 +41,12 @@ RUN apt-get purge -y --auto-remove \
libpng-dev \
python3 \
&& rm -rf /var/lib/apt/lists/*
RUN npm run webpack
RUN npm prune --omit=dev
RUN cp src/public/app/share.js src/public/app-dist/.
RUN cp -r src/public/app/doc_notes src/public/app-dist/.
RUN rm -rf src/public/app
RUN rm src/services/asset_path.ts
RUN npm install && \
npm run webpack && \
npm prune --omit=dev
RUN cp src/public/app/share.js src/public/app-dist/. && \
cp -r src/public/app/doc_notes src/public/app-dist/. && \
rm -rf src/public/app && rm src/services/asset_path.ts
# Some setup tools need to be kept
RUN apt-get update && apt-get install -y --no-install-recommends \

View File

@ -1,38 +0,0 @@
#!/usr/bin/env bash
ELECTRON_VERSION="electron-v125"
NODE_VERSION="node-v115"
if ! command -v jq &> /dev/null; then
echo "Missing command: jq"
exit 1
fi
script_dir=$(realpath $(dirname $0))
cd "$script_dir"
BETTER_SQLITE3_VERSION=$(jq -r '.dependencies.["better-sqlite3"]' ../../package.json | grep -oP "\d+\.\d+\.\d+")
if [ -z $BETTER_SQLITE3_VERSION ]; then
echo "Unable to determine better-sqlite3 version."
exit 2
fi
echo "Version: $BETTER_SQLITE3_VERSION"
function download() {
version="$1"
platform="$2"
dest_name="$3"
url=https://github.com/WiseLibs/better-sqlite3/releases/download/v${BETTER_SQLITE3_VERSION}/better-sqlite3-v${BETTER_SQLITE3_VERSION}-${version}-${platform}.tar.gz
temp_file="temp.tar.gz"
curl -L "$url" -o "$temp_file"
tar -xzvf "$temp_file"
mv build/Release/better_sqlite3.node "$dest_name-better_sqlite3.node"
rm -rf build
rm -f "$temp_file"
}
download $NODE_VERSION "linux-x64" "linux-server"
download $ELECTRON_VERSION "linux-x64" "linux-desktop"
download $ELECTRON_VERSION "win32-x64" "win"
download $ELECTRON_VERSION "darwin-x64" "mac-x64"
download $ELECTRON_VERSION "darwin-arm64" "mac-arm64"

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
set -e # Fail on any command error
if ! command -v dpkg-deb &> /dev/null; then
echo "Missing command: dpkg-deb"
exit 1
fi
if dpkg-deb 2>&1 | grep BusyBox &> /dev/null; then
echo "The dpkg-deb binary provided by BusyBox is not compatible. The Debian tool needs to be used instead."
exit 1
fi
echo "Packaging debian x64 distribution..."
VERSION=`jq -r ".version" package.json`
./node_modules/.bin/electron-installer-debian --config bin/deb-options.json --options.version=${VERSION} --arch amd64

View File

@ -1,58 +0,0 @@
#!/usr/bin/env bash
set -e # Fail on any command error
if ! command -v jq &> /dev/null; then
echo "Missing command: jq"
exit 1
fi
if ! command -v fakeroot &> /dev/null; then
echo "Missing command: fakeroot"
exit 1
fi
if ! command -v dpkg-deb &> /dev/null; then
echo "Missing command: dpkg-deb"
exit 1
fi
if dpkg-deb 2>&1 | grep BusyBox &> /dev/null; then
echo "The dpkg-deb binary provided by BusyBox is not compatible. The Debian tool needs to be used instead."
exit 1
fi
SRC_DIR=./dist/trilium-linux-x64-src
[ "$1" != "DONTCOPY" ] && ./bin/copy-trilium.sh "$SRC_DIR"
echo "Copying required linux-x64 binaries"
cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node "$SRC_DIR"/node_modules/better-sqlite3/build/Release/better_sqlite3.node
echo "Packaging linux x64 electron build"
./node_modules/.bin/electron-packager "$SRC_DIR" --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
BUILD_DIR=./dist/trilium-linux-x64
rm -rf "$BUILD_DIR"
mv "./dist/TriliumNext Notes-linux-x64" "$BUILD_DIR"
cp images/app-icons/png/128x128.png "$BUILD_DIR"/icon.png
cp bin/tpl/anonymize-database.sql "$BUILD_DIR"/
cp -r dump-db "$BUILD_DIR"/
rm -rf "$BUILD_DIR"/dump-db/node_modules
for f in 'trilium-portable' 'trilium-safe-mode' 'trilium-no-cert-check'; do
cp bin/tpl/"$f".sh "$BUILD_DIR"/
chmod 755 "$BUILD_DIR"/"$f".sh
done
echo "Packaging linux x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
pushd dist
tar cJf "trilium-linux-x64-${VERSION}.tar.xz" trilium-linux-x64
popd
bin/build-debian.sh

View File

@ -1,37 +0,0 @@
#!/usr/bin/env bash
set -e # Fail on any command error
SRC_DIR=./dist/trilium-mac-arm64-src
if [ "$1" != "DONTCOPY" ]
then
./bin/copy-trilium.sh $SRC_DIR
fi
echo "Copying required mac arm64 binaries"
cp -r bin/better-sqlite3/mac-arm64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
echo "Packaging mac arm64 electron build"
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=arm64 --overwrite --icon=images/app-icons/mac/icon.icns
BUILD_DIR=./dist/trilium-mac-arm64
rm -rf $BUILD_DIR
# Mac build has by default useless directory level
mv "./dist/TriliumNext Notes-darwin-arm64" $BUILD_DIR
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db $BUILD_DIR/
rm -rf $BUILD_DIR/dump-db/node_modules
echo "Zipping mac arm64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
zip -r9 --symlinks trilium-mac-arm64-${VERSION}.zip trilium-mac-arm64

View File

@ -1,37 +0,0 @@
#!/usr/bin/env bash
set -e # Fail on any command error
SRC_DIR=./dist/trilium-mac-x64-src
if [ "$1" != "DONTCOPY" ]
then
./bin/copy-trilium.sh $SRC_DIR
fi
echo "Copying required mac x64 binaries"
cp -r bin/better-sqlite3/mac-x64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
echo "Packaging mac x64 electron build"
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=x64 --overwrite --icon=images/app-icons/mac/icon.icns
BUILD_DIR=./dist/trilium-mac-x64
rm -rf $BUILD_DIR
# Mac build has by default useless directory level
mv "./dist/TriliumNext Notes-darwin-x64" $BUILD_DIR
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db $BUILD_DIR/
rm -rf $BUILD_DIR/dump-db/node_modules
echo "Zipping mac x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
zip -r9 --symlinks trilium-mac-x64-${VERSION}.zip trilium-mac-x64

View File

@ -24,8 +24,6 @@ rm -r $PKG_DIR/node/include/node
rm -r $PKG_DIR/node_modules/electron*
rm -r $PKG_DIR/electron.js
cp -r bin/better-sqlite3/linux-server-better_sqlite3.node $PKG_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
printf "#!/bin/sh\n./node/bin/node src/www" > $PKG_DIR/trilium.sh
chmod 755 $PKG_DIR/trilium.sh

View File

@ -1,44 +0,0 @@
#!/usr/bin/env bash
set -e # Fail on any command error
if ! command -v wine &> /dev/null; then
echo "Missing command: wine"
exit 1
fi
SRC_DIR=./dist/trilium-windows-x64-src
if [ "$1" != "DONTCOPY" ]
then
./bin/copy-trilium.sh $SRC_DIR
fi
echo "Copying required windows binaries"
cp -r bin/better-sqlite3/win-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node
echo "Packaging windows x64 electron build"
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=images/app-icons/win/icon.ico
BUILD_DIR=./dist/trilium-windows-x64
rm -rf $BUILD_DIR
mv "./dist/TriliumNext Notes-win32-x64" $BUILD_DIR
cp bin/tpl/anonymize-database.sql $BUILD_DIR/
cp -r dump-db $BUILD_DIR/
rm -rf $BUILD_DIR/dump-db/node_modules
cp bin/tpl/trilium-{portable,no-cert-check,safe-mode}.bat $BUILD_DIR/
if [ "$1" != "DONTPACK" ]
then
echo "Zipping windows x64 electron distribution..."
VERSION=`jq -r ".version" package.json`
cd dist
zip -r9 trilium-windows-x64-${VERSION}.zip trilium-windows-x64
fi

View File

@ -52,7 +52,6 @@ if [[ -d "$DIR"/node_modules ]]; then
'@excalidraw/excalidraw/dist/excalidraw-assets-dev' '@excalidraw/excalidraw/dist/excalidraw.development.js' '@excalidraw/excalidraw/dist/excalidraw-with-preact.development.js' \
'mermaid/dist/mermaid.js' \
'boxicons/svg' 'boxicons/node_modules/react'/* \
'better-sqlite3/Release' 'better-sqlite3/deps/sqlite3.tar.gz' 'better-sqlite3/deps/sqlite3' \
'@jimp/plugin-print/fonts' 'jimp/browser' 'jimp/fonts'; do
[[ -e "$DIR"/node_modules/"$d" ]] && rm -r "$DIR"/node_modules/"$d"
done

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
const anonymizationService = require('../src/services/anonymization');
const fs = require('fs');
const path = require('path');
import anonymizationService from '../src/services/anonymization.js';
import fs from 'fs';
import path from 'path';
fs.writeFileSync(path.resolve(__dirname, 'tpl', 'anonymize-database.sql'), anonymizationService.getFullAnonymizationScript());

View File

@ -39,7 +39,7 @@ done
icnsutil compose -f "mac/icon.icns" ./mac/*.png
# Build Windows icon
magick -background none "../icon-color.svg" -define icon:auto-resize=16,32,48,64,128,256 "./win/icon.ico"
magick -background none "../icon-color.svg" -define icon:auto-resize=16,32,48,64,128,256 "./icon.ico"
# Build Squirrel splash image
magick "./png/256x256.png" -background "#ffffff" -gravity center -extent 640x480 "./win/setup-banner.gif"

View File

@ -14,10 +14,10 @@ npm install
## Running
See output of `node dump-db.js --help`:
See output of `npx esrun dump.ts --help`:
```
dump-db.js <path_to_document> <target_directory>
dump-db.ts <path_to_document> <target_directory>
dump the contents of document.db into the target directory

View File

@ -1,14 +1,14 @@
#!/usr/bin/env node
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const dumpService = require('./inc/dump.js');
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import dumpService from './inc/dump.js';
yargs(hideBin(process.argv))
.command('$0 <path_to_document> <target_directory>', 'dump the contents of document.db into the target directory', (yargs) => {
return yargs
.positional('path_to_document', { describe: 'path to the document.db' })
.positional('target_directory', { describe: 'path of the directory into which the notes should be dumped' })
.option('path_to_document', { alias: 'p', describe: 'path to the document.db', type: 'string', demandOption: true })
.option('target_directory', { alias: 't', describe: 'path of the directory into which the notes should be dumped', type: 'string', demandOption: true });
}, (argv) => {
try {
dumpService.dumpDocument(argv.path_to_document, argv.target_directory, {

View File

@ -1,8 +1,8 @@
const crypto = require("crypto");
const sql = require('./sql');
const decryptService = require('./decrypt.js');
import crypto from 'crypto';
import sql from './sql.js';
import decryptService from './decrypt.js';
function getDataKey(password) {
function getDataKey(password: any) {
if (!password) {
return null;
}
@ -16,28 +16,28 @@ function getDataKey(password) {
return decryptedDataKey;
}
catch (e) {
catch (e: any) {
throw new Error(`Cannot read data key, the entered password might be wrong. The underlying error: '${e.message}', stack:\n${e.stack}`);
}
}
function getPasswordDerivedKey(password) {
function getPasswordDerivedKey(password: any) {
const salt = getOption('passwordDerivedKeySalt');
return getScryptHash(password, salt);
}
function getScryptHash(password, salt) {
function getScryptHash(password: any, salt: any) {
const hashed = crypto.scryptSync(password, salt, 32,
{N: 16384, r:8, p:1});
{ N: 16384, r: 8, p: 1 });
return hashed;
}
function getOption(name) {
function getOption(name: string) {
return sql.getValue("SELECT value FROM options WHERE name = ?", [name]);
}
module.exports = {
export default {
getDataKey
};

View File

@ -1,6 +1,6 @@
const crypto = require("crypto");
import crypto from 'crypto';
function decryptString(dataKey, cipherText) {
function decryptString(dataKey: any, cipherText: any) {
const buffer = decrypt(dataKey, cipherText);
if (buffer === null) {
@ -16,7 +16,7 @@ function decryptString(dataKey, cipherText) {
return str;
}
function decrypt(key, cipherText, ivLength = 13) {
function decrypt(key: any, cipherText: any, ivLength = 13) {
if (cipherText === null) {
return null;
}
@ -46,11 +46,10 @@ function decrypt(key, cipherText, ivLength = 13) {
return payload;
}
catch (e) {
catch (e: any) {
// recovery from https://github.com/zadam/trilium/issues/510
if (e.message?.includes("WRONG_FINAL_BLOCK_LENGTH") || e.message?.includes("wrong final block length")) {
log.info("Caught WRONG_FINAL_BLOCK_LENGTH, returning cipherText instead");
console.log("Caught WRONG_FINAL_BLOCK_LENGTH, returning cipherText instead");
return cipherText;
}
else {
@ -59,7 +58,7 @@ function decrypt(key, cipherText, ivLength = 13) {
}
}
function pad(data) {
function pad(data: any) {
if (data.length > 16) {
data = data.slice(0, 16);
}
@ -72,7 +71,7 @@ function pad(data) {
return Buffer.from(data);
}
function arraysIdentical(a, b) {
function arraysIdentical(a: any, b: any) {
let i = a.length;
if (i !== b.length) return false;
while (i--) {
@ -81,12 +80,12 @@ function arraysIdentical(a, b) {
return true;
}
function shaArray(content) {
function shaArray(content: any) {
// we use this as simple checksum and don't rely on its security so SHA-1 is good enough
return crypto.createHash('sha1').update(content).digest();
}
module.exports = {
export default {
decrypt,
decryptString
};

View File

@ -1,11 +1,11 @@
const fs = require("fs");
const sanitize = require("sanitize-filename");
const sql = require('./sql.js');
const decryptService = require('./decrypt.js');
const dataKeyService = require('./data_key.js');
const extensionService = require('./extension.js');
import fs from 'fs';
import sanitize from 'sanitize-filename';
import sql from './sql.js';
import decryptService from './decrypt.js';
import dataKeyService from './data_key.js';
import extensionService from './extension.js';
function dumpDocument(documentPath, targetPath, options) {
function dumpDocument(documentPath: string, targetPath: string, options: { password: any; includeDeleted: any; }) {
const stats = {
succeeded: 0,
failed: 0,
@ -19,14 +19,14 @@ function dumpDocument(documentPath, targetPath, options) {
const dataKey = dataKeyService.getDataKey(options.password);
const existingPaths = {};
const noteIdToPath = {};
const existingPaths: Record<string, any> = {};
const noteIdToPath: Record<string, any> = {};
dumpNote(targetPath, 'root');
printDumpResults(stats, options);
function dumpNote(targetPath, noteId) {
function dumpNote(targetPath: any, noteId: any) {
console.log(`Reading note '${noteId}'`);
let childTargetPath, noteRow, fileNameWithPath;
@ -94,7 +94,7 @@ function dumpDocument(documentPath, targetPath, options) {
noteIdToPath[noteId] = childTargetPath;
}
catch (e) {
catch (e: any) {
console.error(`DUMPERROR: Writing '${noteId}' failed with error '${e.message}':\n${e.stack}`);
stats.failed++;
@ -108,9 +108,9 @@ function dumpDocument(documentPath, targetPath, options) {
}
try {
fs.mkdirSync(childTargetPath, { recursive: true });
fs.mkdirSync(childTargetPath as string, { recursive: true });
}
catch (e) {
catch (e: any) {
console.error(`DUMPERROR: Creating directory ${childTargetPath} failed with error '${e.message}'`);
}
@ -121,7 +121,7 @@ function dumpDocument(documentPath, targetPath, options) {
}
}
function printDumpResults(stats, options) {
function printDumpResults(stats: any, options: any) {
console.log('\n----------------------- STATS -----------------------');
console.log('Successfully dumpted notes: ', stats.succeeded.toString().padStart(5, ' '));
console.log('Protected notes: ', stats.protected.toString().padStart(5, ' '), options.password ? '' : '(skipped)');
@ -134,7 +134,7 @@ function printDumpResults(stats, options) {
}
}
function isContentEmpty(content) {
function isContentEmpty(content: any) {
if (!content) {
return true;
}
@ -150,7 +150,7 @@ function isContentEmpty(content) {
}
}
function validatePaths(documentPath, targetPath) {
function validatePaths(documentPath: string, targetPath: string) {
if (!fs.existsSync(documentPath)) {
console.error(`Path to document '${documentPath}' has not been found. Run with --help to see usage.`);
process.exit(1);
@ -166,6 +166,6 @@ function validatePaths(documentPath, targetPath) {
}
}
module.exports = {
export default {
dumpDocument
};

View File

@ -1,7 +1,7 @@
const path = require("path");
const mimeTypes = require("mime-types");
import path from "path";
import mimeTypes from "mime-types";
function getFileName(note, childTargetPath, safeTitle) {
function getFileName(note: any, childTargetPath: string, safeTitle: string) {
let existingExtension = path.extname(safeTitle).toLowerCase();
let newExtension;
@ -29,6 +29,6 @@ function getFileName(note, childTargetPath, safeTitle) {
return fileNameWithPath;
}
module.exports = {
export default {
getFileName
};

View File

@ -1,17 +0,0 @@
const Database = require("better-sqlite3");
let dbConnection;
const openDatabase = (documentPath) => { dbConnection = new Database(documentPath, { readonly: true }) };
const getRow = (query, params = []) => dbConnection.prepare(query).get(params);
const getRows = (query, params = []) => dbConnection.prepare(query).all(params);
const getValue = (query, params = []) => dbConnection.prepare(query).pluck().get(params);
const getColumn = (query, params = []) => dbConnection.prepare(query).pluck().all(params);
module.exports = {
openDatabase,
getRow,
getRows,
getValue,
getColumn
};

18
dump-db/inc/sql.ts Normal file
View File

@ -0,0 +1,18 @@
import Database, { Database as DatabaseType } from "better-sqlite3";
let dbConnection: DatabaseType;
const openDatabase = (documentPath: string) => { dbConnection = new Database(documentPath, { readonly: true }) };
const getRow = (query: string, params: string[] = []): Record<string, any> => dbConnection.prepare(query).get(params) as Record<string, any>;
const getRows = (query: string, params = []) => dbConnection.prepare(query).all(params);
const getValue = (query: string, params: string[] = []) => dbConnection.prepare(query).pluck().get(params);
const getColumn = (query: string, params: string[] = []) => dbConnection.prepare(query).pluck().all(params);
export default {
openDatabase,
getRow,
getRows,
getValue,
getColumn
};

1513
dump-db/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,24 +2,30 @@
"name": "dump-db",
"version": "1.0.0",
"description": "Standalone tool to dump contents of Trilium document.db file into a directory tree of notes",
"main": "dump-db.js",
"main": "dump-db.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zadam/trilium.git"
"url": "git+https://github.com/TriliumNext/Notes.git"
},
"author": "zadam",
"author": "TriliumNext",
"license": "ISC",
"bugs": {
"url": "https://github.com/zadam/trilium/issues"
"url": "https://github.com/TriliumNext/Notes/issues"
},
"homepage": "https://github.com/zadam/trilium/dump-db#readme",
"homepage": "https://github.com/TriliumNext/Notes/blob/master/dump-db/README.md",
"dependencies": {
"better-sqlite3": "7.5.0",
"mime-types": "2.1.34",
"sanitize-filename": "1.6.3",
"yargs": "17.3.1"
"better-sqlite3": "^11.1.2",
"esrun": "^3.2.26",
"mime-types": "^2.1.34",
"sanitize-filename": "^1.6.3",
"yargs": "^17.3.1"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.11",
"@types/mime-types": "^2.1.4",
"@types/yargs": "^17.0.33"
}
}

10
dump-db/tsconfig.json Normal file
View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "ES6",
"strict": true
}
}

View File

@ -1,18 +1,66 @@
const path = require('path');
const fs = require('fs-extra');
module.exports = {
packagerConfig: {
executableName: "trilium",
name: 'TriliumNext Notes',
overwrite: true,
asar: true,
// icon will break once we add .dmg support, since the .ico & .icns have to be in same dir (see https://www.electronforge.io/guides/create-and-add-icons#windows-and-macos)
icon: "./images/app-icons/win/icon"
icon: "./images/app-icons/icon",
extraResource: getExtraResourcesForPlatform(),
afterComplete: [(buildPath, electronVersion, platform, arch, callback) => {
const extraResources = getExtraResourcesForPlatform();
for (const resource of extraResources) {
let sourcePath;
if (platform === 'darwin') {
sourcePath = path.join(buildPath, 'TriliumNextNotes.app', 'Contents', 'Resources', path.basename(resource));
} else {
sourcePath = path.join(buildPath, 'resources', path.basename(resource));
}
const destPath = path.join(buildPath, path.basename(resource));
// Copy files from resources folder to root
fs.move(sourcePath, destPath)
.then(() => callback())
.catch(err => callback(err));
}
}]
},
rebuildConfig: {
force: true
},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-deb',
config: {
options: {
icon: "./images/app-icons/png/128x128.png",
}
}
},
{
name: '@electron-forge/maker-squirrel',
config: {
iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/win/icon.ico",
setupIcon: "./images/app-icons/win/icon.ico",
iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/icon.ico",
setupIcon: "./images/app-icons/icon.ico",
loadingGif: "./images/app-icons/win/setup-banner.gif"
}
},
{
name: '@electron-forge/maker-dmg',
config: {
icon: "./images/app-icons/icon.icns",
}
},
{
name: '@electron-forge/maker-zip',
config: {
options: {
iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/icon.ico",
icon: "./images/app-icons/icon.ico",
}
}
}
],
plugins: [
@ -22,3 +70,27 @@ module.exports = {
},
],
};
function getExtraResourcesForPlatform() {
let resources = ['dump-db/', './bin/tpl/anonymize-database.sql']
const scripts = ['trilium-portable', 'trilium-safe-mode', 'trilium-no-cert-check']
switch (process.platform) {
case 'win32':
for (const script of scripts) {
resources.push(`./bin/tpl/${script}.bat`)
}
break;
case 'darwin':
break;
case 'linux':
for (const script of scripts) {
resources.push(`./bin/tpl/${script}.sh`)
}
break;
default:
break;
}
return resources;
}

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -2,8 +2,8 @@ import { test as setup, expect } from '@playwright/test';
const authFile = 'playwright/.auth/user.json';
const ROOT_URL = "http://localhost:8080";
const LOGIN_PASSWORD = "eliandoran";
const ROOT_URL = "http://localhost:8082";
const LOGIN_PASSWORD = "demo1234";
// Reference: https://playwright.dev/docs/auth#basic-shared-account-in-all-tests

Binary file not shown.

View File

@ -0,0 +1,9 @@
import { test, expect } from '@playwright/test';
test("Can duplicate note with broken links", async ({ page }) => {
await page.goto(`http://localhost:8082/#2VammGGdG6Ie`);
await page.locator('.tree-wrapper .fancytree-active').getByText('Note map').click({ button: 'right' });
await page.getByText('Duplicate subtree').click();
await expect(page.locator(".toast-body")).toBeHidden();
await expect(page.locator('.tree-wrapper').getByText('Note map (dup)')).toBeVisible();
});

View File

@ -0,0 +1,23 @@
import test, { expect } from "@playwright/test";
test('Help popup', async ({ page }) => {
await page.goto('http://localhost:8082');
await page.getByText('Trilium Integration Test DB').click();
await page.locator('body').press('F1');
await page.getByRole('link', { name: 'online↗' }).click();
expect((await page.waitForEvent('popup')).url()).toBe("https://triliumnext.github.io/Docs/")
});
test('Complete help in search', async ({ page }) => {
await page.goto('http://localhost:8082');
// Clear all tabs
await page.locator('.note-tab:first-of-type').locator("div").nth(1).click({ button: 'right' });
await page.getByText('Close all tabs').click();
await page.locator('#launcher-container').getByRole('button', { name: '' }).first().click();
await page.getByRole('cell', { name: ' ' }).locator('span').first().click();
await page.getByRole('button', { name: 'complete help on search syntax' }).click();
expect((await page.waitForEvent('popup')).url()).toBe("https://triliumnext.github.io/Docs/Wiki/search.html");
});

10
loader-register.js Normal file
View File

@ -0,0 +1,10 @@
// Used to register the loader with Node.js
// This is used to avoid the warning message when using the loader
// Can be removed if this PR is merged:
// https://github.com/TypeStrong/ts-node/pull/2073
// Then probably can change webpack comand to
// "webpack": "cross-env NODE_OPTIONS=--import=ts-node/esm webpack -c webpack.config.ts",
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';
register('ts-node/esm', pathToFileURL('./'));

2056
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"name": "trilium",
"productName": "TriliumNext Notes",
"description": "Build your personal knowledge base with TriliumNext Notes",
"version": "0.90.3",
"version": "0.90.4",
"license": "AGPL-3.0-only",
"main": "./dist/electron.js",
"author": {
@ -23,19 +23,17 @@
"start-server": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
"start-server-safe": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
"start-server-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
"qstart-server": "npm run qswitch-server && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 nodemon src/www.ts",
"start-electron": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts && cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron.js --inspect=5858 .",
"start-test-server": "npm run switch-server; rimraf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 ts-node src/www.ts",
"qstart-server": "npm run switch-server && npm run start-server",
"start-electron": "npm run prepare-dist && cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron.js --inspect=5858 .",
"start-electron-no-dir": "cross-env TRILIUM_SAFE_MODE=1 TRILIUM_ENV=dev TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 electron --inspect=5858 .",
"qstart-electron": "npm run qswitch-electron && TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron --inspect=5858 .",
"start-test-server": "npm run qswitch-server; rimraf ./data-test; cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 ts-node src/www.ts",
"qstart-electron": "npm run switch-electron && npm run start-electron",
"switch-server": "rimraf ./node_modules/better-sqlite3 && npm install",
"switch-electron": "npx electron-rebuild",
"qswitch-server": "rimraf ./node_modules/better-sqlite3/bin ; mkdir -p ./node_modules/better-sqlite3/build ; cp ./bin/better-sqlite3/linux-server-better_sqlite3.node ./node_modules/better-sqlite3/build/better_sqlite3.node",
"qswitch-electron": "rimraf ./node_modules/better-sqlite3/bin ; mkdir -p ./node_modules/better-sqlite3/build ; cp ./bin/better-sqlite3/linux-desktop-better_sqlite3.node ./node_modules/better-sqlite3/build/better_sqlite3.node",
"build-backend-docs": "rimraf ./docs/backend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/becca/entities/*.js src/services/backend_script_api.js src/services/sql.js",
"build-frontend-docs": "rimraf ./docs/frontend_api && ./node_modules/.bin/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",
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
"webpack": "cross-env NODE_OPTIONS=--loader=ts-node/esm webpack -c webpack.config.ts",
"webpack": "cross-env node --import ./loader-register.js node_modules/webpack/bin/webpack.js -c webpack.config.ts",
"test-jasmine": "cross-env TRILIUM_DATA_DIR=./data-test tsx ./node_modules/.bin/jasmine",
"test-es6": "tsx -r esm spec-es6/attribute_parser.spec.ts",
"test": "npm run test-jasmine && npm run test-es6",
@ -44,7 +42,10 @@
"package-electron": "electron-forge package",
"prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
"update-build-info": "tsx bin/update-build-info.ts",
"errors": "tsc --watch --noEmit"
"errors": "tsc --watch --noEmit",
"integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/www.ts",
"integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/www.ts",
"generate-document": "cross-env nodemon src/tools/generate_document.ts 1000"
},
"dependencies": {
"@braintree/sanitize-url": "^7.1.0",
@ -126,7 +127,10 @@
},
"devDependencies": {
"@electron-forge/cli": "^6.4.2",
"@electron-forge/maker-deb": "^7.4.0",
"@electron-forge/maker-dmg": "^7.4.0",
"@electron-forge/maker-squirrel": "^6.4.2",
"@electron-forge/maker-zip": "^7.4.0",
"@electron-forge/plugin-auto-unpack-natives": "^6.4.2",
"@playwright/test": "^1.46.0",
"@types/archiver": "^6.0.2",
@ -177,8 +181,5 @@
"typescript": "^5.3.3",
"webpack": "^5.93.0",
"webpack-cli": "5.1.4"
},
"optionalDependencies": {
"electron-installer-debian": "3.2.0"
}
}

View File

@ -48,7 +48,7 @@ app.use(express.static(path.join(scriptDir, 'public/root')));
app.use(`/manifest.webmanifest`, express.static(path.join(scriptDir, 'public/manifest.webmanifest')));
app.use(`/robots.txt`, express.static(path.join(scriptDir, 'public/robots.txt')));
app.use(sessionParser);
app.use(favicon(`${scriptDir}/../images/app-icons/win/icon.ico`));
app.use(favicon(`${scriptDir}/../images/app-icons/icon.ico`));
assets.register(app);
routes.register(app);

View File

@ -34,7 +34,7 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> {
isSynced?: boolean;
blobId?: string;
protected beforeSaving() {
protected beforeSaving(opts?: {}) {
const constructorData = (this.constructor as unknown as ConstructorData<T>);
if (!(this as any)[constructorData.primaryKeyName]) {
(this as any)[constructorData.primaryKeyName] = utils.newEntityId();
@ -101,7 +101,6 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> {
/**
* Saves entity - executes SQL, but doesn't commit the transaction on its own
*/
// TODO: opts not used but called a few times, maybe should be used by derived classes or passed to beforeSaving.
save(opts?: {}): this {
const constructorData = (this.constructor as unknown as ConstructorData<T>);
const entityName = constructorData.entityName;
@ -109,7 +108,7 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> {
const isNewEntity = !(this as any)[primaryKeyName];
this.beforeSaving();
this.beforeSaving(opts);
const pojo = this.getPojoToSave();

View File

@ -48,7 +48,7 @@ paths:
- name: search
in: query
required: true
description: search query string as described in https://github.com/TriliumNext/Docs/blob/main/Wiki/search.md
description: search query string as described in https://triliumnext.github.io/Docs/Wiki/search.html
schema:
type: string
examples:

View File

@ -249,7 +249,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/TriliumNext/Docs/blob/main/Wiki/search.md
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://triliumnext.github.io/Docs/Wiki/search.html
*
* @method
* @param {string} searchString
@ -261,7 +261,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/TriliumNext/Docs/blob/main/Wiki/search.md
* "#dateModified =* MONTH AND #log". See full documentation for all options at: https://triliumnext.github.io/Docs/Wiki/search.html
*
* @method
* @param {string} searchString
@ -558,7 +558,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
this.getYearNote = dateNotesService.getYearNote;
/**
* Hoist note in the current tab. See https://github.com/TriliumNext/Docs/blob/main/Wiki/note-hoisting.md
* Hoist note in the current tab. See https://triliumnext.github.io/Docs/Wiki/note-hoisting.html
*
* @method
* @param {string} noteId - set hoisted note. 'root' will effectively unhoist

View File

@ -27,7 +27,7 @@ function setupGlobs() {
window.glob.importMarkdownInline = async () => appContext.triggerCommand("importMarkdownInline");
window.glob.SEARCH_HELP_TEXT = `
<strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="search.md">complete help on search</button>
<strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="search.html">complete help on search</button>
<p>
<ul>
<li>Just enter any text for full text search</li>

View File

@ -330,7 +330,7 @@ function initHelpDropdown($el) {
initHelpButtons($dropdownMenu);
}
const wikiBaseUrl = "https://github.com/TriliumNext/Docs/blob/main/Wiki/";
const wikiBaseUrl = "https://triliumnext.github.io/Docs/Wiki/";
function openHelp($button) {
const helpPage = $button.attr("data-help-page");

View File

@ -11,7 +11,7 @@ const TPL = `
<div class="modal-header">
<h5 class="modal-title mr-auto">${t('add_link.add_link')}</h5>
<button type="button" class="help-button" title="${t('add_link.help_on_links')}" data-help-page="links.md">?</button>
<button type="button" class="help-button" title="${t('add_link.help_on_links')}" data-help-page="links.html">?</button>
<button type="button" class="close" data-dismiss="modal" aria-label="${t('add_link.close')}" style="margin-left: 0 !important;">
<span aria-hidden="true">&times;</span>

View File

@ -16,7 +16,7 @@ const TPL = `<div class="branch-prefix-dialog modal fade mx-auto" tabindex="-1"
<div class="modal-header">
<h5 class="modal-title mr-auto">${t('branch_prefix.edit_branch_prefix')}</h5>
<button class="help-button" type="button" data-help-page="tree-concepts.md#prefix" title="${t('branch_prefix.help_on_tree_prefix')}">?</button>
<button class="help-button" type="button" data-help-page="tree-concepts.html#prefix" title="${t('branch_prefix.help_on_tree_prefix')}">?</button>
<button type="button" class="close" data-dismiss="modal" aria-label="${t('branch_prefix.close')}" style="margin-left: 0;">
<span aria-hidden="true">&times;</span>

View File

@ -15,7 +15,7 @@ const TPL = `
<div class="modal-header">
<h5 class="modal-title mr-auto">${t('clone_to.clone_notes_to')}</h5>
<button type="button" class="help-button" title="${t('clone_to.help_on_links')}" data-help-page="cloning-notes.md">?</button>
<button type="button" class="help-button" title="${t('clone_to.help_on_links')}" data-help-page="cloning-notes.html">?</button>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;">
<span aria-hidden="true">&times;</span>

View File

@ -107,7 +107,7 @@ const TPL = `
<div class="card">
<div class="card-body">
<h5 class="card-title"><a class="external" href="https://github.com/TriliumNext/Docs/blob/main/Wiki/text-notes.md#markdown--autoformat">${t('help.markdownAutoformat')}</a></h5>
<h5 class="card-title"><a class="external" href="https://triliumnext.github.io/Docs/Wiki/text-notes.html#markdown--autoformat">${t('help.markdownAutoformat')}</a></h5>
<p class="card-text">
<ul>

View File

@ -10,7 +10,7 @@ const TPL = `
<div class="modal-header">
<h5 class="modal-title mr-auto">${t("protected_session_password.modal_title")}</h5>
<button class="help-button" type="button" data-help-page="protected-notes.md" title="${t("protected_session_password.help_title")}">?</button>
<button class="help-button" type="button" data-help-page="protected-notes.html" title="${t("protected_session_password.help_title")}">?</button>
<button type="button" class="close" data-dismiss="modal" aria-label="${t("protected_session_password.close_label")}" style="margin-left: 0;">
<span aria-hidden="true">&times;</span>

View File

@ -46,7 +46,7 @@ const TPL = `
title="${t("revisions.delete_all_revisions")}"
style="padding: 0 10px 0 10px;" type="button">${t("revisions.delete_all_button")}</button>
<button class="help-button" type="button" data-help-page="note-revisions.md" title="${t("revisions.help_title")}">?</button>
<button class="help-button" type="button" data-help-page="note-revisions.html" title="${t("revisions.help_title")}">?</button>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;">
<span aria-hidden="true">&times;</span>

View File

@ -15,7 +15,7 @@ const TPL = `
<div class="dropdown help-dropdown">
<span class="bx bx-help-circle icon-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu dropdown-menu-right p-4">
<strong>${t('search_string.search_syntax')}</strong> - ${t('search_string.also_see')} <button class="btn btn-sm" type="button" data-help-page="search.md">${t('search_string.complete_help')}</button>
<strong>${t('search_string.search_syntax')}</strong> - ${t('search_string.also_see')} <button class="btn btn-sm" type="button" data-help-page="search.html">${t('search_string.complete_help')}</button>
<p>
<ul>
<li>${t('search_string.full_text_search')}</li>

View File

@ -13,7 +13,7 @@ const TPL = `
}
</style>
<span class="shared-text"></span> <a class="shared-link external"></a>. For help visit <a href="https://github.com/TriliumNext/Docs/blob/main/Wiki/sharing.md">wiki</a>.
<span class="shared-text"></span> <a class="shared-link external"></a>. For help visit <a href="https://triliumnext.github.io/Docs/Wiki/sharing.html">wiki</a>.
</div>`;
export default class SharedInfoWidget extends NoteContextAwareWidget {

View File

@ -20,7 +20,7 @@ export default class SharedSwitchWidget extends SwitchWidget {
this.$switchOffName.text("Shared");
this.$switchOffButton.attr("title", "Unshare the note");
this.$helpButton.attr("data-help-page", "sharing.md").show();
this.$helpButton.attr("data-help-page", "sharing.html").show();
this.$helpButton.on('click', e => utils.openHelp($(e.target)));
}

View File

@ -48,7 +48,7 @@ export default class AttachmentDetailTypeWidget extends TypeWidget {
this.$wrapper.empty();
this.children = [];
const $helpButton = $('<button class="attachment-help-button" type="button" data-help-page="attachments.md" title="' + t('attachment_detail.open_help_page') + '"><span class="bx bx-help-circle"></span></button>');
const $helpButton = $('<button class="attachment-help-button" type="button" data-help-page="attachments.html" title="' + t('attachment_detail.open_help_page') + '"><span class="bx bx-help-circle"></span></button>');
utils.initHelpButtons($helpButton);
this.$linksWrapper.empty().append(

View File

@ -40,7 +40,7 @@ export default class AttachmentListTypeWidget extends TypeWidget {
}
async doRefresh(note) {
const $helpButton = $('<button class="attachment-help-button" type="button" data-help-page="attachments.md" title="' + t('attachment_list.open_help_page') + '"><span class="bx bx-help-circle"></span></button>');
const $helpButton = $('<button class="attachment-help-button" type="button" data-help-page="attachments.html" title="' + t('attachment_list.open_help_page') + '"><span class="bx bx-help-circle"></span></button>');
utils.initHelpButtons($helpButton);
const noteLink = await linkService.createLink(this.noteId); // do separately to avoid race condition between empty() and .append()

View File

@ -8,7 +8,7 @@ const TPL = `
<h4>ETAPI</h4>
<p>ETAPI is a REST API used to access Trilium instance programmatically, without UI. <br/>
See more details on <a href="https://github.com/TriliumNext/Docs/blob/main/Wiki/etapi.md">wiki</a> and <a onclick="window.open('etapi/etapi.openapi.yaml')" href="etapi/etapi.openapi.yaml">ETAPI OpenAPI spec</a>.</p>
See more details on <a href="https://triliumnext.github.io/Docs/Wiki/etapi.html">wiki</a> and <a onclick="window.open('etapi/etapi.openapi.yaml')" href="etapi/etapi.openapi.yaml">ETAPI OpenAPI spec</a>.</p>
<button type="button" class="create-etapi-token btn btn-sm">Create new ETAPI token</button>

View File

@ -37,7 +37,7 @@ const TPL = `
<h4>Protected Session Timeout</h4>
<p>Protected session timeout is a time period after which the protected session is wiped from
the browser's memory. This is measured from the last interaction with protected notes. See <a href="https://github.com/TriliumNext/Docs/blob/main/Wiki/protected-notes.md" class="external">wiki</a> for more info.</p>
the browser's memory. This is measured from the last interaction with protected notes. See <a href="https://triliumnext.github.io/Docs/Wiki/protected-notes.html" class="external">wiki</a> for more info.</p>
<div class="form-group">
<label>Protected session timeout (in seconds)</label>

View File

@ -28,7 +28,7 @@ const TPL = `
<div style="display: flex; justify-content: space-between;">
<button class="btn btn-primary">Save</button>
<button class="btn" type="button" data-help-page="synchronization.md">Help</button>
<button class="btn" type="button" data-help-page="synchronization.html">Help</button>
</div>
</form>
</div>

View File

@ -98,14 +98,14 @@
"export_finished_successfully": "Export finished successfully."
},
"help": {
"fullDocumentation": "Help (full documentation is available <a class=\"external\" href=\"https://github.com/zadam/trilium/wiki\">online</a>)",
"fullDocumentation": "Help (full documentation is available <a class=\"external\" href=\"https://triliumnext.github.io/Docs/\">online</a>)",
"close": "Close",
"noteNavigation": "Note navigation",
"goUpDown": "go up/down in the list of notes",
"collapseExpand": "collapse/expand node",
"notSet": "not set",
"goBackForwards": "go back / forwards in the history",
"showJumpToNoteDialog": "show <a class=\"external\" href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/note-navigation.md#jump-to-note\">\"Jump to\" dialog</a>",
"showJumpToNoteDialog": "show <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">\"Jump to\" dialog</a>",
"scrollToActiveNote": "scroll to active note",
"jumpToParentNote": "jump to parent note",
"collapseWholeTree": "collapse whole note tree",
@ -120,14 +120,14 @@
"creatingNotes": "Creating notes",
"createNoteAfter": "create new note after the active note",
"createNoteInto": "create new sub-note into active note",
"editBranchPrefix": "edit <a class=\"external\" href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/tree-concepts.md#prefix\">prefix</a> of active note clone",
"editBranchPrefix": "edit <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">prefix</a> of active note clone",
"movingCloningNotes": "Moving / cloning notes",
"moveNoteUpDown": "move note up/down in the note list",
"moveNoteUpHierarchy": "move note up in the hierarchy",
"multiSelectNote": "multi-select note above/below",
"selectAllNotes": "select all notes in the current level",
"selectNote": "select note",
"copyNotes": "copy active note (or current selection) into clipboard (used for <a class=\"external\" href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/cloning-notes.md\">cloning</a>)",
"copyNotes": "copy active note (or current selection) into clipboard (used for <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/cloning-notes.html#cloning-notes\">cloning</a>)",
"cutNotes": "cut current (or current selection) note into clipboard (used for moving notes)",
"pasteNotes": "paste note(s) as sub-note into active note (which is either move or clone depending on whether it was copied or cut into clipboard)",
"deleteNotes": "delete note / sub-tree",
@ -341,8 +341,8 @@
"css_class": "value of this label is then added as CSS class to the node representing given note in the tree. This can be useful for advanced theming. Can be used in template notes.",
"icon_class": "value of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.",
"page_size": "number of items per page in note listing",
"custom_request_handler": "see <a href=\"javascript:\" data-help-page=\"Custom request handler\">Custom request handler</a>",
"custom_resource_provider": "see <a href=\"javascript:\" data-help-page=\"Custom request handler\">Custom request handler</a>",
"custom_request_handler": "see <a href=\"javascript:\" data-help-page=\"custom-request-handler.html\">Custom request handler</a>",
"custom_resource_provider": "see <a href=\"javascript:\" data-help-page=\"custom-request-handler.html\">Custom request handler</a>",
"widget": "marks this note as a custom widget which will be added to the Trilium component tree",
"workspace": "marks this note as a workspace which allows easy hoisting",
"workspace_icon_class": "defines box icon CSS class which will be used in tab when hoisted to this note",
@ -367,7 +367,7 @@
"share_index": "note with this this label will list all roots of shared notes",
"display_relations": "comma delimited names of relations which should be displayed. All other ones will be hidden.",
"hide_relations": "comma delimited names of relations which should be hidden. All other ones will be displayed.",
"title_template": "default title of notes created as children of this note. The value is evaluated as JavaScript string \n and thus can be enriched with dynamic content via the injected <code>now</code> and <code>parentNote</code> variables. Examples:\n \n <ul>\n <li><code>${parentNote.getLabelValue('authorName')}'s literary works</code></li>\n <li><code>Log for ${now.format('YYYY-MM-DD HH:mm:ss')}</code></li>\n </ul>\n \n See <a href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/default-note-title.md\">wiki with details</a>, API docs for <a href=\"https://zadam.github.io/trilium/backend_api/Note.html\">parentNote</a> and <a href=\"https://day.js.org/docs/en/display/format\">now</a> for details.",
"title_template": "default title of notes created as children of this note. The value is evaluated as JavaScript string \n and thus can be enriched with dynamic content via the injected <code>now</code> and <code>parentNote</code> variables. Examples:\n \n <ul>\n <li><code>${parentNote.getLabelValue('authorName')}'s literary works</code></li>\n <li><code>Log for ${now.format('YYYY-MM-DD HH:mm:ss')}</code></li>\n </ul>\n \n See <a href=\"https://triliumnext.github.io/Docs/Wiki/default-note-title.html\">wiki with details</a>, API docs for <a href=\"https://zadam.github.io/trilium/backend_api/Note.html\">parentNote</a> and <a href=\"https://day.js.org/docs/en/display/format\">now</a> for details.",
"template": "This note will appear in the selection of available template when creating new note",
"toc": "<code>#toc</code> or <code>#toc=show</code> will force the Table of Contents to be shown, <code>#toc=hide</code> will force hiding it. If the label doesn't exist, the global setting is observed",
"color": "defines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f",
@ -879,7 +879,7 @@
"no_attachments": "This note has no attachments."
},
"book": {
"no_children_help": "This note of type Book doesn't have any child notes so there's nothing to display. See <a href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/book-note.md\">wiki</a> for details."
"no_children_help": "This note of type Book doesn't have any child notes so there's nothing to display. See <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a> for details."
},
"editable_code": {
"placeholder": "Type the content of your code note here..."
@ -919,7 +919,7 @@
},
"render": {
"note_detail_render_help_1": "This help note is shown because this note of type Render HTML doesn't have required relation to function properly.",
"note_detail_render_help_2": "Render HTML note type is used for <a class=\"external\" href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/scripts.md\">scripting</a>. In short, you have a HTML code note (optionally with some JavaScript) and this note will render it. To make it work, you need to define a <a class=\"external\" href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/attributes.md\">relation</a> called \"renderNote\" pointing to the HTML note to render."
"note_detail_render_help_2": "Render HTML note type is used for <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/scripts.html\">scripting</a>. In short, you have a HTML code note (optionally with some JavaScript) and this note will render it. To make it work, you need to define a <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/attributes.html\">relation</a> called \"renderNote\" pointing to the HTML note to render."
},
"web_view": {
"web_view": "Web View",
@ -1066,7 +1066,7 @@
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "Note Revisions Snapshot Interval",
"note_revisions_snapshot_description": "Note revision snapshot time interval is time in seconds after which a new note revision will be created for the note. See <a href=\"https://github.com/TriliumNext/Docs/blob/main/Wiki/note-revisions.md\" class=\"external\">wiki</a> for more info.",
"note_revisions_snapshot_description": "Note revision snapshot time interval is time in seconds after which a new note revision will be created for the note. See <a href=\"https://triliumnext.github.io/Docs/Wiki/note-revisions.html\" class=\"external\">wiki</a> for more info.",
"snapshot_time_interval_label": "Note revision snapshot time interval (in seconds)"
},
"search_engine": {

View File

@ -114,13 +114,13 @@ interface Api {
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "#dateModified =* MONTH AND #log". See {@link https://github.com/TriliumNext/Docs/blob/main/Wiki/search.md} for full documentation for all options
* "#dateModified =* MONTH AND #log". See {@link https://triliumnext.github.io/Docs/Wiki/search.html} for full documentation for all options
*/
searchForNotes(query: string, searchParams: SearchParams): BNote[];
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
* "#dateModified =* MONTH AND #log". See {@link https://github.com/TriliumNext/Docs/blob/main/Wiki/search.md} for full documentation for all options
* "#dateModified =* MONTH AND #log". See {@link https://triliumnext.github.io/Docs/Wiki/search.html} for full documentation for all options
*/
searchForNote(query: string, searchParams: SearchParams): BNote | null;
@ -251,7 +251,7 @@ interface Api {
*/
sortNotes(parentNoteId: string, sortConfig: {
/** 'title', 'dateCreated', 'dateModified' or a label name
* See {@link https://github.com/TriliumNext/Docs/blob/main/Wiki/sorting.md} for details. */
* See {@link https://triliumnext.github.io/Docs/Wiki/sorting.html} for details. */
sortBy?: string;
reverse?: boolean;
foldersFirst?: boolean;
@ -371,7 +371,7 @@ interface Api {
* This object contains "at your risk" and "no BC guarantees" objects for advanced use cases.
*/
__private: {
/** provides access to the backend in-memory object graph, see {@link https://github.com/zadam/trilium/blob/master/src/becca/becca.js} */
/** provides access to the backend in-memory object graph, see {@link Becca} */
becca: Becca;
};
}

View File

@ -1,4 +1,4 @@
export default {
buildDate: "2024-08-06T17:40:58Z",
buildRevision: "712ef92f7ca6b12cf19a8aa81b9735fd5f08cce8"
buildDate: "2024-08-09T22:05:59Z",
buildRevision: "2a5c444eff3eb99389339716ea8bfc989be90ecd"
};

View File

@ -107,7 +107,7 @@ function getNewNoteTitle(parentNote: BNote) {
// - now
// - parentNote
title = eval(`\`${titleTemplate}\``);
title = (0, eval)(`\`${titleTemplate}\``);
} catch (e: any) {
log.error(`Title template of note '${parentNote.noteId}' failed with: ${e.message}`);
}
@ -817,7 +817,6 @@ function undeleteBranch(branchId: string, deleteId: string, taskContext: TaskCon
for (const attributeRow of attributeRows) {
// relation might point to a note which hasn't been undeleted yet and would thus throw up
// TODO: skipValidation is not used.
new BAttribute(attributeRow).save({skipValidation: true});
}
@ -997,8 +996,7 @@ function duplicateSubtreeInner(origNote: BNote, origBranch: BBranch, newParentNo
}
// the relation targets may not be created yet, the mapping is pre-generated
// TODO: This used to be `attr.save({skipValidation: true});`, but skipValidation is in beforeSaving.
attr.save();
attr.save({skipValidation: true});
}
for (const childBranch of origNote.getChildBranches()) {

View File

@ -99,7 +99,7 @@ function executeScript(script: string, params: ScriptParams, startNoteId: string
}
function execute(ctx: ScriptContext, script: string) {
return function () { return eval(`const apiContext = this;\r\n(${script}\r\n)()`); }.call(ctx);
return function () { return (0, eval)(`const apiContext = this;\r\n(${script}\r\n)()`); }.call(ctx);
}
function getParams(params?: ScriptParams) {

View File

@ -14,8 +14,21 @@ import ws from "./ws.js";
import becca_loader from "../becca/becca_loader.js";
import entity_changes from "./entity_changes.js";
const dbConnection: DatabaseType = new Database(dataDir.DOCUMENT_PATH);
dbConnection.pragma('journal_mode = WAL');
function buildDatabase(path: string) {
if (process.env.TRILIUM_INTEGRATION_TEST === "memory") {
// This allows a database that is read normally but is kept in memory and discards all modifications.
const dbBuffer = fs.readFileSync(path);
return new Database(dbBuffer);
}
return new Database(dataDir.DOCUMENT_PATH);
}
const dbConnection: DatabaseType = buildDatabase(dataDir.DOCUMENT_PATH);
if (!process.env.TRILIUM_INTEGRATION_TEST) {
dbConnection.pragma('journal_mode = WAL');
}
const LOG_ALL_QUERIES = false;

View File

@ -3,13 +3,13 @@
* will create 1000 new notes and some clones into the current document.db
*/
require('../becca/entity_constructor');
const sqlInit = require('../services/sql_init');
const noteService = require('../services/notes');
const attributeService = require('../services/attributes');
const cls = require('../services/cls');
const cloningService = require('../services/cloning');
const loremIpsum = require('lorem-ipsum').loremIpsum;
import sqlInit from '../services/sql_init.js';
import noteService from '../services/notes.js';
import attributeService from '../services/attributes.js';
import cls from '../services/cls.js';
import cloningService from '../services/cloning.js';
import loremIpsum from 'lorem-ipsum';
import '../becca/entity_constructor.js';
const noteCount = parseInt(process.argv[2]);
@ -28,7 +28,7 @@ function getRandomNoteId() {
async function start() {
for (let i = 0; i < noteCount; i++) {
const title = loremIpsum({
const title = loremIpsum.loremIpsum({
count: 1,
units: 'sentences',
sentenceLowerBound: 1,
@ -36,7 +36,7 @@ async function start() {
});
const paragraphCount = Math.floor(Math.random() * Math.random() * 100);
const content = loremIpsum({
const content = loremIpsum.loremIpsum({
count: paragraphCount,
units: 'paragraphs',
sentenceLowerBound: 1,
@ -46,7 +46,7 @@ async function start() {
format: 'html'
});
const {note} = noteService.createNewNote({
const { note } = noteService.createNewNote({
parentNoteId: getRandomNoteId(),
title,
content,
@ -58,7 +58,7 @@ async function start() {
if (Math.random() < 0.04) {
const noteIdToClone = note.noteId;
const parentNoteId = getRandomNoteId();
const prefix = Math.random() > 0.8 ? "prefix" : null;
const prefix = Math.random() > 0.8 ? "prefix" : '';
const result = await cloningService.cloneNoteToBranch(noteIdToClone, parentNoteId, prefix);

View File

@ -14,7 +14,7 @@
},
"include": [
"./src/**/*.js",
"./src/**/*.ts",
"./src/**/*.ts",
"./*.ts",
"./spec/**/*.ts",
"./spec-es6/**/*.ts"