Compare commits

..

2 Commits

Author SHA1 Message Date
Elian Doran
5dc546605b Prepare for 0.91.3-beta 2025-01-16 23:05:53 +02:00
Elian Doran
62cda1bd24 Merge pull request #960 from pano9000/fix_csrf-csrf_existing_cookie
fix(csrf): fix handling of existing _csrf cookies
2025-01-16 21:54:11 +02:00
567 changed files with 6559 additions and 18686 deletions

View File

@@ -15,9 +15,3 @@ indent_size = 2
indent_style = space indent_style = space
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.yml]
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

3
.gitattributes vendored
View File

@@ -1,3 +1,2 @@
package-lock.json linguist-generated=true package-lock.json linguist-generated=true
**/package-lock.json linguist-generated=true **/package-lock.json linguist-generated=true
libraries/** linguist-vendored

View File

@@ -1,6 +1,7 @@
name: Bug Report name: Bug Report
description: Report a bug description: Report a bug
type: "Bug" title: "(Bug report) "
labels: "Type: Bug"
body: body:
- type: textarea - type: textarea
attributes: attributes:

View File

@@ -1,11 +1,12 @@
name: Feature Request name: Feature Request
description: Ask for a new feature to be added description: Ask for a new feature to be added
type: "Feature" title: "(Feature request) "
labels: "Type: Enhancement"
body: body:
- type: textarea - type: textarea
attributes: attributes:
label: Describe feature label: Describe feature
description: A clear and concise description of what you want to be added. description: A clear and concise description of what you want to be added..
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@@ -1,10 +0,0 @@
name: Task
description: Create a new Task
type: "Task"
body:
- type: textarea
attributes:
label: Describe Task
description: A clear and concise description of what the task is about.
validations:
required: true

View File

@@ -1,48 +0,0 @@
inputs:
os:
description: "One of the supported platforms: macos, linux, windows"
required: true
arch:
description: "The architecture to build for: x64, arm64"
required: true
extension:
description: "Platform specific extensions to copy in the output: dmg, deb, rpm, exe"
required: true
runs:
using: composite
steps:
- name: Set up Python for appdmg to be installed
if: ${{ inputs.os == 'macos' }}
shell: bash
run: brew install python-setuptools
- name: Install dependencies for RPM and Flatpak package building
if: ${{ inputs.os == 'linux' }}
shell: bash
run: |
sudo apt-get update && sudo apt-get install rpm flatpak-builder elfutils
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
FLATPAK_ARCH=$(if [[ ${{ inputs.arch }} = 'arm64' ]]; then echo 'aarch64'; else echo 'x86_64'; fi)
FLATPAK_VERSION='24.08'
flatpak install --user --no-deps --arch $FLATPAK_ARCH --assumeyes runtime/org.freedesktop.Platform/$FLATPAK_ARCH/$FLATPAK_VERSION runtime/org.freedesktop.Sdk/$FLATPAK_ARCH/$FLATPAK_VERSION org.electronjs.Electron2.BaseApp/$FLATPAK_ARCH/$FLATPAK_VERSION
- name: Install dependencies
shell: bash
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
shell: bash
run: npm run chore:update-build-info
- name: Run electron-forge
shell: bash
run: npm run electron-forge:make -- --arch=${{ inputs.arch }}
- name: Prepare artifacts
shell: bash
run: |
mkdir -p upload;
for ext in ${{ inputs.extension }};
do
file=$(find out/make -name "*.$ext" -print -quit);
cp "$file" "upload/TriliumNextNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}.$ext";
done

View File

@@ -1,31 +0,0 @@
inputs:
os:
description: "One of the supported platforms: windows"
required: true
arch:
description: "The architecture to build for: x64, arm64"
required: true
runs:
using: composite
steps:
- name: Set up node & dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
shell: bash
run: npm ci
- name: Run Linux server build
env:
MATRIX_ARCH: ${{ inputs.arch }}
shell: bash
run: |
npm run chore:update-build-info
./bin/build-server.sh
- name: Prepare artifacts
shell: bash
run: |
mkdir -p upload
file=$(find dist -name '*.tar.xz' -print -quit)
cp "$file" "upload/TriliumNextNotes-Server-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"

View File

@@ -33,7 +33,7 @@ jobs:
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set IMAGE_NAME to lowercase - name: Set IMAGE_NAME to lowercase
run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV
- name: Set TEST_TAG to lowercase - name: Set TEST_TAG to lowercase
@@ -47,16 +47,16 @@ jobs:
with: with:
node-version: 20 node-version: 20
cache: "npm" cache: "npm"
- name: Install npm dependencies - name: Install npm dependencies
run: npm ci run: npm ci
- name: Install Playwright Browsers - name: Install Playwright Browsers
run: npx playwright install --with-deps run: npx playwright install --with-deps
- name: Run the TypeScript build - name: Run the TypeScript build
run: npx tsc run: npx tsc
- name: Create server-package.json - name: Create server-package.json
run: cat package.json | grep -v electron > server-package.json run: cat package.json | grep -v electron > server-package.json
@@ -69,12 +69,12 @@ jobs:
tags: ${{ env.TEST_TAG }} tags: ${{ env.TEST_TAG }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
- name: Validate container run output - name: Validate container run output
run: | run: |
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --network=host -e TRILIUM_PORT=8082 --volume ./integration-tests/db:/home/node/trilium-data --name trilium_local ${{ env.TEST_TAG }}) CONTAINER_ID=$(docker run -d --log-driver=journald --rm --network=host -e TRILIUM_PORT=8082 --volume ./integration-tests/db:/home/node/trilium-data --name trilium_local ${{ env.TEST_TAG }})
echo "Container ID: $CONTAINER_ID" echo "Container ID: $CONTAINER_ID"
- name: Wait for the healthchecks to pass - name: Wait for the healthchecks to pass
uses: stringbean/docker-healthcheck-action@v3 uses: stringbean/docker-healthcheck-action@v3
with: with:
@@ -82,7 +82,7 @@ jobs:
wait-time: 50 wait-time: 50
require-status: running require-status: running
require-healthy: true require-healthy: true
- name: Run Playwright tests - name: Run Playwright tests
run: TRILIUM_DOCKER=1 npx playwright test run: TRILIUM_DOCKER=1 npx playwright test
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
@@ -100,20 +100,7 @@ jobs:
build: build:
name: Build Docker images name: Build Docker images
strategy: runs-on: ubuntu-latest
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:
@@ -121,6 +108,16 @@ 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: |
@@ -147,13 +144,13 @@ jobs:
type=sha type=sha
flavor: | flavor: |
latest=false latest=false
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Set up node & dependencies - name: Set up node & dependencies
uses: actions/setup-node@v4 uses: actions/setup-node@v4
@@ -172,14 +169,14 @@ jobs:
registry: ${{ env.GHCR_REGISTRY }} registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.DOCKERHUB_REGISTRY }} registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push by digest - name: Build and push by digest
id: build id: build
uses: docker/build-push-action@v6 uses: docker/build-push-action@v6
@@ -189,13 +186,13 @@ jobs:
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true outputs: type=image,name=${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest - name: Export digest
run: | run: |
mkdir -p /tmp/digests mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}" digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}" touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest - name: Upload digest
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
@@ -223,7 +220,7 @@ jobs:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
@@ -240,14 +237,14 @@ jobs:
registry: ${{ env.GHCR_REGISTRY }} registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.DOCKERHUB_REGISTRY }} registry: ${{ env.DOCKERHUB_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create manifest list and push - name: Create manifest list and push
working-directory: /tmp/digests working-directory: /tmp/digests
run: | run: |
@@ -258,7 +255,7 @@ jobs:
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \ -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) $(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \ -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \
$(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) $(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
@@ -270,25 +267,25 @@ jobs:
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \ -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) $(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \ -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \
$(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) $(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
# Small delay to ensure stable tag is fully propagated # Small delay to ensure stable tag is fully propagated
sleep 5 sleep 5
# Now update latest tags # Now update latest tags
docker buildx imagetools create \ docker buildx imagetools create \
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable
docker buildx imagetools create \ docker buildx imagetools create \
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable
fi fi
- name: Inspect image - name: Inspect image
run: | run: |
docker buildx imagetools inspect ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}

View File

@@ -7,7 +7,7 @@ on:
paths-ignore: paths-ignore:
- "docs/**" - "docs/**"
- ".github/workflows/main-docker.yml" - ".github/workflows/main-docker.yml"
workflow_dispatch: workflow_dispatch:
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@@ -23,13 +23,13 @@ jobs:
os: os:
- name: macos - name: macos
image: macos-latest image: macos-latest
extension: [dmg, zip] extension: dmg
- name: linux - name: linux
image: ubuntu-latest image: ubuntu-latest
extension: [deb, rpm, zip, flatpak] extension: deb
- name: windows - name: windows
image: windows-latest image: windows-latest
extension: [exe, zip] extension: exe
runs-on: ${{ matrix.os.image }} runs-on: ${{ matrix.os.image }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -37,12 +37,31 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
- name: Run the build - name: Set up Python for appdmg to be installed
uses: ./.github/actions/build-electron if: ${{ matrix.os.name == 'macos' }}
with: run: brew install python-setuptools
os: ${{ matrix.os.name }} - name: Install dependencies
arch: ${{ matrix.arch }} run: npm ci
extension: ${{ matrix.os.extension }} - 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 - name: Publish artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
@@ -53,26 +72,29 @@ jobs:
with: with:
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.${{matrix.os.extension}} name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.${{matrix.os.extension}}
path: upload/*.${{ matrix.os.extension }} path: upload/*.${{ matrix.os.extension }}
build_linux_server-x64:
build_linux_server: name: Build Linux Server x86_64
name: Build Linux Server runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [x64, arm64]
include:
- arch: x64
runs-on: ubuntu-latest
- arch: arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runs-on }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Run the build - name: Set up node & dependencies
uses: ./.github/actions/build-server uses: actions/setup-node@v4
with: with:
arch: ${{ matrix.arch }} node-version: 20
cache: "npm"
- 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 - uses: actions/upload-artifact@v4
with: with:
name: TriliumNextNotes linux server ${{ matrix.arch }} name: TriliumNextNotes linux server x64
path: upload/TriliumNextNotes-linux-${{ matrix.arch }}-${{ github.ref_name }}.tar.xz path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz

View File

@@ -12,7 +12,7 @@ permissions:
contents: write contents: write
jobs: jobs:
nightly-electron: nightly-electron:
name: Deploy nightly name: Deploy nightly
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -20,71 +20,110 @@ jobs:
os: os:
- name: macos - name: macos
image: macos-latest image: macos-latest
extension: [dmg, zip] extension: dmg
- name: linux - name: linux
image: ubuntu-latest image: ubuntu-latest
extension: [deb, rpm, zip, flatpak] extension: deb
- name: windows - name: windows
image: windows-latest image: windows-latest
extension: [exe, zip] extension: exe
runs-on: ${{ matrix.os.image }} runs-on: ${{ matrix.os.image }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set up node & dependencies - name: Set up node & dependencies
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
- name: Set up Python for appdmg to be installed
if: ${{ matrix.os.name == 'macos' }}
run: brew install python-setuptools
- name: Install dependencies - name: Install dependencies
shell: bash
run: npm ci run: npm ci
- name: Update build info
run: npm run update-build-info
- name: Update nightly version - name: Update nightly version
run: npm run chore:ci-update-nightly-version run: npm run ci-update-nightly-version
- name: Run the build - name: Run electron-forge
uses: ./.github/actions/build-electron 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 }}.zip"
file=$(find out/make -name '*.${{ matrix.os.extension }}' -print -quit)
cp "$file" "upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}.${{ 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 }}.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 }}.${{ matrix.os.extension }}"
- name: Publish artifacts
uses: actions/upload-artifact@v4
with: with:
os: ${{ matrix.os.name }} name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
arch: ${{ matrix.arch }} path: upload/*.zip
extension: ${{ join(matrix.os.extension, ' ') }} overwrite: true
- name: Publish installer artifacts
- name: Publish release uses: actions/upload-artifact@v4
uses: softprops/action-gh-release@v2
with: with:
make_latest: false name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
prerelease: true path: upload/*.${{ matrix.os.extension }}
draft: false overwrite: true
fail_on_unmatched_files: true
files: upload/*.*
tag_name: nightly
name: Nightly Build
- name: Deploy release
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: ${{ env.GITHUB_UPLOAD_URL }}
release_id: ${{ env.GITHUB_RELEASE_ID }}
asset_path: upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}.zip # path to archive to upload
asset_name: TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-nightly.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash
asset_content_type: application/zip # required by GitHub API
- name: Deploy installer release
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: ${{ env.GITHUB_UPLOAD_URL }}
release_id: ${{ env.GITHUB_RELEASE_ID }}
asset_path: upload/TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}.${{ matrix.os.extension }} # path to archive to upload
asset_name: TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-nightly.${{ matrix.os.extension }} # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash
asset_content_type: application/zip # required by GitHub API
nightly-server: nightly-server:
name: Deploy server nightly name: Deploy server nightly
strategy: runs-on: ubuntu-latest
fail-fast: false
matrix:
arch: [x64, arm64]
include:
- arch: x64
runs-on: ubuntu-latest
- arch: arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runs-on }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set up node & dependencies
- name: Run the build uses: actions/setup-node@v4
uses: ./.github/actions/build-server
with: with:
os: linux node-version: 20
arch: ${{ matrix.arch }} cache: "npm"
- name: Install dependencies
- name: Publish release run: npm ci
uses: softprops/action-gh-release@v2 - name: Run Linux server build (x86_64)
run: |
npm run update-build-info
npm run ci-update-nightly-version
./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: with:
make_latest: false name: TriliumNextNotes linux server x64
prerelease: true path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz
draft: false overwrite: true
fail_on_unmatched_files: true
files: upload/*.* - name: Deploy release
tag_name: nightly uses: WebFreak001/deploy-nightly@v3.2.0
name: Nightly Build with:
upload_url: ${{ env.GITHUB_UPLOAD_URL }}
release_id: ${{ env.GITHUB_RELEASE_ID }}
asset_path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz # path to archive to upload
asset_name: TriliumNextNotes-linux-x64-nightly.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash
asset_content_type: application/zip # required by GitHub API

View File

@@ -3,7 +3,7 @@ on:
push: push:
tags: tags:
- "v*" - "v*"
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: write contents: write
concurrency: concurrency:
@@ -20,13 +20,13 @@ jobs:
os: os:
- name: macos - name: macos
image: macos-latest image: macos-latest
extension: [dmg, zip] extension: dmg
- name: linux - name: linux
image: ubuntu-latest image: ubuntu-latest
extension: [deb, rpm, zip, flatpak] extension: deb
- name: windows - name: windows
image: windows-latest image: windows-latest
extension: [exe, zip] extension: exe
runs-on: ${{ matrix.os.image }} runs-on: ${{ matrix.os.image }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -34,43 +34,62 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
- name: Run the build - name: Set up Python for appdmg to be installed
uses: ./.github/actions/build-electron if: ${{ matrix.os.name == 'macos' }}
with: run: brew install python-setuptools
os: ${{ matrix.os.name }} - name: Install dependencies
arch: ${{ matrix.arch }} run: npm ci
extension: ${{ join(matrix.os.extension, ' ') }} - 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-${{ github.ref_name }}-${{ matrix.os.name }}-${{ matrix.arch }}.zip"
file=$(find out/make -name '*.${{ matrix.os.extension }}' -print -quit)
cp "$file" "upload/TriliumNextNotes-${{ github.ref_name }}-${{ matrix.os.name }}-${{ matrix.arch }}.${{ 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-${{ github.ref_name }}-${{ matrix.os.name }}-${{ matrix.arch }}.zip"
$file = Get-ChildItem -Path out/make -Filter '*.${{ matrix.os.extension }}' -Recurse | Select-Object -First 1
Copy-Item -Path $file.FullName -Destination "upload/TriliumNextNotes-${{ github.ref_name }}-${{ matrix.os.name }}-${{ matrix.arch }}.${{ matrix.os.extension }}"
- name: Publish release - name: Publish release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
draft: true draft: true
fail_on_unmatched_files: true fail_on_unmatched_files: true
files: upload/*.* files: upload/*.*
build_linux_server-x64: build_linux_server-x64:
name: Build Linux Server name: Build Linux Server x86_64
strategy: runs-on: ubuntu-latest
fail-fast: false
matrix:
arch: [x64, arm64]
include:
- arch: x64
runs-on: ubuntu-latest
- arch: arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runs-on }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set up node & dependencies
- name: Run the build uses: actions/setup-node@v4
uses: ./.github/actions/build-server
with: with:
os: linux node-version: 20
arch: ${{ matrix.arch }} cache: "npm"
- 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-${{ github.ref_name }}-server-linux-x64.tar.xz"
- name: Publish release - name: Publish release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
draft: true draft: true
fail_on_unmatched_files: true fail_on_unmatched_files: true
files: upload/*.* files: upload/*.*

3
.gitignore vendored
View File

@@ -1,14 +1,11 @@
.cache
.DS_Store .DS_Store
node_modules/ node_modules/
dist/ dist/
build/ build/
coverage/
src/public/app-dist/ src/public/app-dist/
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
po-*/ po-*/
.flatpak-builder/
*.db *.db
!integration-tests/db/document.db !integration-tests/db/document.db

View File

@@ -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 server:start command: npm run start-server
ports: ports:
- port: 8080 - port: 8080

1
.npmrc
View File

@@ -1 +1,2 @@
save-prefix = '' save-prefix = ''
legacy-peer-deps = true

View File

@@ -18,6 +18,5 @@
"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/**"]
} }

View File

@@ -1,5 +1,5 @@
# Build stage # Build stage
FROM node:22.14.0-bullseye-slim AS builder FROM node:22.13.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,9 +25,10 @@ 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 build:webpack && \ npm run webpack && \
npm prune --omit=dev && \ npm prune --omit=dev && \
npm cache clean --force && \ npm cache clean --force && \
cp src/public/app/share.js src/public/app-dist/. && \
cp -r src/public/app/doc_notes src/public/app-dist/. && \ cp -r src/public/app/doc_notes src/public/app-dist/. && \
rm -rf src/public/app/* && \ rm -rf src/public/app/* && \
mkdir -p src/public/app/services && \ mkdir -p src/public/app/services && \
@@ -36,7 +37,7 @@ RUN cp -R build/src/* src/. && \
rm -r build rm -r build
# Runtime stage # Runtime stage
FROM node:22.14.0-bullseye-slim FROM node:22.13.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 \

View File

@@ -1,5 +1,5 @@
# Build stage # Build stage
FROM node:22.14.0-alpine AS builder FROM node:22.13.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,9 +24,10 @@ 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 build:webpack && \ npm run webpack && \
npm prune --omit=dev && \ npm prune --omit=dev && \
npm cache clean --force && \ npm cache clean --force && \
cp src/public/app/share.js src/public/app-dist/. && \
cp -r src/public/app/doc_notes src/public/app-dist/. && \ cp -r src/public/app/doc_notes src/public/app-dist/. && \
rm -rf src/public/app && \ rm -rf src/public/app && \
mkdir -p src/public/app/services && \ mkdir -p src/public/app/services && \
@@ -35,7 +36,7 @@ RUN cp -R build/src/* src/. && \
rm -r build rm -r build
# Runtime stage # Runtime stage
FROM node:22.14.0-alpine FROM node:22.13.0-alpine
# Install runtime dependencies # Install runtime dependencies
RUN apk add --no-cache su-exec shadow RUN apk add --no-cache su-exec shadow

View File

@@ -78,7 +78,7 @@ Trilium 也提供 Flatpak
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 致谢 ## 👏 致谢

View File

@@ -86,7 +86,7 @@ Clone localmente y ejecute
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Reconocimientos ## 👏 Reconocimientos

View File

@@ -73,7 +73,7 @@ Clona localmente ed esegui
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Riconoscimenti ## 👏 Riconoscimenti

View File

@@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 📢 シャウトアウト ## 📢 シャウトアウト

View File

@@ -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 server:start npm run start-server
``` ```
### Documentation ### Documentation
@@ -118,10 +118,8 @@ Head on over to our [Docs repo](https://github.com/TriliumNext/Docs)
## 🤝 Support ## 🤝 Support
Support for the TriliumNext organization will be possible in the near future. For now, you can: You can support the original Trilium developer using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
- Support continued development on TriliumNext by supporting our developers: [eliandoran](https://github.com/sponsors/eliandoran) (See the [repository insights]([developers]([url](https://github.com/TriliumNext/Notes/graphs/contributors))) for a full list) Support for the TriliumNext organization will be possible in the near future.
- Show a token of gratitude to the original Trilium developer ([zadam](https://github.com/sponsors/zadam)) via [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
## 🔑 License ## 🔑 License

View File

@@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Благодарности ## 👏 Благодарности

View File

@@ -2,57 +2,21 @@
set -e # Fail on any command error set -e # Fail on any command error
# Debug output PKG_DIR=dist/trilium-linux-x64-server
echo "Matrix Arch: $MATRIX_ARCH"
# Detect architecture from matrix input, fallback to system architecture
if [ -n "$MATRIX_ARCH" ]; then
ARCH=$MATRIX_ARCH
else
ARCH=$(uname -m)
# Convert system architecture to our naming convention
case $ARCH in
x86_64) ARCH="x64" ;;
aarch64) ARCH="arm64" ;;
esac
fi
# Debug output
echo "Selected Arch: $ARCH"
# Set Node.js version and architecture-specific filename
NODE_VERSION=20.15.1 NODE_VERSION=20.15.1
NODE_ARCH=$ARCH
# Debug output
echo "Node arch: $NODE_ARCH"
# Special case for x64 in Node.js downloads
if [ "$NODE_ARCH" = "x64" ]; then
NODE_FILENAME="x64"
elif [ "$NODE_ARCH" = "arm64" ]; then
NODE_FILENAME="arm64"
fi
# Debug output
echo "Node filename: $NODE_FILENAME"
PKG_DIR=dist/trilium-linux-${ARCH}-server
echo "Package directory: $PKG_DIR"
if [ "$1" != "DONTCOPY" ] if [ "$1" != "DONTCOPY" ]
then then
# Need to modify copy-trilium.sh to accept the target directory ./bin/copy-trilium.sh $PKG_DIR
./bin/copy-trilium.sh "$PKG_DIR"
fi fi
cd dist cd dist
wget https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_FILENAME}.tar.xz wget https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz
tar xfJ node-v${NODE_VERSION}-linux-${NODE_FILENAME}.tar.xz tar xfJ node-v${NODE_VERSION}-linux-x64.tar.xz
rm node-v${NODE_VERSION}-linux-${NODE_FILENAME}.tar.xz rm node-v${NODE_VERSION}-linux-x64.tar.xz
cd .. cd ..
mv dist/node-v${NODE_VERSION}-linux-${NODE_FILENAME} $PKG_DIR/node mv dist/node-v${NODE_VERSION}-linux-x64 $PKG_DIR/node
rm -r $PKG_DIR/node/lib/node_modules/npm rm -r $PKG_DIR/node/lib/node_modules/npm
rm -r $PKG_DIR/node/include/node rm -r $PKG_DIR/node/include/node
@@ -73,4 +37,4 @@ VERSION=`jq -r ".version" package.json`
cd dist cd dist
tar cJf trilium-linux-${ARCH}-server-${VERSION}.tar.xz trilium-linux-${ARCH}-server tar cJf trilium-linux-x64-server-${VERSION}.tar.xz trilium-linux-x64-server

View File

@@ -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: any[]) { function log(...args) {
if (VERBOSE) { if (VERBOSE) {
console.log(...args); console.log(args);
} }
} }
@@ -29,12 +29,7 @@ const copy = async () => {
fs.copySync(path.join("build", srcFile), destFile, { recursive: true }); fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
} }
const filesToCopy = [ const filesToCopy = ["config-sample.ini", "tsconfig.webpack.json"];
"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));
@@ -81,11 +76,13 @@ const copy = async () => {
"node_modules/@excalidraw/excalidraw/dist/", "node_modules/@excalidraw/excalidraw/dist/",
"node_modules/katex/dist/", "node_modules/katex/dist/",
"node_modules/dayjs/", "node_modules/dayjs/",
"node_modules/force-graph/dist/",
"node_modules/boxicons/css/", "node_modules/boxicons/css/",
"node_modules/boxicons/fonts/", "node_modules/boxicons/fonts/",
"node_modules/mermaid/dist/", "node_modules/mermaid/dist/",
"node_modules/jquery/dist/", "node_modules/jquery/dist/",
"node_modules/jquery-hotkeys/", "node_modules/jquery-hotkeys/",
"node_modules/print-this/",
"node_modules/split.js/dist/", "node_modules/split.js/dist/",
"node_modules/panzoom/dist/", "node_modules/panzoom/dist/",
"node_modules/i18next/", "node_modules/i18next/",
@@ -93,6 +90,7 @@ const copy = async () => {
"node_modules/jsplumb/dist/", "node_modules/jsplumb/dist/",
"node_modules/vanilla-js-wheel-zoom/dist/", "node_modules/vanilla-js-wheel-zoom/dist/",
"node_modules/mark.js/dist/", "node_modules/mark.js/dist/",
"node_modules/knockout/build/output/",
"node_modules/normalize.css/", "node_modules/normalize.css/",
"node_modules/jquery.fancytree/dist/", "node_modules/jquery.fancytree/dist/",
"node_modules/bootstrap/dist/", "node_modules/bootstrap/dist/",
@@ -103,8 +101,7 @@ const copy = async () => {
"node_modules/codemirror/keymap/", "node_modules/codemirror/keymap/",
"node_modules/mind-elixir/dist/", "node_modules/mind-elixir/dist/",
"node_modules/@highlightjs/cdn-assets/languages", "node_modules/@highlightjs/cdn-assets/languages",
"node_modules/@highlightjs/cdn-assets/styles", "node_modules/@highlightjs/cdn-assets/styles"
"node_modules/leaflet/dist"
]; ];
for (const folder of nodeModulesFolder) { for (const folder of nodeModulesFolder) {

View File

@@ -23,7 +23,7 @@ rm -rf "$DIR"
mkdir -pv "$DIR" mkdir -pv "$DIR"
echo Webpack start echo Webpack start
npm run build:webpack npm run webpack
echo Webpack finish echo Webpack finish
echo "Copying Trilium to build directory $DIR" echo "Copying Trilium to build directory $DIR"
@@ -68,6 +68,7 @@ find $DIR -name "*.ts" -type f -delete
d="$DIR"/src/public d="$DIR"/src/public
[[ -d "$d"/app-dist ]] || mkdir -pv "$d"/app-dist [[ -d "$d"/app-dist ]] || mkdir -pv "$d"/app-dist
cp "$d"/app/share.js "$d"/app-dist/
cp -r "$d"/app/doc_notes "$d"/app-dist/ cp -r "$d"/app/doc_notes "$d"/app-dist/
rm -rf "$d"/app rm -rf "$d"/app

View File

@@ -22,10 +22,6 @@ inkscape -w 180 -h 180 "../icon-color.svg" -o "./ios/apple-touch-icon.png"
# Build PNGs # Build PNGs
inkscape -w 128 -h 128 "../icon-color.svg" -o "./png/128x128.png" inkscape -w 128 -h 128 "../icon-color.svg" -o "./png/128x128.png"
inkscape -w 256 -h 256 "../icon-color.svg" -o "./png/256x256.png" inkscape -w 256 -h 256 "../icon-color.svg" -o "./png/256x256.png"
# Build dev icons (including tray)
inkscape -w 16 -h 16 "../icon-purple.svg" -o "./png/16x16-dev.png"
inkscape -w 32 -h 32 "../icon-purple.svg" -o "./png/32x32-dev.png"
inkscape -w 256 -h 256 "../icon-purple.svg" -o "./png/256x256-dev.png" inkscape -w 256 -h 256 "../icon-purple.svg" -o "./png/256x256-dev.png"
# Build Mac .icns # Build Mac .icns
@@ -45,8 +41,5 @@ icnsutil compose -f "mac/icon.icns" ./mac/*.png
# Build Windows icon # Build Windows icon
magick -background none "../icon-color.svg" -define icon:auto-resize=16,32,48,64,128,256 "./icon.ico" magick -background none "../icon-color.svg" -define icon:auto-resize=16,32,48,64,128,256 "./icon.ico"
# Build Windows setup icon
magick -background none "../icon-installer.svg" -define icon:auto-resize=16,32,48,64,128,256 "./win/setup.ico"
# Build Squirrel splash image # Build Squirrel splash image
magick "./png/256x256.png" -background "#ffffff" -gravity center -extent 640x480 "./win/setup-banner.gif" magick "./png/256x256.png" -background "#ffffff" -gravity center -extent 640x480 "./win/setup-banner.gif"

View File

@@ -1,17 +1,12 @@
[Desktop Entry] [Desktop Entry]
<%= <% if (productName) { %>Name=<%= productName %>
Object.entries({ <% } %><% if (description) { %>Comment=<%= description %>
"Name": productName, <% } %><% if (genericName) { %>GenericName=<%= genericName %>
"Comment": description, <% } %><% if (name) { %>Exec=<%= name %> %U
"GenericName": genericName, Icon=<%= name %>
"Exec": name ? `${name} %U` : undefined, <% } %>Type=Application
"Icon": name, StartupNotify=true
"Type": "Application", <% if (productName) { %>StartupWMClass=<%= productName %>
"StartupNotify": "true", <% } if (categories && categories.length) { %>Categories=<%= categories.join(';') %>;
"StartupWMClass": productName, <% } %><% if (mimeType && mimeType.length) { %>MimeType=<%= mimeType.join(';') %>;
"Categories": categories?.length ? `${categories.join(";")};` : undefined, <% } %>
"MimeType": mimeType?.length ? `${mimeType.join(";")};` : undefined
})
.map(line => line[1] ? line.join("=") : undefined)
.filter(line => !!line)
.join("\n")%>

View File

@@ -1,189 +0,0 @@
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
*/

View File

@@ -32,7 +32,7 @@ mv package.json.tmp package.json
git add package.json git add package.json
npm run chore:update-build-info npm run update-build-info
git add src/services/build.ts git add src/services/build.ts

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-bookmark"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 7v14l-6 -4l-6 4v-14a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4z" /></svg>

Before

Width:  |  Height:  |  Size: 383 B

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env bash
if ! command -v magick &> /dev/null; then
echo "This tool requires ImageMagick to be installed in order to create the icons."
exit 1
fi
if ! command -v inkscape &> /dev/null; then
echo "This tool requires Inkscape to be render sharper SVGs than ImageMagick."
exit 1
fi
script_dir=$(realpath $(dirname $0))
images_dir="$script_dir/../../images"
output_dir="$images_dir/app-icons/tray"
function generateDpiScaledIcons {
file=$1
suffix=$2
name="$(basename $file .svg)$suffix"
inkscape -w 16 -h 16 "$file" -o "$output_dir/$name.png"
inkscape -w 20 -h 20 "$file" -o "$output_dir/$name@1.25x.png"
inkscape -w 24 -h 24 "$file" -o "$output_dir/$name@1.5x.png"
inkscape -w 32 -h 32 "$file" -o "$output_dir/$name@2x.png"
}
generateDpiScaledIcons "$images_dir/icon-black.svg" "Template"
generateDpiScaledIcons "$images_dir/icon-color.svg"
generateDpiScaledIcons "$images_dir/icon-purple.svg"
for file in *.svg; do
name="$(basename $file .svg)Template"
generateDpiScaledIcons "$file" "Template"
magick "$output_dir/$name.png" -channel RGB -negate "$output_dir/$name-inverted.png"
magick "$output_dir/$name@1.25x.png" -channel RGB -negate "$output_dir/$name-inverted@1.25x.png"
magick "$output_dir/$name@1.5x.png" -channel RGB -negate "$output_dir/$name-inverted@1.5x.png"
magick "$output_dir/$name@2x.png" -channel RGB -negate "$output_dir/$name-inverted@2x.png"
done

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-x"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg>

Before

Width:  |  Height:  |  Size: 356 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-plus"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 5l0 14" /><path d="M5 12l14 0" /></svg>

Before

Width:  |  Height:  |  Size: 357 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-history"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 8l0 4l2 2" /><path d="M3.05 11a9 9 0 1 1 .5 4m-.5 5v-5h5" /></svg>

Before

Width:  |  Height:  |  Size: 387 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-calendar-star"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 21h-5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v3.5" /><path d="M16 3v4" /><path d="M8 3v4" /><path d="M4 11h11" /><path d="M17.8 20.817l-2.172 1.138a.392 .392 0 0 1 -.568 -.41l.415 -2.411l-1.757 -1.707a.389 .389 0 0 1 .217 -.665l2.428 -.352l1.086 -2.193a.392 .392 0 0 1 .702 0l1.086 2.193l2.428 .352a.39 .39 0 0 1 .217 .665l-1.757 1.707l.414 2.41a.39 .39 0 0 1 -.567 .411l-2.172 -1.138z" /></svg>

Before

Width:  |  Height:  |  Size: 734 B

View File

@@ -27,23 +27,3 @@ keyPath=
# once set, expressjs will use the X-Forwarded-For header set by the rev. proxy to determinate the real IPs of clients. # once set, expressjs will use the X-Forwarded-For header set by the rev. proxy to determinate the real IPs of clients.
# expressjs shortcuts are supported: loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) # expressjs shortcuts are supported: loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
trustedReverseProxy=false trustedReverseProxy=false
[Session]
# 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).
# It prevents your instances from overwriting each others' cookies, allowing you to stay logged in multiple instances simultanteously.
# 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
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]
#syncServerHost=
#syncServerTimeout=
#syncServerProxy=

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,5 +1,8 @@
import http from "http"; import http from "http";
import config from "./src/services/config.js"; import ini from "ini";
import fs from "fs";
import dataDir from "./src/services/data_dir.js";
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, "utf-8"));
if (config.Network.https) { if (config.Network.https) {
// built-in TLS (terminated by trilium) is not supported yet, PRs are welcome // built-in TLS (terminated by trilium) is not supported yet, PRs are welcome

View File

@@ -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 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: <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:
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 electron:switch</code> does, which uses <code>electron-rebuild</code> under the hood.</p><p>When the deliveries are built (see&nbsp;<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>.&nbsp;</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&nbsp;<a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a>&nbsp;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 switch-electron</code> does, which uses <code>electron-rebuild</code> under the hood.</p><p>When the deliveries are built (see&nbsp;<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>.&nbsp;</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&nbsp;<a class="reference-link type-text" href="UTB518X6X9Uh.html">Build deliveries locally</a>&nbsp;or via the CI.</p>
</div> </div>

View File

@@ -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 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 &nbsp;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 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 &nbsp;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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -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">server:start</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">start-server</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>

View File

@@ -78,7 +78,7 @@ Trilium 也提供 Flatpak
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 致谢 ## 👏 致谢

View File

@@ -86,7 +86,7 @@ Clone localmente y ejecute
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Reconocimientos ## 👏 Reconocimientos

View File

@@ -73,7 +73,7 @@ Clona localmente ed esegui
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Riconoscimenti ## 👏 Riconoscimenti

View File

@@ -54,7 +54,7 @@ Trilium は Flatpak としても提供されます:
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 📢 シャウトアウト ## 📢 シャウトアウト

View File

@@ -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 server:start npm run start-server
``` ```
### Documentation ### Documentation

View File

@@ -44,7 +44,7 @@ Trilium предоставляется в виде десктопного при
```shell ```shell
npm install npm install
npm run server:start npm run start-server
``` ```
## 👏 Благодарности ## 👏 Благодарности

View File

@@ -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 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> <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>
</div> </div>

View File

@@ -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 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> <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>
</div> </div>

View File

@@ -12,7 +12,7 @@ function getDataKey(password: any) {
const encryptedDataKey = getOption("encryptedDataKey"); const encryptedDataKey = getOption("encryptedDataKey");
const decryptedDataKey = decryptService.decrypt(passwordDerivedKey, encryptedDataKey); const decryptedDataKey = decryptService.decrypt(passwordDerivedKey, encryptedDataKey, 16);
return decryptedDataKey; return decryptedDataKey;
} catch (e: any) { } catch (e: any) {

View File

@@ -16,7 +16,7 @@ function decryptString(dataKey: any, cipherText: any) {
return str; return str;
} }
function decrypt(key: any, cipherText: any) { function decrypt(key: any, cipherText: any, ivLength = 13) {
if (cipherText === null) { if (cipherText === null) {
return null; return null;
} }
@@ -27,8 +27,6 @@ function decrypt(key: any, cipherText: any) {
try { try {
const cipherTextBufferWithIv = Buffer.from(cipherText.toString(), "base64"); const cipherTextBufferWithIv = Buffer.from(cipherText.toString(), "base64");
// old encrypted data can have IV of length 13, see some details here: https://github.com/zadam/trilium/issues/3017
const ivLength = cipherTextBufferWithIv.length % 16 === 0 ? 16 : 13;
const iv = cipherTextBufferWithIv.slice(0, ivLength); const iv = cipherTextBufferWithIv.slice(0, ivLength);
const cipherTextBuffer = cipherTextBufferWithIv.slice(ivLength); const cipherTextBuffer = cipherTextBufferWithIv.slice(ivLength);

View File

@@ -464,9 +464,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/better-sqlite3": { "node_modules/better-sqlite3": {
"version": "11.8.1", "version": "11.7.2",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.8.1.tgz", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.7.2.tgz",
"integrity": "sha512-9BxNaBkblMjhJW8sMRZxnxVTRgbRmssZW0Oxc1MPBTfiR+WW21e2Mk4qu8CzrcZb1LwPCnFsfDEzq+SNcBU8eg==", "integrity": "sha512-10a57cHVDmfNQS4jrZ9AH2t+2ekzYh5Rhbcnb4ytpmYweoLdogDmyTt5D+hLiY9b44Mx9foowb/4iXBTO2yP3Q==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"bindings": "^1.5.0", "bindings": "^1.5.0",
@@ -1516,9 +1516,9 @@
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
}, },
"better-sqlite3": { "better-sqlite3": {
"version": "11.8.1", "version": "11.7.2",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.8.1.tgz", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.7.2.tgz",
"integrity": "sha512-9BxNaBkblMjhJW8sMRZxnxVTRgbRmssZW0Oxc1MPBTfiR+WW21e2Mk4qu8CzrcZb1LwPCnFsfDEzq+SNcBU8eg==", "integrity": "sha512-10a57cHVDmfNQS4jrZ9AH2t+2ekzYh5Rhbcnb4ytpmYweoLdogDmyTt5D+hLiY9b44Mx9foowb/4iXBTO2yP3Q==",
"requires": { "requires": {
"bindings": "^1.5.0", "bindings": "^1.5.0",
"prebuild-install": "^7.1.1" "prebuild-install": "^7.1.1"

View File

@@ -1,27 +0,0 @@
import { test, expect, Page } from "@playwright/test";
import App from "./support/app";
test("Help popup", async ({ page, context }) => {
page.setDefaultTimeout(15_000);
const app = new App(page, context);
await app.goto();
const popupPromise = page.waitForEvent("popup");
await app.currentNoteSplit.press("Shift+F1");
await page.getByRole("link", { name: "online" }).click();
const popup = await popupPromise;
expect(popup.url()).toBe("https://triliumnext.github.io/Docs/");
});
test("Complete help in search", async ({ page, context }) => {
const app = new App(page, context);
await app.goto();
await app.launcherBar.locator(".bx-search").first().click();
await app.currentNoteSplit.locator(".search-settings .bx-help-circle").click();
const popupPromise = page.waitForEvent("popup");
await page.getByRole("link", { name: "complete help on search syntax" }).click();
const popup = await popupPromise;
expect(popup.url()).toBe("https://triliumnext.github.io/Docs/Wiki/search.html");
});

View File

@@ -1,67 +0,0 @@
import { test, expect, Page, BrowserContext } from "@playwright/test";
import App from "../support/app";
test("renders ELK flowchart", async ({ page, context }) => {
await testAriaSnapshot({
page, context,
noteTitle: "Flowchart ELK on",
snapshot: `
- document:
- paragraph: A
- paragraph: B
- paragraph: C
- paragraph: Guarantee
- paragraph: User attributes
- paragraph: Master data
- paragraph: Exchange Rate
- paragraph: Profit Centers
- paragraph: Vendor Partners
- paragraph: Work Situation
- paragraph: Customer
- paragraph: Profit Centers
- paragraph: Guarantee
- text: Interfaces for B
`
})
});
test("renders standard flowchart", async ({ page, context }) => {
await testAriaSnapshot({
page, context,
noteTitle: "Flowchart ELK off",
snapshot: `
- document:
- paragraph: Guarantee
- paragraph: User attributes
- paragraph: Master data
- paragraph: Exchange Rate
- paragraph: Profit Centers
- paragraph: Vendor Partners
- paragraph: Work Situation
- paragraph: Customer
- paragraph: Profit Centers
- paragraph: Guarantee
- paragraph: A
- paragraph: B
- paragraph: C
- text: Interfaces for B
`
})
});
interface AriaTestOpts {
page: Page;
context: BrowserContext;
noteTitle: string;
snapshot: string;
}
async function testAriaSnapshot({ page, context, noteTitle, snapshot }: AriaTestOpts) {
const app = new App(page, context);
await app.goto();
await app.goToNoteInNewTab(noteTitle);
const svgData = app.currentNoteSplit.locator(".mermaid-render svg");
await expect(svgData).toBeVisible();
await expect(svgData).toMatchAriaSnapshot(snapshot);
}

View File

@@ -1,4 +1,4 @@
import { test, expect } from "@playwright/test"; import { test, expect, Page } from "@playwright/test";
import App from "../support/app"; import App from "../support/app";
test("displays simple map", async ({ page, context }) => { test("displays simple map", async ({ page, context }) => {

View File

@@ -1,9 +0,0 @@
import { test, expect } from "@playwright/test";
import App from "../support/app";
test("renders global map", async ({ page, context }) => {
const app = new App(page, context);
await app.goto();
await app.launcherBar.locator(".launcher-button.bx-map-alt").click();
await expect(app.currentNoteSplit.locator(".force-graph-container canvas")).toBeVisible();
});

View File

@@ -49,20 +49,3 @@ test("Highlights list is displayed", async ({ page, context }) => {
await expect(rootList.locator("li").nth(index++)).toContainText(highlightedEl); await expect(rootList.locator("li").nth(index++)).toContainText(highlightedEl);
} }
}); });
test("Displays math popup", async ({ page, context }) => {
const app = new App(page, context);
await app.goto();
await app.goToNoteInNewTab("Empty text");
const noteContent = app.currentNoteSplit.locator(".note-detail-editable-text-editor")
await noteContent.fill("Hello world");
await noteContent.press("ControlOrMeta+M");
const mathForm = page.locator(".ck-math-form");
await expect(mathForm).toBeVisible();
await mathForm.locator(".ck-input").first().fill("e=mc^2");
const preview = page.locator('[id^="math-preview"]');
await expect(preview).toMatchAriaSnapshot("- math: e = m c 2");
});

View File

@@ -1,18 +0,0 @@
import { test, expect, Page } from "@playwright/test";
import App from "./support/app";
test("Goes to share root", async ({ page, context }) => {
const app = new App(page, context);
await app.goto({ url: "/share" });
const noteTitle = "Shared notes";
await expect(page).toHaveTitle(noteTitle);
await expect(page.locator("h1")).toHaveText(noteTitle);
});
test("Goes to parent share root page", async ({ page, context }) => {
const app = new App(page, context);
await app.goto({ url: "/share/bKMn5EFv9KS2" });
await expect(page.locator("h1")).toHaveText("Child note");
await page.locator("#parentLink a").click();
await page.waitForURL("/share/");
});

View File

@@ -2,7 +2,6 @@ import { expect, Locator, Page } from "@playwright/test";
import type { BrowserContext } from "@playwright/test"; import type { BrowserContext } from "@playwright/test";
interface GotoOpts { interface GotoOpts {
url?: string;
isMobile?: boolean; isMobile?: boolean;
} }
@@ -14,7 +13,6 @@ export default class App {
readonly tabBar: Locator; readonly tabBar: Locator;
readonly noteTree: Locator; readonly noteTree: Locator;
readonly launcherBar: Locator;
readonly currentNoteSplit: Locator; readonly currentNoteSplit: Locator;
readonly sidebar: Locator; readonly sidebar: Locator;
@@ -24,32 +22,25 @@ export default class App {
this.tabBar = page.locator(".tab-row-widget-container"); this.tabBar = page.locator(".tab-row-widget-container");
this.noteTree = page.locator(".tree-wrapper"); this.noteTree = page.locator(".tree-wrapper");
this.launcherBar = page.locator("#launcher-container");
this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)") this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)")
this.sidebar = page.locator("#right-pane"); this.sidebar = page.locator("#right-pane");
} }
async goto({ url, isMobile }: GotoOpts = {}) { async goto(opts: GotoOpts = {}) {
await this.context.addCookies([ await this.context.addCookies([
{ {
url: BASE_URL, url: BASE_URL,
name: "trilium-device", name: "trilium-device",
value: isMobile ? "mobile" : "desktop" value: opts.isMobile ? "mobile" : "desktop"
} }
]); ]);
if (!url) { await this.page.goto("/", { waitUntil: "networkidle" });
url = "/";
}
await this.page.goto(url, { waitUntil: "networkidle" });
// Wait for the page to load. // Wait for the page to load.
if (url === "/") { await expect(this.page.locator(".tree"))
await expect(this.page.locator(".tree")) .toContainText("Trilium Integration Test");
.toContainText("Trilium Integration Test"); await this.closeAllTabs();
await this.closeAllTabs();
}
} }
async goToNoteInNewTab(noteTitle: string) { async goToNoteInNewTab(noteTitle: string) {

View File

@@ -26,8 +26,6 @@ electronDl({ saveAs: true });
// needed for excalidraw export https://github.com/zadam/trilium/issues/4271 // needed for excalidraw export https://github.com/zadam/trilium/issues/4271
electron.app.commandLine.appendSwitch("enable-experimental-web-platform-features"); electron.app.commandLine.appendSwitch("enable-experimental-web-platform-features");
electron.app.userAgentFallback = `${electron.app.getName()} ${electron.app.getVersion()}`;
// Quit when all windows are closed, except on macOS. There, it's common // Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits // for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q. // explicitly with Cmd + Q.

View File

@@ -3,13 +3,6 @@ const fs = require("fs-extra");
const APP_NAME = "TriliumNext Notes"; const APP_NAME = "TriliumNext Notes";
const extraResourcesForPlatform = getExtraResourcesForPlatform();
const baseLinuxMakerConfigOptions = {
icon: "./images/app-icons/png/128x128.png",
desktopTemplate: path.resolve("./bin/electron-forge/desktop.ejs"),
categories: ["Office", "Utility"]
};
module.exports = { module.exports = {
packagerConfig: { packagerConfig: {
executableName: "trilium", executableName: "trilium",
@@ -19,7 +12,7 @@ module.exports = {
icon: "./images/app-icons/icon", icon: "./images/app-icons/icon",
extraResource: [ extraResource: [
// Moved to root // Moved to root
...extraResourcesForPlatform, ...getExtraResourcesForPlatform(),
// Moved to resources (TriliumNext Notes.app/Contents/Resources on macOS) // Moved to resources (TriliumNext Notes.app/Contents/Resources on macOS)
"translations/", "translations/",
@@ -27,18 +20,22 @@ module.exports = {
], ],
afterComplete: [ afterComplete: [
(buildPath, _electronVersion, platform, _arch, callback) => { (buildPath, _electronVersion, platform, _arch, callback) => {
for (const resource of extraResourcesForPlatform) { const extraResources = getExtraResourcesForPlatform();
for (const resource of extraResources) {
const baseName = path.basename(resource); const baseName = path.basename(resource);
let sourcePath;
if (platform === "darwin") {
sourcePath = path.join(buildPath, `${APP_NAME}.app`, "Contents", "Resources", baseName);
} else {
sourcePath = path.join(buildPath, "resources", baseName);
}
let destPath;
// prettier-ignore if (baseName !== "256x256.png") {
const sourcePath = (platform === "darwin") destPath = path.join(buildPath, baseName);
? path.join(buildPath, `${APP_NAME}.app`, "Contents", "Resources", baseName) } else {
: path.join(buildPath, "resources", baseName); destPath = path.join(buildPath, "icon.png");
}
// prettier-ignore
const destPath = (baseName !== "256x256.png")
? path.join(buildPath, baseName)
: path.join(buildPath, "icon.png");
// Copy files from resources folder to root // Copy files from resources folder to root
fs.move(sourcePath, destPath) fs.move(sourcePath, destPath)
@@ -56,38 +53,8 @@ module.exports = {
name: "@electron-forge/maker-deb", name: "@electron-forge/maker-deb",
config: { config: {
options: { options: {
...baseLinuxMakerConfigOptions icon: "./images/app-icons/png/128x128.png",
} desktopTemplate: path.resolve("./bin/electron-forge/desktop.ejs")
}
},
{
name: "@electron-forge/maker-flatpak",
config: {
options: {
...baseLinuxMakerConfigOptions,
id: "com.triliumnext.notes",
runtimeVersion: "24.08",
base: "org.electronjs.Electron2.BaseApp",
baseVersion: "24.08",
baseFlatpakref: "https://flathub.org/repo/flathub.flatpakrepo",
modules: [
{
name: "zypak",
sources: {
type: "git",
url: "https://github.com/refi64/zypak",
tag: "v2024.01.17"
}
}
]
},
}
},
{
name: "@electron-forge/maker-rpm",
config: {
options: {
...baseLinuxMakerConfigOptions
} }
} }
}, },
@@ -95,7 +62,7 @@ module.exports = {
name: "@electron-forge/maker-squirrel", name: "@electron-forge/maker-squirrel",
config: { config: {
iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/icon.ico", iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/icon.ico",
setupIcon: "./images/app-icons/win/setup.ico", setupIcon: "./images/app-icons/icon.ico",
loadingGif: "./images/app-icons/win/setup-banner.gif" loadingGif: "./images/app-icons/win/setup-banner.gif"
} }
}, },
@@ -124,20 +91,21 @@ module.exports = {
}; };
function getExtraResourcesForPlatform() { function getExtraResourcesForPlatform() {
const resources = ["dump-db/", "./bin/tpl/anonymize-database.sql"]; let resources = ["dump-db/", "./bin/tpl/anonymize-database.sql"];
const scripts = ["trilium-portable", "trilium-safe-mode", "trilium-no-cert-check"];
const getScriptRessources = () => {
const scripts = ["trilium-portable", "trilium-safe-mode", "trilium-no-cert-check"];
const scriptExt = (process.platform === "win32") ? "bat" : "sh";
return scripts.map(script => `./bin/tpl/${script}.${scriptExt}`);
}
switch (process.platform) { switch (process.platform) {
case "win32": case "win32":
resources.push(...getScriptRessources()) for (const script of scripts) {
resources.push(`./bin/tpl/${script}.bat`);
}
break;
case "darwin":
break; break;
case "linux": case "linux":
resources.push(...getScriptRessources(), "images/app-icons/png/256x256.png"); resources.push("images/app-icons/png/256x256.png");
for (const script of scripts) {
resources.push(`./bin/tpl/${script}.sh`);
}
break; break;
default: default:
break; break;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 804 B

Some files were not shown because too many files have changed in this diff Show More