mirror of
https://github.com/zadam/trilium.git
synced 2025-12-15 12:49:53 +01:00
Compare commits
2 Commits
v0.100.0
...
v0.91.3-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dc546605b | ||
|
|
62cda1bd24 |
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.git
|
||||
.idea
|
||||
/bin
|
||||
/dist
|
||||
/docs
|
||||
/npm-debug.log
|
||||
node_modules
|
||||
|
||||
src/**/*.ts
|
||||
!src/services/asset_path.ts
|
||||
@@ -1,6 +1,6 @@
|
||||
root = true
|
||||
|
||||
[*.{js,ts,tsx}]
|
||||
[*.{js,ts}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
@@ -8,9 +8,6 @@ indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
|
||||
[{server,translation}.json]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
@@ -18,9 +15,3 @@ indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
21
.gitattributes
vendored
21
.gitattributes
vendored
@@ -1,21 +1,2 @@
|
||||
# Mark files as auto-generated to simplify reviews.
|
||||
package-lock.json linguist-generated=true
|
||||
**/package-lock.json linguist-generated=true
|
||||
apps/server/src/assets/doc_notes/en/User[[:space:]]Guide/** linguist-generated
|
||||
|
||||
# Ignore from GitHub language stats.
|
||||
apps/server/src/assets/doc_notes/en/User[[:space:]]Guide/**/*.html eol=lf
|
||||
apps/server/src/assets/doc_notes/** linguist-vendored=true
|
||||
apps/edit-docs/demo/** linguist-vendored=true
|
||||
docs/** linguist-vendored=true
|
||||
|
||||
# Normalize line endings.
|
||||
docs/**/*.md eol=lf
|
||||
docs/**/*.json eol=lf
|
||||
demo/**/*.html eol=lf
|
||||
demo/**/*.json eol=lf
|
||||
demo/**/*.svg eol=lf
|
||||
demo/**/*.txt eol=lf
|
||||
demo/**/*.js eol=lf
|
||||
demo/**/*.css eol=lf
|
||||
*.sh eol=lf
|
||||
**/package-lock.json linguist-generated=true
|
||||
6
.github/FUNDING.yml
vendored
6
.github/FUNDING.yml
vendored
@@ -1,6 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [eliandoran]
|
||||
custom: ["https://paypal.me/eliandoran"]
|
||||
liberapay: ElianDoran
|
||||
buy_me_a_coffee: eliandoran
|
||||
github: [zadam]
|
||||
custom: ["https://paypal.me/za4am"]
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Bug Report
|
||||
description: Report a bug
|
||||
type: "Bug"
|
||||
title: "(Bug report) "
|
||||
labels: "Type: Bug"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
5
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,11 +1,12 @@
|
||||
name: Feature Request
|
||||
description: Ask for a new feature to be added
|
||||
type: "Feature"
|
||||
title: "(Feature request) "
|
||||
labels: "Type: Enhancement"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
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:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/task.yml
vendored
10
.github/ISSUE_TEMPLATE/task.yml
vendored
@@ -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
|
||||
187
.github/actions/build-electron/action.yml
vendored
187
.github/actions/build-electron/action.yml
vendored
@@ -1,187 +0,0 @@
|
||||
name: "Build Electron App"
|
||||
description: "Builds and packages the Electron app for different platforms"
|
||||
|
||||
inputs:
|
||||
os:
|
||||
description: "One of the supported platforms: macos, linux, windows"
|
||||
required: true
|
||||
arch:
|
||||
description: "The architecture to build for: x64, arm64"
|
||||
required: true
|
||||
shell:
|
||||
description: "Which shell to use"
|
||||
required: true
|
||||
forge_platform:
|
||||
description: "The --platform to pass to Electron Forge"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# Certificate setup
|
||||
- name: Import Apple certificates
|
||||
if: inputs.os == 'macos'
|
||||
uses: apple-actions/import-codesign-certs@v5
|
||||
with:
|
||||
p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }}
|
||||
p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }}
|
||||
keychain: build-app-${{ github.run_id }}
|
||||
keychain-password: ${{ github.run_id }}
|
||||
|
||||
- name: Install Installer certificate
|
||||
if: inputs.os == 'macos'
|
||||
uses: apple-actions/import-codesign-certs@v5
|
||||
with:
|
||||
p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
|
||||
p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
|
||||
keychain: build-installer-${{ github.run_id }}
|
||||
keychain-password: ${{ github.run_id }}
|
||||
|
||||
- name: Verify certificates
|
||||
if: inputs.os == 'macos'
|
||||
shell: ${{ inputs.shell }}
|
||||
run: |
|
||||
echo "Available signing identities in app keychain:"
|
||||
security find-identity -v -p codesigning build-app-${{ github.run_id }}.keychain
|
||||
|
||||
echo "Available signing identities in installer keychain:"
|
||||
security find-identity -v -p codesigning build-installer-${{ github.run_id }}.keychain
|
||||
|
||||
# Make the keychains searchable
|
||||
security list-keychains -d user -s build-app-${{ github.run_id }}.keychain build-installer-${{ github.run_id }}.keychain $(security list-keychains -d user | tr -d '"')
|
||||
security default-keychain -s build-app-${{ github.run_id }}.keychain
|
||||
security unlock-keychain -p ${{ github.run_id }} build-app-${{ github.run_id }}.keychain
|
||||
security unlock-keychain -p ${{ github.run_id }} build-installer-${{ github.run_id }}.keychain
|
||||
security set-keychain-settings -t 3600 -l build-app-${{ github.run_id }}.keychain
|
||||
security set-keychain-settings -t 3600 -l build-installer-${{ github.run_id }}.keychain
|
||||
|
||||
- name: Set up Python and other macOS dependencies
|
||||
if: ${{ inputs.os == 'macos' }}
|
||||
shell: ${{ inputs.shell }}
|
||||
run: |
|
||||
brew install python-setuptools
|
||||
brew install create-dmg
|
||||
|
||||
- name: Install dependencies for RPM and Flatpak package building
|
||||
if: ${{ inputs.os == 'linux' }}
|
||||
shell: ${{ inputs.shell }}
|
||||
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: Update build info
|
||||
shell: ${{ inputs.shell }}
|
||||
run: pnpm run chore:update-build-info
|
||||
|
||||
# Critical debugging configuration
|
||||
- name: Run electron-forge build with enhanced logging
|
||||
shell: ${{ inputs.shell }}
|
||||
env:
|
||||
# Pass through required environment variables for signing and notarization
|
||||
APPLE_TEAM_ID: ${{ env.APPLE_TEAM_ID }}
|
||||
APPLE_ID: ${{ env.APPLE_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }}
|
||||
WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }}
|
||||
TRILIUM_ARTIFACT_NAME_HINT: TriliumNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}
|
||||
TARGET_ARCH: ${{ inputs.arch }}
|
||||
run: pnpm run --filter desktop electron-forge:make --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }}
|
||||
|
||||
# Add DMG signing step
|
||||
- name: Sign DMG
|
||||
if: inputs.os == 'macos'
|
||||
shell: ${{ inputs.shell }}
|
||||
run: |
|
||||
echo "Signing DMG file..."
|
||||
dmg_file=$(find ./apps/desktop/dist -name "*.dmg" -print -quit)
|
||||
if [ -n "$dmg_file" ]; then
|
||||
echo "Found DMG: $dmg_file"
|
||||
# Get the first valid signing identity from the keychain
|
||||
SIGNING_IDENTITY=$(security find-identity -v -p codesigning build-app-${{ github.run_id }}.keychain | grep "Developer ID Application" | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [ -z "$SIGNING_IDENTITY" ]; then
|
||||
echo "Error: No valid Developer ID Application certificate found in keychain"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using signing identity: $SIGNING_IDENTITY"
|
||||
# Sign the DMG
|
||||
codesign --force --sign "$SIGNING_IDENTITY" --options runtime --timestamp "$dmg_file"
|
||||
# Notarize the DMG
|
||||
xcrun notarytool submit "$dmg_file" --apple-id "$APPLE_ID" --password "$APPLE_ID_PASSWORD" --team-id "$APPLE_TEAM_ID" --wait
|
||||
# Staple the notarization ticket
|
||||
xcrun stapler staple "$dmg_file"
|
||||
else
|
||||
echo "No DMG found to sign"
|
||||
fi
|
||||
|
||||
- name: Verify code signing
|
||||
if: inputs.os == 'macos'
|
||||
shell: ${{ inputs.shell }}
|
||||
run: |
|
||||
echo "Verifying code signing for all artifacts..."
|
||||
|
||||
# First check the .app bundle
|
||||
echo "Looking for .app bundle..."
|
||||
app_bundle=$(find ./apps/desktop/dist -name "*.app" -print -quit)
|
||||
if [ -n "$app_bundle" ]; then
|
||||
echo "Found app bundle: $app_bundle"
|
||||
echo "Verifying app bundle signing..."
|
||||
codesign --verify --deep --strict --verbose=2 "$app_bundle"
|
||||
echo "Displaying app bundle signing info..."
|
||||
codesign --display --verbose=2 "$app_bundle"
|
||||
|
||||
echo "Checking entitlements..."
|
||||
codesign --display --entitlements :- "$app_bundle"
|
||||
|
||||
echo "Checking notarization status..."
|
||||
xcrun stapler validate "$app_bundle" || echo "Warning: App bundle not notarized yet"
|
||||
else
|
||||
echo "No .app bundle found to verify"
|
||||
fi
|
||||
|
||||
# Then check DMG if it exists
|
||||
echo "Looking for DMG..."
|
||||
dmg_file=$(find ./apps/desktop/dist -name "*.dmg" -print -quit)
|
||||
if [ -n "$dmg_file" ]; then
|
||||
echo "Found DMG: $dmg_file"
|
||||
echo "Verifying DMG signing..."
|
||||
codesign --verify --deep --strict --verbose=2 "$dmg_file"
|
||||
echo "Displaying DMG signing info..."
|
||||
codesign --display --verbose=2 "$dmg_file"
|
||||
|
||||
echo "Checking DMG notarization..."
|
||||
xcrun stapler validate "$dmg_file" || echo "Warning: DMG not notarized yet"
|
||||
else
|
||||
echo "No DMG found to verify"
|
||||
fi
|
||||
|
||||
# Finally check ZIP if it exists
|
||||
echo "Looking for ZIP..."
|
||||
zip_file=$(find ./apps/desktop/dist -name "*.zip" -print -quit)
|
||||
if [ -n "$zip_file" ]; then
|
||||
echo "Found ZIP: $zip_file"
|
||||
echo "Note: ZIP files are not code signed, but their contents should be"
|
||||
fi
|
||||
|
||||
- name: Sign the RPM
|
||||
if: inputs.os == 'linux'
|
||||
shell: ${{ inputs.shell }}
|
||||
run: |
|
||||
echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import
|
||||
|
||||
# Import the key into RPM for verification
|
||||
gpg --export -a > pubkey
|
||||
rpm --import pubkey
|
||||
rm pubkey
|
||||
|
||||
# Sign the RPM
|
||||
rpm_file=$(find ./apps/desktop/upload -name "*.rpm" -print -quit)
|
||||
rpmsign --define "_gpg_name Trilium Notes Signing Key <triliumnotes@outlook.com>" --addsign "$rpm_file"
|
||||
rpm -Kv "$rpm_file"
|
||||
|
||||
# Validate code signing
|
||||
if ! rpm -K "$rpm_file" | grep -q "digests signatures OK"; then
|
||||
echo .rpm file not signed
|
||||
exit 1
|
||||
fi
|
||||
33
.github/actions/build-server/action.yml
vendored
33
.github/actions/build-server/action.yml
vendored
@@ -1,33 +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:
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run Linux server build
|
||||
env:
|
||||
MATRIX_ARCH: ${{ inputs.arch }}
|
||||
shell: bash
|
||||
run: |
|
||||
pnpm run chore:update-build-info
|
||||
pnpm run --filter server package
|
||||
- name: Prepare artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p upload
|
||||
file=$(find ./apps/server/out -name '*.tar.xz' -print -quit)
|
||||
name=${{ github.ref_name }}
|
||||
cp "$file" "upload/TriliumNotes-Server-${name//\//-}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"
|
||||
@@ -1,103 +0,0 @@
|
||||
name: "Deploy to Cloudflare Pages"
|
||||
description: "Deploys to Cloudflare Pages on either a temporary branch with preview comment, or on the production version if on the main branch."
|
||||
inputs:
|
||||
project_name:
|
||||
description: "CloudFlare Pages project name"
|
||||
comment_body:
|
||||
description: "The message to display when deployment is ready"
|
||||
default: "Deployment is ready."
|
||||
required: false
|
||||
production_url:
|
||||
description: "The URL to mention as the production URL."
|
||||
required: true
|
||||
deploy_dir:
|
||||
description: "The directory from which to deploy."
|
||||
required: true
|
||||
cloudflare_api_token:
|
||||
description: "The Cloudflare API token to use for deployment."
|
||||
required: true
|
||||
cloudflare_account_id:
|
||||
description: "The Cloudflare account ID to use for deployment."
|
||||
required: true
|
||||
github_token:
|
||||
description: "The GitHub token to use for posting PR comments."
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# Install wrangler globally to avoid workspace issues
|
||||
- name: Install Wrangler
|
||||
shell: bash
|
||||
run: npm install -g wrangler
|
||||
|
||||
# Deploy using Wrangler (use pre-installed wrangler)
|
||||
- name: Deploy to Cloudflare Pages
|
||||
id: deploy
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ inputs.cloudflare_api_token }}
|
||||
accountId: ${{ inputs.cloudflare_account_id }}
|
||||
command: pages deploy ${{ inputs.deploy_dir }} --project-name=${{ inputs.project_name}} --branch=${{ github.ref_name }}
|
||||
wranglerVersion: '' # Use pre-installed version
|
||||
|
||||
# Deploy preview for PRs
|
||||
- name: Deploy Preview to Cloudflare Pages
|
||||
id: preview-deployment
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ inputs.cloudflare_api_token }}
|
||||
accountId: ${{ inputs.cloudflare_account_id }}
|
||||
command: pages deploy ${{ inputs.deploy_dir }} --project-name=${{ inputs.project_name}} --branch=pr-${{ github.event.pull_request.number }}
|
||||
wranglerVersion: '' # Use pre-installed version
|
||||
|
||||
# Post deployment URL as PR comment
|
||||
- name: Comment PR with Preview URL
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
COMMENT_BODY: ${{ inputs.comment_body }}
|
||||
PRODUCTION_URL: ${{ inputs.production_url }}
|
||||
PROJECT_NAME: ${{ inputs.project_name }}
|
||||
with:
|
||||
github-token: ${{ inputs.github_token }}
|
||||
script: |
|
||||
const prNumber = context.issue.number;
|
||||
// Construct preview URL based on Cloudflare Pages pattern
|
||||
const projectName = process.env.PROJECT_NAME;
|
||||
const previewUrl = `https://pr-${prNumber}.${projectName}.pages.dev`;
|
||||
|
||||
// Check if we already commented
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber
|
||||
});
|
||||
|
||||
const customMessage = process.env.COMMENT_BODY;
|
||||
const botComment = comments.data.find(comment =>
|
||||
comment.user.type === 'Bot' &&
|
||||
comment.body.includes(customMessage)
|
||||
);
|
||||
|
||||
const mainUrl = process.env.PRODUCTION_URL;
|
||||
const commentBody = `${customMessage}!\n\n🔗 Preview URL: ${previewUrl}\n📖 Production URL: ${mainUrl}\n\n✅ All checks passed\n\n_This preview will be updated automatically with new commits._`;
|
||||
|
||||
if (botComment) {
|
||||
// Update existing comment
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: botComment.id,
|
||||
body: commentBody
|
||||
});
|
||||
} else {
|
||||
// Create new comment
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: prNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: commentBody
|
||||
});
|
||||
}
|
||||
79
.github/actions/report-size/action.yml
vendored
79
.github/actions/report-size/action.yml
vendored
@@ -1,79 +0,0 @@
|
||||
name: 'Bundle size reporter'
|
||||
description: 'Post bundle size difference compared to another branch'
|
||||
inputs:
|
||||
branch:
|
||||
description: 'Branch to compare to'
|
||||
required: true
|
||||
default: 'main'
|
||||
paths:
|
||||
description:
|
||||
'Paths to json file bundle size report or folder containing bundles'
|
||||
required: true
|
||||
default: '/'
|
||||
onlyDiff:
|
||||
description: 'Report only different sizes'
|
||||
required: false
|
||||
default: 'false'
|
||||
filter:
|
||||
description: 'Regex filter based on file path'
|
||||
required: false
|
||||
unit:
|
||||
description: 'Size unit'
|
||||
required: false
|
||||
default: 'KB'
|
||||
|
||||
# Comment inputs
|
||||
comment:
|
||||
description: 'Post comment'
|
||||
required: false
|
||||
default: 'true'
|
||||
header:
|
||||
description: 'Comment header'
|
||||
required: false
|
||||
default: 'Bundle size report'
|
||||
append:
|
||||
description: 'Append comment'
|
||||
required: false
|
||||
default: 'false'
|
||||
ghToken:
|
||||
description: 'Github token'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# Checkout branch to compare to [required]
|
||||
- name: Checkout base branch
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
path: br-base
|
||||
token: ${{ inputs.ghToken }}
|
||||
|
||||
# Generate the bundle size difference report [required]
|
||||
- name: Generate report
|
||||
id: bundleSize
|
||||
uses: nejcm/bundle-size-reporter-action@v1.4.1
|
||||
with:
|
||||
paths: ${{ inputs.paths }}
|
||||
onlyDiff: ${{ inputs.onlyDiff }}
|
||||
filter: ${{ inputs.filter }}
|
||||
unit: ${{ inputs.unit }}
|
||||
|
||||
# Post github action summary
|
||||
- name: Post summary
|
||||
if: ${{ steps.bundleSize.outputs.hasDifferences == 'true' }} # post only in case of changes
|
||||
run: |
|
||||
echo '${{ steps.bundleSize.outputs.summary }}' >> $GITHUB_STEP_SUMMARY
|
||||
shell: bash
|
||||
|
||||
# Post github action comment
|
||||
- name: Post comment
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
if: ${{ steps.bundleSize.outputs.hasDifferences == 'true' }} # post only in case of changes
|
||||
with:
|
||||
number: ${{ github.event.pull_request.number }}
|
||||
header: ${{ inputs.header }}
|
||||
append: ${{ inputs.append }}
|
||||
message: '${{ steps.bundleSize.outputs.summary }}'
|
||||
GITHUB_TOKEN: ${{ inputs.ghToken }}
|
||||
334
.github/copilot-instructions.md
vendored
334
.github/copilot-instructions.md
vendored
@@ -1,334 +0,0 @@
|
||||
# Trilium Notes - AI Coding Agent Instructions
|
||||
|
||||
## Project Overview
|
||||
|
||||
Trilium Notes is a hierarchical note-taking application with advanced features like synchronization, scripting, and rich text editing. Built as a TypeScript monorepo using pnpm, it implements a three-layer caching architecture (Becca/Froca/Shaca) with a widget-based UI system and supports extensive user scripting capabilities.
|
||||
|
||||
## Essential Architecture Patterns
|
||||
|
||||
### Three-Layer Cache System (Critical to Understand)
|
||||
- **Becca** (`apps/server/src/becca/`): Server-side entity cache, primary data source
|
||||
- **Froca** (`apps/client/src/services/froca.ts`): Client-side mirror synchronized via WebSocket
|
||||
- **Shaca** (`apps/server/src/share/`): Optimized cache for public/shared notes
|
||||
|
||||
**Key insight**: Never bypass these caches with direct DB queries. Always use `becca.notes[noteId]`, `froca.getNote()`, or equivalent cache methods.
|
||||
|
||||
### Entity Relationship Model
|
||||
Notes use a **multi-parent tree** via branches:
|
||||
- `BNote` - The note content and metadata
|
||||
- `BBranch` - Tree relationships (one note can have multiple parents via cloning)
|
||||
- `BAttribute` - Key-value metadata attached to notes (labels and relations)
|
||||
|
||||
### Entity Change System & Sync
|
||||
Every entity modification (notes, branches, attributes) creates an `EntityChange` record that drives synchronization:
|
||||
|
||||
```typescript
|
||||
// Entity changes are automatically tracked
|
||||
note.title = "New Title";
|
||||
note.save(); // Creates EntityChange record with changeId
|
||||
|
||||
// Sync protocol via WebSocket
|
||||
ws.sendMessage({ type: 'sync-pull-in-progress', ... });
|
||||
```
|
||||
|
||||
**Critical**: This is why you must use Becca/Froca methods instead of direct DB writes - they create the change tracking records needed for sync.
|
||||
|
||||
### Entity Lifecycle & Events
|
||||
The event system (`apps/server/src/services/events.ts`) broadcasts entity lifecycle events:
|
||||
|
||||
```typescript
|
||||
// Subscribe to events in widgets or services
|
||||
eventService.subscribe('noteChanged', ({ noteId }) => {
|
||||
// React to note changes
|
||||
});
|
||||
|
||||
// Common events: noteChanged, branchChanged, attributeChanged, noteDeleted
|
||||
// Widget method: entitiesReloadedEvent({loadResults}) for handling reloads
|
||||
```
|
||||
|
||||
**Becca loader priorities**: Events are emitted in order (notes → branches → attributes) during initial load to ensure referential integrity.
|
||||
|
||||
### TaskContext for Long Operations
|
||||
Use `TaskContext` for operations with progress reporting (imports, exports, bulk operations):
|
||||
|
||||
```typescript
|
||||
const taskContext = new TaskContext("task-id", "import", "Import Notes");
|
||||
taskContext.increaseProgressCount();
|
||||
|
||||
// WebSocket messages: { type: 'taskProgressCount', taskId, taskType, data, progressCount }
|
||||
|
||||
**Pattern**: All long-running operations (delete note trees, export, import) use TaskContext to send WebSocket updates to the frontend.
|
||||
|
||||
### Protected Session Handling
|
||||
Protected notes require an active encryption session:
|
||||
|
||||
```typescript
|
||||
// Always check before accessing protected content
|
||||
if (note.isContentAvailable()) {
|
||||
const content = note.getContent(); // Safe
|
||||
} else {
|
||||
const title = note.getTitleOrProtected(); // Returns "[protected]"
|
||||
}
|
||||
|
||||
// Protected session management
|
||||
protectedSessionService.isProtectedSessionAvailable() // Check session
|
||||
protectedSessionService.startProtectedSession() // After password entry
|
||||
```
|
||||
|
||||
**Session timeout**: Protected sessions expire after inactivity. The encryption key is kept in memory only.
|
||||
|
||||
### Attribute Inheritance Patterns
|
||||
Attributes can be inherited through three mechanisms:
|
||||
|
||||
```typescript
|
||||
// 1. Standard inheritance (#hidePromotedAttributes ~hidePromotedAttributes)
|
||||
note.getInheritableAttributes() // Walks up parent tree
|
||||
|
||||
// 2. Child prefix inheritance (child:label copies to children)
|
||||
parentNote.setLabel("child:icon", "book") // All children inherit this
|
||||
|
||||
// 3. Template relation inheritance (#template=templateNoteId)
|
||||
note.setRelation("template", templateNoteId)
|
||||
note.getInheritedAttributes() // Includes template's inheritable attributes
|
||||
```
|
||||
|
||||
**Cycle prevention**: Inheritance tracking prevents infinite loops when notes reference each other.
|
||||
|
||||
### Widget-Based UI Architecture
|
||||
All UI components extend from widget base classes (`apps/client/src/widgets/`):
|
||||
|
||||
```typescript
|
||||
// Right panel widget (sidebar)
|
||||
class MyWidget extends RightPanelWidget {
|
||||
get position() { return 100; } // Order in panel
|
||||
get parentWidget() { return 'right-pane'; }
|
||||
isEnabled() { return this.note && this.note.hasLabel('myLabel'); }
|
||||
async refreshWithNote(note) { /* Update UI */ }
|
||||
}
|
||||
|
||||
// Note-aware widget (responds to note changes)
|
||||
class MyNoteWidget extends NoteContextAwareWidget {
|
||||
async refreshWithNote(note) { /* Refresh when note changes */ }
|
||||
async entitiesReloadedEvent({loadResults}) { /* Handle entity updates */ }
|
||||
}
|
||||
```
|
||||
|
||||
**Important**: Widgets use jQuery (`this.$widget`) for DOM manipulation. Don't mix React patterns here.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Running & Testing
|
||||
```bash
|
||||
# From root directory
|
||||
pnpm install # Install dependencies
|
||||
corepack enable # Enable pnpm if not available
|
||||
pnpm server:start # Dev server (http://localhost:8080)
|
||||
pnpm server:start-prod # Production mode server
|
||||
pnpm desktop:start # Desktop app development
|
||||
pnpm server:test spec/etapi/search.spec.ts # Run specific test
|
||||
pnpm test:parallel # Client tests (can run parallel)
|
||||
pnpm test:sequential # Server tests (sequential due to shared DB)
|
||||
pnpm test:all # All tests (parallel + sequential)
|
||||
pnpm coverage # Generate coverage reports
|
||||
pnpm typecheck # Type check all projects
|
||||
```
|
||||
|
||||
### Building
|
||||
```bash
|
||||
pnpm client:build # Build client application
|
||||
pnpm server:build # Build server application
|
||||
pnpm desktop:build # Build desktop application
|
||||
```
|
||||
|
||||
### Test Organization
|
||||
- **Server tests** (`apps/server/spec/`): Must run sequentially (shared database state)
|
||||
- **Client tests** (`apps/client/src/`): Can run in parallel
|
||||
- **E2E tests** (`apps/server-e2e/`): Use Playwright for integration testing
|
||||
- **ETAPI tests** (`apps/server/spec/etapi/`): External API contract tests
|
||||
|
||||
**Pattern**: When adding new API endpoints, add tests in `spec/etapi/` following existing patterns (see `search.spec.ts`).
|
||||
|
||||
### Monorepo Navigation
|
||||
```
|
||||
apps/
|
||||
client/ # Frontend (shared by server & desktop)
|
||||
server/ # Node.js backend with REST API
|
||||
desktop/ # Electron wrapper
|
||||
web-clipper/ # Browser extension for saving web content
|
||||
db-compare/ # Database comparison tool
|
||||
dump-db/ # Database export utility
|
||||
edit-docs/ # Documentation editing tools
|
||||
packages/
|
||||
commons/ # Shared types and utilities
|
||||
ckeditor5/ # Custom rich text editor with Trilium-specific plugins
|
||||
codemirror/ # Code editor integration
|
||||
highlightjs/ # Syntax highlighting
|
||||
share-theme/ # Theme for shared/published notes
|
||||
ckeditor5-admonition/ # Admonition blocks plugin
|
||||
ckeditor5-footnotes/ # Footnotes plugin
|
||||
ckeditor5-math/ # Math equations plugin
|
||||
ckeditor5-mermaid/ # Mermaid diagrams plugin
|
||||
```
|
||||
|
||||
**Filter commands**: Use `pnpm --filter server test` to run commands in specific packages.
|
||||
|
||||
## Critical Code Patterns
|
||||
|
||||
### ETAPI Backwards Compatibility
|
||||
When adding query parameters to ETAPI endpoints (`apps/server/src/etapi/`), maintain backwards compatibility by checking if new params exist before changing response format.
|
||||
|
||||
**Pattern**: ETAPI consumers expect specific response shapes. Always check for breaking changes.
|
||||
|
||||
### Frontend-Backend Communication
|
||||
- **REST API**: `apps/server/src/routes/api/` - Internal endpoints (no auth required when `noAuthentication=true`)
|
||||
- **ETAPI**: `apps/server/src/etapi/` - External API with authentication
|
||||
- **WebSocket**: Real-time sync via `apps/server/src/services/ws.ts`
|
||||
|
||||
**Auth note**: ETAPI uses basic auth with tokens. Internal API endpoints trust the frontend.
|
||||
|
||||
### Database Migrations
|
||||
- Add scripts in `apps/server/src/migrations/YYMMDD_HHMM__description.sql`
|
||||
- Update schema in `apps/server/src/assets/db/schema.sql`
|
||||
- Never bypass Becca cache after migrations
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Never bypass the cache layers** - Always use `becca.notes[noteId]`, `froca.getNote()`, or equivalent cache methods. Direct database queries will cause sync issues between Becca/Froca/Shaca and won't create EntityChange records needed for synchronization.
|
||||
|
||||
2. **Protected notes require session check** - Before accessing `note.title` or `note.getContent()` on protected notes, check `note.isContentAvailable()` or use `note.getTitleOrProtected()` which handles this automatically.
|
||||
|
||||
3. **Widget lifecycle matters** - Override `refreshWithNote()` for note changes, `doRenderBody()` for initial render, `entitiesReloadedEvent()` for entity updates. Widgets use jQuery (`this.$widget`) - don't mix React patterns.
|
||||
|
||||
4. **Tests run differently** - Server tests must run sequentially (shared database state), client tests can run in parallel. Use `pnpm test:sequential` for backend, `pnpm test:parallel` for frontend.
|
||||
|
||||
5. **ETAPI requires authentication** - ETAPI endpoints use basic auth with tokens. Internal API endpoints (`apps/server/src/routes/api/`) trust the frontend when `noAuthentication=true`.
|
||||
|
||||
6. **Search expressions are evaluated in memory** - The search service loads all matching notes, scores them in JavaScript, then sorts. You cannot add SQL-level LIMIT/OFFSET without losing scoring functionality.
|
||||
|
||||
7. **Documentation edits have rules** - `docs/Script API/` is auto-generated (never edit directly). `docs/User Guide/` should be edited via `pnpm edit-docs:edit-docs`, not manually. Only `docs/Developer Guide/` and `docs/Release Notes/` are safe for direct Markdown editing.
|
||||
|
||||
8. **pnpm workspace filtering** - Use `pnpm --filter server <command>` or shorthand `pnpm server:test` defined in root `package.json`. Note the `--filter` syntax, not `-F` or other shortcuts.
|
||||
|
||||
9. **Event subscription cleanup** - When subscribing to events in widgets, unsubscribe in `cleanup()` or `doDestroy()` to prevent memory leaks.
|
||||
|
||||
10. **Attribute inheritance can be complex** - When checking for labels/relations, use `note.getOwnedAttribute()` for direct attributes or `note.getAttribute()` for inherited ones. Don't assume attributes are directly on the note.
|
||||
|
||||
## TypeScript Configuration
|
||||
|
||||
- **Project references**: Monorepo uses TypeScript project references (`tsconfig.json`)
|
||||
- **Path mapping**: Use relative imports, not path aliases
|
||||
- **Build order**: `pnpm typecheck` builds all projects in dependency order
|
||||
- **Build system**: Uses Vite for fast development, ESBuild for production optimization
|
||||
- **Patches**: Custom patches in `patches/` directory for CKEditor and other dependencies
|
||||
|
||||
## Key Files for Context
|
||||
|
||||
- `apps/server/src/becca/entities/bnote.ts` - Note entity methods
|
||||
- `apps/client/src/services/froca.ts` - Frontend cache API
|
||||
- `apps/server/src/services/search/services/search.ts` - Search implementation
|
||||
- `apps/server/src/routes/routes.ts` - API route registration
|
||||
- `apps/client/src/widgets/basic_widget.ts` - Widget base class
|
||||
- `apps/server/src/main.ts` - Server startup entry point
|
||||
- `apps/client/src/desktop.ts` - Client initialization
|
||||
- `apps/server/src/services/backend_script_api.ts` - Scripting API
|
||||
- `apps/server/src/assets/db/schema.sql` - Database schema
|
||||
|
||||
## Note Types and Features
|
||||
|
||||
Trilium supports multiple note types with specialized widgets in `apps/client/src/widgets/type_widgets/`:
|
||||
- **Text**: Rich text with CKEditor5 (markdown import/export)
|
||||
- **Code**: Syntax-highlighted code editing with CodeMirror
|
||||
- **File**: Binary file attachments
|
||||
- **Image**: Image display with editing capabilities
|
||||
- **Canvas**: Drawing/diagramming with Excalidraw
|
||||
- **Mermaid**: Diagram generation
|
||||
- **Relation Map**: Visual note relationship mapping
|
||||
- **Web View**: Embedded web pages
|
||||
- **Doc/Book**: Hierarchical documentation structure
|
||||
|
||||
### Collections
|
||||
Notes can be marked with the `#collection` label to enable collection view modes. Collections support multiple view types:
|
||||
- **List**: Standard list view
|
||||
- **Grid**: Card/grid layout
|
||||
- **Calendar**: Calendar-based view
|
||||
- **Table**: Tabular data view
|
||||
- **GeoMap**: Geographic map view
|
||||
- **Board**: Kanban-style board
|
||||
- **Presentation**: Slideshow presentation mode
|
||||
|
||||
View types are configured via `#viewType` label (e.g., `#viewType=table`). Each view mode stores its configuration in a separate attachment (e.g., `table.json`). Collections are organized separately from regular note type templates in the note creation menu.
|
||||
|
||||
## Common Development Tasks
|
||||
|
||||
### Adding New Note Types
|
||||
1. Create widget in `apps/client/src/widgets/type_widgets/`
|
||||
2. Register in `apps/client/src/services/note_types.ts`
|
||||
3. Add backend handling in `apps/server/src/services/notes.ts`
|
||||
|
||||
### Extending Search
|
||||
- Search expressions handled in `apps/server/src/services/search/`
|
||||
- Add new search operators in search context files
|
||||
- Remember: scoring happens in-memory, not at database level
|
||||
|
||||
### Custom CKEditor Plugins
|
||||
- Create new package in `packages/` following existing plugin structure
|
||||
- Register in `packages/ckeditor5/src/plugins.ts`
|
||||
- See `ckeditor5-admonition`, `ckeditor5-footnotes`, `ckeditor5-math`, `ckeditor5-mermaid` for examples
|
||||
|
||||
### Database Migrations
|
||||
- Add migration scripts in `apps/server/src/migrations/YYMMDD_HHMM__description.sql`
|
||||
- Update schema in `apps/server/src/assets/db/schema.sql`
|
||||
- Never bypass Becca cache after migrations
|
||||
|
||||
## Security & Features
|
||||
|
||||
### Security Considerations
|
||||
- Per-note encryption with granular protected sessions
|
||||
- CSRF protection for API endpoints
|
||||
- OpenID and TOTP authentication support
|
||||
- Sanitization of user-generated content
|
||||
|
||||
### Scripting System
|
||||
Trilium provides powerful user scripting capabilities:
|
||||
- **Frontend scripts**: Run in browser context with UI access
|
||||
- **Backend scripts**: Run in Node.js context with full API access
|
||||
- Script API documentation in `docs/Script API/`
|
||||
- Backend API available via `api` object in script context
|
||||
|
||||
### Internationalization
|
||||
- Translation files in `apps/client/src/translations/`
|
||||
- Use translation system via `t()` function
|
||||
- Automatic pluralization: Add `_other` suffix to translation keys (e.g., `item` and `item_other` for singular/plural)
|
||||
|
||||
## Testing Conventions
|
||||
|
||||
```typescript
|
||||
// ETAPI test pattern
|
||||
describe("etapi/feature", () => {
|
||||
beforeAll(async () => {
|
||||
config.General.noAuthentication = false;
|
||||
app = await buildApp();
|
||||
token = await login(app);
|
||||
});
|
||||
|
||||
it("should test feature", async () => {
|
||||
const response = await supertest(app)
|
||||
.get("/etapi/notes?search=test")
|
||||
.auth(USER, token, { type: "basic" })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.results).toBeDefined();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Questions to Verify Understanding
|
||||
|
||||
Before implementing significant changes, confirm:
|
||||
- Is this touching the cache layer? (Becca/Froca/Shaca must stay in sync via EntityChange records)
|
||||
- Does this change API response shape? (Check backwards compatibility for ETAPI)
|
||||
- Are you adding search features? (Understand expression-based architecture and in-memory scoring first)
|
||||
- Is this a new widget? (Know which base class and lifecycle methods to use)
|
||||
- Does this involve protected notes? (Check `isContentAvailable()` before accessing content)
|
||||
- Is this a long-running operation? (Use TaskContext for progress reporting)
|
||||
- Are you working with attributes? (Understand inheritance patterns: direct, child-prefix, template)
|
||||
18
.github/workflows/checks.yml
vendored
18
.github/workflows/checks.yml
vendored
@@ -1,18 +0,0 @@
|
||||
name: Checks
|
||||
on:
|
||||
push:
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Check if PRs have conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@v3
|
||||
if: github.repository == ${{ vars.REPO_MAIN }}
|
||||
with:
|
||||
dirtyLabel: "merge-conflicts"
|
||||
repoToken: "${{ secrets.MERGE_CONFLICT_LABEL_PAT }}"
|
||||
100
.github/workflows/codeql.yml
vendored
100
.github/workflows/codeql.yml
vendored
@@ -1,100 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL Advanced"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '20 7 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: actions
|
||||
build-mode: none
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||
# or others). This is typically only required for manual builds.
|
||||
# - name: Setup runtime (example)
|
||||
# uses: actions/setup-example@v1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
78
.github/workflows/deploy-docs.yml
vendored
78
.github/workflows/deploy-docs.yml
vendored
@@ -1,78 +0,0 @@
|
||||
name: Deploy Documentation
|
||||
|
||||
on:
|
||||
# Trigger on push to main branch
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master # Also support master branch
|
||||
# Only run when docs files change
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'apps/edit-docs/**'
|
||||
- 'apps/build-docs/**'
|
||||
- 'packages/share-theme/**'
|
||||
|
||||
# Allow manual triggering from Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Run on pull requests for preview deployments
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'apps/edit-docs/**'
|
||||
- 'apps/build-docs/**'
|
||||
- 'packages/share-theme/**'
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
name: Build and Deploy Documentation
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
# Required permissions for deployment
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write # For PR preview comments
|
||||
id-token: write # For OIDC authentication (if needed)
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Trigger build of documentation
|
||||
run: pnpm docs:build
|
||||
|
||||
- name: Validate Built Site
|
||||
run: |
|
||||
test -f site/index.html || (echo "ERROR: site/index.html not found" && exit 1)
|
||||
test -f site/developer-guide/index.html || (echo "ERROR: site/developer-guide/index.html not found" && exit 1)
|
||||
echo "✓ User Guide and Developer Guide built successfully"
|
||||
|
||||
- name: Deploy
|
||||
uses: ./.github/actions/deploy-to-cloudflare-pages
|
||||
if: github.repository == ${{ vars.REPO_MAIN }}
|
||||
with:
|
||||
project_name: "trilium-docs"
|
||||
comment_body: "📚 Documentation preview is ready"
|
||||
production_url: "https://docs.triliumnotes.org"
|
||||
deploy_dir: "site"
|
||||
cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
98
.github/workflows/dev.yml
vendored
98
.github/workflows/dev.yml
vendored
@@ -1,9 +1,9 @@
|
||||
name: Dev
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches-ignore:
|
||||
- 'develop'
|
||||
- 'feature/update**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -12,11 +12,8 @@ concurrency:
|
||||
env:
|
||||
GHCR_REGISTRY: ghcr.io
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: ${{ github.repository}}
|
||||
TEST_TAG: ${{ github.repository}}:test
|
||||
|
||||
permissions:
|
||||
pull-requests: write # for PR comments
|
||||
IMAGE_NAME: ${{ github.repository_owner }}/notes
|
||||
TEST_TAG: ${{ github.repository_owner }}/notes:test
|
||||
|
||||
jobs:
|
||||
test_dev:
|
||||
@@ -24,50 +21,41 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: "pnpm"
|
||||
- run: pnpm install --frozen-lockfile
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm typecheck
|
||||
|
||||
- name: Run the unit tests
|
||||
run: pnpm run test:all
|
||||
- run: npm ci
|
||||
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
build_docker:
|
||||
name: Build Docker image
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- test_dev
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Update build info
|
||||
run: pnpm run chore:update-build-info
|
||||
- name: Trigger client build
|
||||
run: pnpm client:build
|
||||
- name: Send client bundle stats to RelativeCI
|
||||
if: false
|
||||
uses: relative-ci/agent-action@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
webpackStatsFile: ./apps/client/dist/webpack-stats.json
|
||||
key: ${{ secrets.RELATIVE_CI_CLIENT_KEY }}
|
||||
- name: Trigger server build
|
||||
run: pnpm run server:build
|
||||
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
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: apps/server
|
||||
context: .
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-to: type=gha,mode=max
|
||||
test_docker:
|
||||
name: Check Docker build
|
||||
runs-on: ubuntu-latest
|
||||
@@ -80,17 +68,8 @@ jobs:
|
||||
- dockerfile: Dockerfile
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Update build info
|
||||
run: pnpm run chore:update-build-info
|
||||
- name: Trigger build
|
||||
run: pnpm server:build
|
||||
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set IMAGE_NAME to lowercase
|
||||
run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV
|
||||
- name: Set TEST_TAG to lowercase
|
||||
@@ -99,21 +78,35 @@ jobs:
|
||||
- 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: Build and export to Docker
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: apps/server
|
||||
file: apps/server/${{ matrix.dockerfile }}
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
load: true
|
||||
tags: ${{ env.TEST_TAG }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
- name: Validate container run output
|
||||
run: |
|
||||
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --name trilium_local ${{ env.TEST_TAG }})
|
||||
echo "Container ID: $CONTAINER_ID"
|
||||
|
||||
|
||||
- name: Wait for the healthchecks to pass
|
||||
uses: stringbean/docker-healthcheck-action@v3
|
||||
with:
|
||||
@@ -125,4 +118,5 @@ jobs:
|
||||
# Print the entire log of the container thus far, regardless if the healthcheck failed or succeeded
|
||||
- name: Print entire log
|
||||
if: always()
|
||||
run: journalctl -u docker CONTAINER_NAME=trilium_local --no-pager
|
||||
run: |
|
||||
journalctl -u docker CONTAINER_NAME=trilium_local --no-pager
|
||||
|
||||
159
.github/workflows/main-docker.yml
vendored
159
.github/workflows/main-docker.yml
vendored
@@ -1,7 +1,7 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "develop"
|
||||
- "feature/update**"
|
||||
- "feature/server_esm**"
|
||||
paths-ignore:
|
||||
@@ -14,8 +14,8 @@ on:
|
||||
env:
|
||||
GHCR_REGISTRY: ghcr.io
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: ${{ github.repository}}
|
||||
TEST_TAG: ${{ github.repository}}:test
|
||||
IMAGE_NAME: ${{ github.repository_owner }}/notes
|
||||
TEST_TAG: ${{ github.repository_owner }}/notes:test
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -32,8 +32,8 @@ jobs:
|
||||
- dockerfile: Dockerfile
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set IMAGE_NAME to lowercase
|
||||
run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV
|
||||
- name: Set TEST_TAG to lowercase
|
||||
@@ -42,37 +42,39 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: "pnpm"
|
||||
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: npm ci
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install --with-deps
|
||||
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Run the TypeScript build
|
||||
run: pnpm run server: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: apps/server
|
||||
file: apps/server/${{ matrix.dockerfile }}
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
load: true
|
||||
tags: ${{ env.TEST_TAG }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
- name: Validate container run output
|
||||
run: |
|
||||
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --network=host -e TRILIUM_PORT=8082 --volume ./apps/server/spec/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"
|
||||
|
||||
|
||||
- name: Wait for the healthchecks to pass
|
||||
uses: stringbean/docker-healthcheck-action@v3
|
||||
with:
|
||||
@@ -80,18 +82,10 @@ jobs:
|
||||
wait-time: 50
|
||||
require-status: running
|
||||
require-healthy: true
|
||||
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpm --filter=server-e2e e2e
|
||||
|
||||
- name: Upload Playwright trace
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: Playwright trace (${{ matrix.dockerfile }})
|
||||
path: test-output/playwright/output
|
||||
|
||||
- uses: actions/upload-artifact@v5
|
||||
run: TRILIUM_DOCKER=1 npx playwright test
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: Playwright report (${{ matrix.dockerfile }})
|
||||
@@ -106,23 +100,7 @@ jobs:
|
||||
|
||||
build:
|
||||
name: Build Docker images
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- dockerfile: Dockerfile.alpine
|
||||
platform: linux/amd64
|
||||
image: ubuntu-latest
|
||||
- dockerfile: Dockerfile
|
||||
platform: linux/arm64
|
||||
image: ubuntu-24.04-arm
|
||||
- dockerfile: Dockerfile.legacy
|
||||
platform: linux/arm/v7
|
||||
image: ubuntu-24.04-arm
|
||||
- dockerfile: Dockerfile.legacy
|
||||
platform: linux/arm/v8
|
||||
image: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.image }}
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- test_docker
|
||||
permissions:
|
||||
@@ -130,6 +108,16 @@ jobs:
|
||||
packages: write
|
||||
attestations: 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:
|
||||
- name: Prepare
|
||||
run: |
|
||||
@@ -140,28 +128,9 @@ jobs:
|
||||
- name: Set TEST_TAG to lowercase
|
||||
run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Update build info
|
||||
run: pnpm run chore:update-build-info
|
||||
|
||||
- name: Update nightly version
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: pnpm run chore:ci-update-nightly-version
|
||||
|
||||
- name: Run the TypeScript build
|
||||
run: pnpm run server:build
|
||||
|
||||
uses: actions/checkout@v4
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -175,12 +144,24 @@ jobs:
|
||||
type=sha
|
||||
flavor: |
|
||||
latest=false
|
||||
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-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: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
@@ -188,34 +169,34 @@ jobs:
|
||||
registry: ${{ env.GHCR_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.DOCKERHUB_REGISTRY }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: apps/server
|
||||
file: apps/server/${{ matrix.dockerfile }}
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}-${{ matrix.dockerfile }}
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
@@ -227,7 +208,7 @@ jobs:
|
||||
- build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
@@ -239,7 +220,7 @@ jobs:
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -256,14 +237,14 @@ jobs:
|
||||
registry: ${{ env.GHCR_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.DOCKERHUB_REGISTRY }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
@@ -274,7 +255,7 @@ jobs:
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \
|
||||
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
|
||||
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \
|
||||
$(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
@@ -286,25 +267,25 @@ jobs:
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \
|
||||
$(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
|
||||
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \
|
||||
$(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
|
||||
|
||||
# Small delay to ensure stable tag is fully propagated
|
||||
sleep 5
|
||||
|
||||
|
||||
# Now update latest tags
|
||||
docker buildx imagetools create \
|
||||
-t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
|
||||
${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable
|
||||
|
||||
|
||||
docker buildx imagetools create \
|
||||
-t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
|
||||
${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
|
||||
|
||||
100
.github/workflows/main.yml
vendored
Normal file
100
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: Main
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "feature/update**"
|
||||
- "feature/server_esm**"
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- ".github/workflows/main-docker.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
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
|
||||
- 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: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.zip
|
||||
path: upload/*.zip
|
||||
- name: Publish installer artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
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
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
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
|
||||
with:
|
||||
name: TriliumNextNotes linux server x64
|
||||
path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz
|
||||
204
.github/workflows/nightly.yml
vendored
204
.github/workflows/nightly.yml
vendored
@@ -2,32 +2,17 @@ name: Nightly Release
|
||||
on:
|
||||
# This can be used to automatically publish nightlies at UTC nighttime
|
||||
schedule:
|
||||
- cron: "0 2 * * *" # run at 2 AM UTC
|
||||
- cron: '0 2 * * *' # run at 2 AM UTC
|
||||
# This can be used to allow manually triggering nightlies from the web interface
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- renovate/electron-forge*
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/actions/build-electron/*
|
||||
- .github/workflows/nightly.yml
|
||||
- forge.config.ts
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
GITHUB_UPLOAD_URL: https://uploads.github.com/repos/TriliumNext/Notes/releases/179589950/assets{?name,label}
|
||||
GITHUB_RELEASE_ID: 179589950
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
nightly-electron:
|
||||
if: github.repository == ${{ vars.REPO_MAIN }}
|
||||
name: Deploy nightly
|
||||
name: Deploy nightly
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -35,109 +20,110 @@ jobs:
|
||||
os:
|
||||
- name: macos
|
||||
image: macos-latest
|
||||
shell: bash
|
||||
forge_platform: darwin
|
||||
extension: dmg
|
||||
- name: linux
|
||||
image: ubuntu-22.04
|
||||
shell: bash
|
||||
forge_platform: linux
|
||||
image: ubuntu-latest
|
||||
extension: deb
|
||||
- name: windows
|
||||
image: win-signing
|
||||
shell: cmd
|
||||
forge_platform: win32
|
||||
# Exclude ARM64 Linux from default matrix to use native runner
|
||||
exclude:
|
||||
- arch: arm64
|
||||
os:
|
||||
name: linux
|
||||
# Add ARM64 Linux with native ubuntu-24.04-arm runner for better-sqlite3 compatibility
|
||||
include:
|
||||
- arch: arm64
|
||||
os:
|
||||
name: linux
|
||||
image: ubuntu-24.04-arm
|
||||
shell: bash
|
||||
forge_platform: linux
|
||||
runs-on: ${{ matrix.os.image }}
|
||||
image: windows-latest
|
||||
extension: exe
|
||||
runs-on: ${{ matrix.os.image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'pnpm'
|
||||
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
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: npm ci
|
||||
- name: Update build info
|
||||
run: npm run update-build-info
|
||||
- name: Update nightly version
|
||||
run: pnpm run chore:ci-update-nightly-version
|
||||
- name: Run the build
|
||||
uses: ./.github/actions/build-electron
|
||||
with:
|
||||
os: ${{ matrix.os.name }}
|
||||
arch: ${{ matrix.arch }}
|
||||
shell: ${{ matrix.os.shell }}
|
||||
forge_platform: ${{ matrix.os.forge_platform }}
|
||||
env:
|
||||
APPLE_APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_CERTIFICATE_BASE64 }}
|
||||
APPLE_APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_APP_CERTIFICATE_PASSWORD }}
|
||||
APPLE_INSTALLER_CERTIFICATE_BASE64: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
|
||||
APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }}
|
||||
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
|
||||
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@v2.4.2
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
make_latest: false
|
||||
prerelease: true
|
||||
draft: false
|
||||
fail_on_unmatched_files: true
|
||||
files: apps/desktop/upload/*.*
|
||||
tag_name: nightly
|
||||
name: Nightly Build
|
||||
|
||||
run: npm run ci-update-nightly-version
|
||||
- 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 }}.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@v5
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }}
|
||||
path: apps/desktop/upload
|
||||
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
|
||||
path: upload/*.zip
|
||||
overwrite: true
|
||||
- name: Publish installer artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
|
||||
path: upload/*.${{ matrix.os.extension }}
|
||||
overwrite: true
|
||||
|
||||
- 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:
|
||||
if: github.repository == ${{ vars.REPO_MAIN }}
|
||||
name: Deploy server nightly
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [x64, arm64]
|
||||
include:
|
||||
- arch: x64
|
||||
runs-on: ubuntu-22.04
|
||||
- arch: arm64
|
||||
runs-on: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Run the build
|
||||
uses: ./.github/actions/build-server
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
os: linux
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@v2.4.2
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- 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:
|
||||
make_latest: false
|
||||
prerelease: true
|
||||
draft: false
|
||||
fail_on_unmatched_files: true
|
||||
files: upload/*.*
|
||||
tag_name: nightly
|
||||
name: Nightly Build
|
||||
name: TriliumNextNotes linux server x64
|
||||
path: upload/TriliumNextNotes-linux-x64-${{ github.ref_name }}.tar.xz
|
||||
overwrite: true
|
||||
|
||||
- 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-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
|
||||
|
||||
104
.github/workflows/playwright.yml
vendored
104
.github/workflows/playwright.yml
vendored
@@ -1,87 +1,27 @@
|
||||
name: playwright
|
||||
|
||||
name: Playwright Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- hotfix
|
||||
paths-ignore:
|
||||
- "apps/website/**"
|
||||
branches: [ develop ]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
branches: [ develop ]
|
||||
jobs:
|
||||
e2e:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: linux-x64
|
||||
os: ubuntu-22.04
|
||||
arch: x64
|
||||
- name: linux-arm64
|
||||
os: ubuntu-24.04-arm
|
||||
arch: arm64
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: E2E tests on ${{ matrix.name }}
|
||||
env:
|
||||
TRILIUM_DOCKER: 1
|
||||
TRILIUM_PORT: 8082
|
||||
TRILIUM_DATA_DIR: "${{ github.workspace }}/apps/server/spec/db"
|
||||
TRILIUM_INTEGRATION_TEST: memory
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
filter: tree:0
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: pnpm exec playwright install --with-deps
|
||||
|
||||
- name: Build the server
|
||||
uses: ./.github/actions/build-server
|
||||
with:
|
||||
os: linux
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Unpack and start the server
|
||||
run: |
|
||||
version=$(node --eval "console.log(require('./package.json').version)")
|
||||
file=$(find ./upload -name '*.tar.xz' -print -quit)
|
||||
name=$(basename "$file" .tar.xz)
|
||||
mkdir -p ./server-dist
|
||||
tar -xvf "$file" -C ./server-dist
|
||||
server_dir="./server-dist/TriliumNotes-Server-$version-linux-${{ matrix.arch }}"
|
||||
if [ ! -d "$server_dir" ]; then
|
||||
echo Missing dir.
|
||||
exit 1
|
||||
fi
|
||||
cd "$server_dir"
|
||||
"./trilium.sh" &
|
||||
sleep 10
|
||||
|
||||
- name: Server end-to-end tests
|
||||
run: pnpm --filter server-e2e e2e
|
||||
|
||||
- name: Upload test report
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: e2e report ${{ matrix.arch }}
|
||||
path: apps/server-e2e/test-output
|
||||
|
||||
- name: Kill the server
|
||||
if: always()
|
||||
run: pkill -f trilium || true
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
- name: Run Playwright tests
|
||||
run: npx playwright test
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
20
.github/workflows/release-winget.yml
vendored
20
.github/workflows/release-winget.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Release to winget
|
||||
on:
|
||||
release:
|
||||
types: [ published ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: 'Git tag to release from'
|
||||
type: string
|
||||
required: true
|
||||
jobs:
|
||||
release-winget:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Publish to WinGet
|
||||
uses: vedantmgoyal9/winget-releaser@main
|
||||
with:
|
||||
identifier: TriliumNext.Notes
|
||||
token: ${{ secrets.WINGET_PAT }}
|
||||
release-tag: ${{ github.event.inputs.release_tag || github.event.release.tag_name }}
|
||||
172
.github/workflows/release.yml
vendored
172
.github/workflows/release.yml
vendored
@@ -3,9 +3,9 @@ on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
contents: write
|
||||
discussions: write
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
@@ -20,120 +20,76 @@ jobs:
|
||||
os:
|
||||
- name: macos
|
||||
image: macos-latest
|
||||
shell: bash
|
||||
forge_platform: darwin
|
||||
extension: dmg
|
||||
- name: linux
|
||||
image: ubuntu-22.04
|
||||
shell: bash
|
||||
forge_platform: linux
|
||||
image: ubuntu-latest
|
||||
extension: deb
|
||||
- name: windows
|
||||
image: win-signing
|
||||
shell: cmd
|
||||
forge_platform: win32
|
||||
# Exclude ARM64 Linux from default matrix to use native runner
|
||||
exclude:
|
||||
- arch: arm64
|
||||
os:
|
||||
name: linux
|
||||
# Add ARM64 Linux with native ubuntu-24.04-arm runner for better-sqlite3 compatibility
|
||||
include:
|
||||
- arch: arm64
|
||||
os:
|
||||
name: linux
|
||||
image: ubuntu-24.04-arm
|
||||
shell: bash
|
||||
forge_platform: linux
|
||||
image: windows-latest
|
||||
extension: exe
|
||||
runs-on: ${{ matrix.os.image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'pnpm'
|
||||
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
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run the build
|
||||
uses: ./.github/actions/build-electron
|
||||
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-${{ 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
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
os: ${{ matrix.os.name }}
|
||||
arch: ${{ matrix.arch }}
|
||||
shell: ${{ matrix.os.shell }}
|
||||
forge_platform: ${{ matrix.os.forge_platform }}
|
||||
env:
|
||||
APPLE_APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_CERTIFICATE_BASE64 }}
|
||||
APPLE_APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_APP_CERTIFICATE_PASSWORD }}
|
||||
APPLE_INSTALLER_CERTIFICATE_BASE64: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_BASE64 }}
|
||||
APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }}
|
||||
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
|
||||
|
||||
- name: Upload the artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: release-desktop-${{ matrix.os.name }}-${{ matrix.arch }}
|
||||
path: apps/desktop/upload/*.*
|
||||
|
||||
build_server:
|
||||
name: Build Linux Server
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [x64, arm64]
|
||||
include:
|
||||
- arch: x64
|
||||
runs-on: ubuntu-22.04
|
||||
- arch: arm64
|
||||
runs-on: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Run the build
|
||||
uses: ./.github/actions/build-server
|
||||
with:
|
||||
os: linux
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Upload the artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: release-server-linux-${{ matrix.arch }}
|
||||
path: upload/*.*
|
||||
|
||||
publish_release:
|
||||
name: Publish release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- make-electron
|
||||
- build_server
|
||||
steps:
|
||||
- run: mkdir upload
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: |
|
||||
docs/Release Notes
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
merge-multiple: true
|
||||
pattern: release-*
|
||||
path: upload
|
||||
|
||||
- name: Publish stable release
|
||||
uses: softprops/action-gh-release@v2.4.2
|
||||
with:
|
||||
draft: false
|
||||
body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md
|
||||
draft: true
|
||||
fail_on_unmatched_files: true
|
||||
files: upload/*.*
|
||||
discussion_category_name: Releases
|
||||
make_latest: ${{ !contains(github.ref, 'rc') }}
|
||||
prerelease: ${{ contains(github.ref, 'rc') }}
|
||||
token: ${{ secrets.RELEASE_PAT }}
|
||||
build_linux_server-x64:
|
||||
name: Build Linux Server 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"
|
||||
- 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
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: true
|
||||
fail_on_unmatched_files: true
|
||||
files: upload/*.*
|
||||
11
.github/workflows/unblock_signing.yml
vendored
11
.github/workflows/unblock_signing.yml
vendored
@@ -1,11 +0,0 @@
|
||||
name: Unblock signing
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
unblock-win-signing:
|
||||
runs-on: win-signing
|
||||
steps:
|
||||
- run: |
|
||||
cat ${{ vars.WINDOWS_SIGN_ERROR_LOG }}
|
||||
rm ${{ vars.WINDOWS_SIGN_ERROR_LOG }}
|
||||
51
.github/workflows/website.yml
vendored
51
.github/workflows/website.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: Deploy website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "apps/website/**"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- "apps/website/**"
|
||||
|
||||
release:
|
||||
types: [ released ]
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build & deploy website
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write # For PR preview comments
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --filter website --frozen-lockfile
|
||||
|
||||
- name: Build the website
|
||||
run: pnpm website:build
|
||||
|
||||
- name: Deploy
|
||||
uses: ./.github/actions/deploy-to-cloudflare-pages
|
||||
with:
|
||||
project_name: "trilium-homepage"
|
||||
comment_body: "📚 Website preview is ready"
|
||||
production_url: "https://triliumnotes.org"
|
||||
deploy_dir: "apps/website/dist"
|
||||
cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
71
.github/workflows_old/codeql-analysis.yml
vendored
Normal file
71
.github/workflows_old/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '37 4 * * 1'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
53
.github/workflows_old/docker.yaml
vendored
Normal file
53
.github/workflows_old/docker.yaml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Publish Docker image
|
||||
on:
|
||||
push:
|
||||
tags: [v*]
|
||||
jobs:
|
||||
push_to_registries:
|
||||
name: Push Docker image to multiple registries
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: |
|
||||
zadam/trilium
|
||||
ghcr.io/zadam/trilium
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}-latest
|
||||
type=match,pattern=(\d+.\d+).\d+\-beta,enable=${{ endsWith(github.ref, 'beta') }},group=1,suffix=-latest
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
install: true
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Log in to GitHub Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create server-package.json
|
||||
run: cat package.json | grep -v electron > server-package.json
|
||||
- name: Build and Push
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
|
||||
push: true
|
||||
cache-from: type=registry,ref=zadam/trilium:buildcache
|
||||
cache-to: type=registry,ref=zadam/trilium:buildcache,mode=max
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
74
.gitignore
vendored
74
.gitignore
vendored
@@ -1,51 +1,35 @@
|
||||
# See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
||||
/.cache
|
||||
|
||||
# compiled output
|
||||
dist
|
||||
tmp
|
||||
out-tsc
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
src/public/app-dist/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
po-*/
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.db
|
||||
!integration-tests/db/document.db
|
||||
!integration-tests/db/config.ini
|
||||
integration-tests/db/log
|
||||
integration-tests/db/sessions
|
||||
integration-tests/db/backup
|
||||
integration-tests/db/session_secret.txt
|
||||
|
||||
vite.config.*.timestamp*
|
||||
vitest.config.*.timestamp*
|
||||
test-output
|
||||
cert.key
|
||||
cert.crt
|
||||
server-package.json
|
||||
.idea/httpRequests/
|
||||
.idea/shelf/
|
||||
data/
|
||||
data-test/
|
||||
tmp/
|
||||
.eslintcache
|
||||
|
||||
apps/*/data*
|
||||
apps/*/out
|
||||
upload
|
||||
out/
|
||||
|
||||
.rollup.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
/result
|
||||
.svelte-kit
|
||||
|
||||
# docs
|
||||
site/
|
||||
images/app-icons/mac/*.png
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
15
.gitpod.dockerfile
Normal file
15
.gitpod.dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM gitpod/workspace-full
|
||||
|
||||
RUN sudo apt-get update \
|
||||
&& sudo apt-get install -yq --no-install-recommends \
|
||||
libpng16-16 \
|
||||
libpng-dev \
|
||||
pkg-config \
|
||||
autoconf \
|
||||
libtool \
|
||||
build-essential \
|
||||
nasm \
|
||||
libx11-dev \
|
||||
libxkbfile-dev \
|
||||
&& sudo rm -rf /var/lib/apt/lists/*
|
||||
|
||||
11
.gitpod.yml
Normal file
11
.gitpod.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
image:
|
||||
file: .gitpod.dockerfile
|
||||
|
||||
tasks:
|
||||
- before: nvm install 20.15.1 && nvm use 20.15.1
|
||||
init: npm install
|
||||
command: npm run start-server
|
||||
|
||||
ports:
|
||||
- port: 8080
|
||||
onOpen: open-preview
|
||||
6
.idea/.gitignore
generated
vendored
Normal file
6
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
||||
|
||||
# Datasource local storage ignored files
|
||||
/dataSources.local.xml
|
||||
/dataSources/
|
||||
15
.idea/codeStyles/Project.xml
generated
Normal file
15
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
12
.idea/dataSources.xml
generated
Normal file
12
.idea/dataSources.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="document.db" uuid="2a4ac1e6-b828-4a2a-8e4a-3f59f10aff26">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/data/document.db</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
4
.idea/encodings.xml
generated
Normal file
4
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||
</project>
|
||||
15
.idea/git_toolbox_prj.xml
generated
Normal file
15
.idea/git_toolbox_prj.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxProjectSettings">
|
||||
<option name="commitMessageIssueKeyValidationOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
<option name="commitMessageValidationEnabledOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
11
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
11
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/jsLibraryMappings.xml
generated
Normal file
6
.idea/jsLibraryMappings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<includedPredefinedLibrary name="Node.js Core" />
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/jsLinters/jslint.xml
generated
Normal file
9
.idea/jsLinters/jslint.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JSLintConfiguration">
|
||||
<option devel="true" />
|
||||
<option es6="true" />
|
||||
<option maxerr="50" />
|
||||
<option node="true" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/misc.xml
generated
Normal file
8
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" default="true" project-jdk-name="openjdk-16" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/trilium.iml" filepath="$PROJECT_DIR$/trilium.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/sqldialects.xml
generated
Normal file
7
.idea/sqldialects.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$" dialect="SQLite" />
|
||||
<file url="PROJECT" dialect="SQLite" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
5
.prettierignore
Normal file
5
.prettierignore
Normal file
@@ -0,0 +1,5 @@
|
||||
*.html
|
||||
*.md
|
||||
*.yml
|
||||
libraries/*
|
||||
docs/*
|
||||
22
.prettierrc
Normal file
22
.prettierrc
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"printWidth": 200,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"quoteProps": "as-needed",
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"endOfLine": "lf",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.json"],
|
||||
"options": {
|
||||
"tabWidth": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
14
.vscode/extensions.json
vendored
14
.vscode/extensions.json
vendored
@@ -1,15 +1,3 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"editorconfig.editorconfig",
|
||||
"lokalise.i18n-ally",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"ms-playwright.playwright",
|
||||
"redhat.vscode-yaml",
|
||||
"tobermory.es6-string-html",
|
||||
"vitest.explorer",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"svelte.svelte-vscode",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
]
|
||||
"recommendations": ["lokalise.i18n-ally", "editorconfig.editorconfig"]
|
||||
}
|
||||
|
||||
5
.vscode/i18n-ally-custom-framework.yml
vendored
5
.vscode/i18n-ally-custom-framework.yml
vendored
@@ -3,7 +3,6 @@
|
||||
languageIds:
|
||||
- javascript
|
||||
- typescript
|
||||
- typescriptreact
|
||||
- html
|
||||
|
||||
# An array of RegExes to find the key usage. **The key should be captured in the first match group**.
|
||||
@@ -14,7 +13,6 @@ usageMatchRegex:
|
||||
# the `{key}` will be placed by a proper keypath matching regex,
|
||||
# you can ignore it and use your own matching rules as well
|
||||
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
|
||||
- <Trans\s*i18nKey="({key})"[^>]*>
|
||||
|
||||
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
|
||||
# and works like how the i18next framework identifies the namespace scope from the
|
||||
@@ -27,10 +25,9 @@ scopeRangeRegex: "useTranslation\\(\\s*\\[?\\s*['\"`](.*?)['\"`]"
|
||||
# The "$1" will be replaced by the keypath specified.
|
||||
refactorTemplates:
|
||||
- t("$1")
|
||||
- {t("$1")}
|
||||
- ${t("$1")}
|
||||
- <%= t("$1") %>
|
||||
|
||||
|
||||
# If set to true, only enables this custom framework (will disable all built-in frameworks)
|
||||
monopoly: true
|
||||
monopoly: true
|
||||
20
.vscode/i18n-ally-reviews.yml
vendored
Normal file
20
.vscode/i18n-ally-reviews.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Review comments generated by i18n-ally. Please commit this file.
|
||||
|
||||
reviews:
|
||||
help.inPageSearch:
|
||||
description: >-
|
||||
Describes the shortcut which triggers a search within the current
|
||||
page/note only
|
||||
add_label.to_value:
|
||||
locales:
|
||||
fr:
|
||||
comments:
|
||||
- user:
|
||||
name: Potjoe-97
|
||||
email: giann@LAPTOPT490-GF
|
||||
id: QXec0JUoxfGmMlpch-B1S
|
||||
comment: ''
|
||||
suggestion: vers la valeur
|
||||
type: request_change
|
||||
time: '2024-10-15T16:57:06.188Z'
|
||||
resolved: true
|
||||
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
// nodemon should be installed globally, use npm i -g nodemon
|
||||
{
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"name": "nodemon start-server",
|
||||
"program": "${workspaceFolder}/src/www",
|
||||
"request": "launch",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "nodemon",
|
||||
"env": {
|
||||
"TRILIUM_ENV": "dev",
|
||||
"TRILIUM_DATA_DIR": "./data"
|
||||
},
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"type": "node",
|
||||
"outputCapture": "std"
|
||||
}
|
||||
]
|
||||
}
|
||||
60
.vscode/settings.json
vendored
60
.vscode/settings.json
vendored
@@ -1,40 +1,22 @@
|
||||
{
|
||||
"editor.formatOnSave": false,
|
||||
"files.eol": "\n",
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.localesPaths": [
|
||||
"apps/server/src/assets/translations",
|
||||
"apps/client/src/translations",
|
||||
"apps/website/public/translations"
|
||||
],
|
||||
"npm.exclude": [
|
||||
"**/dist",
|
||||
],
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "vscode.css-language-features"
|
||||
},
|
||||
"github-actions.workflows.pinned.workflows": [
|
||||
".github/workflows/nightly.yml"
|
||||
],
|
||||
"typescript.validate.enable": true,
|
||||
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"docs/**/*.html": true,
|
||||
"docs/**/*.png": true,
|
||||
"apps/server/src/assets/doc_notes/**": true,
|
||||
"apps/edit-docs/demo/**": true
|
||||
}
|
||||
}
|
||||
"editor.formatOnSave": false,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"files.eol": "\n",
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.localesPaths": ["./src/public/translations", "./translations"],
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"github-actions.workflows.pinned.workflows": [".github/workflows/nightly.yml"],
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "vscode.css-language-features"
|
||||
}
|
||||
}
|
||||
|
||||
5
.vscode/snippets.code-snippets
vendored
5
.vscode/snippets.code-snippets
vendored
@@ -20,10 +20,5 @@
|
||||
"scope": "typescript",
|
||||
"prefix": "jqf",
|
||||
"body": ["private $${1:name}!: JQuery<HTMLElement>;"]
|
||||
},
|
||||
"region": {
|
||||
"scope": "css",
|
||||
"prefix": "region",
|
||||
"body": ["/* #region ${1:name} */\n$0\n/* #endregion */"]
|
||||
}
|
||||
}
|
||||
|
||||
152
CLAUDE.md
152
CLAUDE.md
@@ -1,152 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
Trilium Notes is a hierarchical note-taking application with advanced features like synchronization, scripting, and rich text editing. It's built as a TypeScript monorepo using pnpm, with multiple applications and shared packages.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Setup
|
||||
- `pnpm install` - Install all dependencies
|
||||
- `corepack enable` - Enable pnpm if not available
|
||||
|
||||
### Running Applications
|
||||
- `pnpm run server:start` - Start development server (http://localhost:8080)
|
||||
- `pnpm run server:start-prod` - Run server in production mode
|
||||
|
||||
### Building
|
||||
- `pnpm run client:build` - Build client application
|
||||
- `pnpm run server:build` - Build server application
|
||||
- `pnpm run electron:build` - Build desktop application
|
||||
|
||||
### Testing
|
||||
- `pnpm test:all` - Run all tests (parallel + sequential)
|
||||
- `pnpm test:parallel` - Run tests that can run in parallel
|
||||
- `pnpm test:sequential` - Run tests that must run sequentially (server, ckeditor5-mermaid, ckeditor5-math)
|
||||
- `pnpm coverage` - Generate coverage reports
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Monorepo Structure
|
||||
- **apps/**: Runnable applications
|
||||
- `client/` - Frontend application (shared by server and desktop)
|
||||
- `server/` - Node.js server with web interface
|
||||
- `desktop/` - Electron desktop application
|
||||
- `web-clipper/` - Browser extension for saving web content
|
||||
- Additional tools: `db-compare`, `dump-db`, `edit-docs`
|
||||
|
||||
- **packages/**: Shared libraries
|
||||
- `commons/` - Shared interfaces and utilities
|
||||
- `ckeditor5/` - Custom rich text editor with Trilium-specific plugins
|
||||
- `codemirror/` - Code editor customizations
|
||||
- `highlightjs/` - Syntax highlighting
|
||||
- Custom CKEditor plugins: `ckeditor5-admonition`, `ckeditor5-footnotes`, `ckeditor5-math`, `ckeditor5-mermaid`
|
||||
|
||||
### Core Architecture Patterns
|
||||
|
||||
#### Three-Layer Cache System
|
||||
- **Becca** (Backend Cache): Server-side entity cache (`apps/server/src/becca/`)
|
||||
- **Froca** (Frontend Cache): Client-side mirror of backend data (`apps/client/src/services/froca.ts`)
|
||||
- **Shaca** (Share Cache): Optimized cache for shared/published notes (`apps/server/src/share/`)
|
||||
|
||||
#### Entity System
|
||||
Core entities are defined in `apps/server/src/becca/entities/`:
|
||||
- `BNote` - Notes with content and metadata
|
||||
- `BBranch` - Hierarchical relationships between notes (allows multiple parents)
|
||||
- `BAttribute` - Key-value metadata attached to notes
|
||||
- `BRevision` - Note version history
|
||||
- `BOption` - Application configuration
|
||||
|
||||
#### Widget-Based UI
|
||||
Frontend uses a widget system (`apps/client/src/widgets/`):
|
||||
- `BasicWidget` - Base class for all UI components
|
||||
- `NoteContextAwareWidget` - Widgets that respond to note changes
|
||||
- `RightPanelWidget` - Widgets displayed in the right panel
|
||||
- Type-specific widgets in `type_widgets/` directory
|
||||
|
||||
#### API Architecture
|
||||
- **Internal API**: REST endpoints in `apps/server/src/routes/api/`
|
||||
- **ETAPI**: External API for third-party integrations (`apps/server/src/etapi/`)
|
||||
- **WebSocket**: Real-time synchronization (`apps/server/src/services/ws.ts`)
|
||||
|
||||
### Key Files for Understanding Architecture
|
||||
|
||||
1. **Application Entry Points**:
|
||||
- `apps/server/src/main.ts` - Server startup
|
||||
- `apps/client/src/desktop.ts` - Client initialization
|
||||
|
||||
2. **Core Services**:
|
||||
- `apps/server/src/becca/becca.ts` - Backend data management
|
||||
- `apps/client/src/services/froca.ts` - Frontend data synchronization
|
||||
- `apps/server/src/services/backend_script_api.ts` - Scripting API
|
||||
|
||||
3. **Database Schema**:
|
||||
- `apps/server/src/assets/db/schema.sql` - Core database structure
|
||||
|
||||
4. **Configuration**:
|
||||
- `package.json` - Project dependencies and scripts
|
||||
|
||||
## Note Types and Features
|
||||
|
||||
Trilium supports multiple note types, each with specialized widgets:
|
||||
- **Text**: Rich text with CKEditor5 (markdown import/export)
|
||||
- **Code**: Syntax-highlighted code editing with CodeMirror
|
||||
- **File**: Binary file attachments
|
||||
- **Image**: Image display with editing capabilities
|
||||
- **Canvas**: Drawing/diagramming with Excalidraw
|
||||
- **Mermaid**: Diagram generation
|
||||
- **Relation Map**: Visual note relationship mapping
|
||||
- **Web View**: Embedded web pages
|
||||
- **Doc/Book**: Hierarchical documentation structure
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Testing Strategy
|
||||
- Server tests run sequentially due to shared database
|
||||
- Client tests can run in parallel
|
||||
- E2E tests use Playwright for both server and desktop apps
|
||||
- Build validation tests check artifact integrity
|
||||
|
||||
### Scripting System
|
||||
Trilium provides powerful user scripting capabilities:
|
||||
- Frontend scripts run in browser context
|
||||
- Backend scripts run in Node.js context with full API access
|
||||
- Script API documentation available in `docs/Script API/`
|
||||
|
||||
### Internationalization
|
||||
- Translation files in `apps/client/src/translations/`
|
||||
- Supported languages: English, German, Spanish, French, Romanian, Chinese
|
||||
|
||||
### Security Considerations
|
||||
- Per-note encryption with granular protected sessions
|
||||
- CSRF protection for API endpoints
|
||||
- OpenID and TOTP authentication support
|
||||
- Sanitization of user-generated content
|
||||
|
||||
## Common Development Tasks
|
||||
|
||||
### Adding New Note Types
|
||||
1. Create widget in `apps/client/src/widgets/type_widgets/`
|
||||
2. Register in `apps/client/src/services/note_types.ts`
|
||||
3. Add backend handling in `apps/server/src/services/notes.ts`
|
||||
|
||||
### Extending Search
|
||||
- Search expressions handled in `apps/server/src/services/search/`
|
||||
- Add new search operators in search context files
|
||||
|
||||
### Custom CKEditor Plugins
|
||||
- Create new package in `packages/` following existing plugin structure
|
||||
- Register in `packages/ckeditor5/src/plugins.ts`
|
||||
|
||||
### Database Migrations
|
||||
- Add migration scripts in `apps/server/src/migrations/`
|
||||
- Update schema in `apps/server/src/assets/db/schema.sql`
|
||||
|
||||
## Build System Notes
|
||||
- Uses pnpm for monorepo management
|
||||
- Vite for fast development builds
|
||||
- ESBuild for production optimization
|
||||
- pnpm workspaces for dependency management
|
||||
- Docker support with multi-stage builds
|
||||
65
Dockerfile
Normal file
65
Dockerfile
Normal file
@@ -0,0 +1,65 @@
|
||||
# Build stage
|
||||
FROM node:22.13.0-bullseye-slim AS builder
|
||||
|
||||
# Configure build dependencies in a single layer
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
autoconf \
|
||||
automake \
|
||||
g++ \
|
||||
gcc \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
libpng-dev \
|
||||
python3 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy only necessary files for build
|
||||
COPY . .
|
||||
COPY server-package.json package.json
|
||||
|
||||
# Build and cleanup in a single layer
|
||||
RUN cp -R build/src/* src/. && \
|
||||
cp build/docker_healthcheck.js . && \
|
||||
rm docker_healthcheck.ts && \
|
||||
npm install && \
|
||||
npm run webpack && \
|
||||
npm prune --omit=dev && \
|
||||
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/. && \
|
||||
rm -rf src/public/app/* && \
|
||||
mkdir -p src/public/app/services && \
|
||||
cp -r build/src/public/app/services/mime_type_definitions.js src/public/app/services/mime_type_definitions.js && \
|
||||
rm src/services/asset_path.ts && \
|
||||
rm -r build
|
||||
|
||||
# Runtime stage
|
||||
FROM node:22.13.0-bullseye-slim
|
||||
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gosu \
|
||||
&& rm -rf /var/lib/apt/lists/* && \
|
||||
rm -rf /var/cache/apt/*
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy only necessary files from builder
|
||||
COPY --from=builder /usr/src/app/node_modules ./node_modules
|
||||
COPY --from=builder /usr/src/app/src ./src
|
||||
COPY --from=builder /usr/src/app/db ./db
|
||||
COPY --from=builder /usr/src/app/docker_healthcheck.js .
|
||||
COPY --from=builder /usr/src/app/start-docker.sh .
|
||||
COPY --from=builder /usr/src/app/package.json .
|
||||
COPY --from=builder /usr/src/app/config-sample.ini .
|
||||
COPY --from=builder /usr/src/app/images ./images
|
||||
COPY --from=builder /usr/src/app/translations ./translations
|
||||
COPY --from=builder /usr/src/app/libraries ./libraries
|
||||
|
||||
# Configure container
|
||||
EXPOSE 8080
|
||||
CMD [ "./start-docker.sh" ]
|
||||
HEALTHCHECK --start-period=10s CMD exec gosu node node docker_healthcheck.js
|
||||
64
Dockerfile.alpine
Normal file
64
Dockerfile.alpine
Normal file
@@ -0,0 +1,64 @@
|
||||
# Build stage
|
||||
FROM node:22.13.0-alpine AS builder
|
||||
|
||||
# Configure build dependencies
|
||||
RUN apk add --no-cache --virtual .build-dependencies \
|
||||
autoconf \
|
||||
automake \
|
||||
g++ \
|
||||
gcc \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
libpng-dev \
|
||||
python3
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy only necessary files for build
|
||||
COPY . .
|
||||
COPY server-package.json package.json
|
||||
|
||||
# Build and cleanup in a single layer
|
||||
RUN cp -R build/src/* src/. && \
|
||||
cp build/docker_healthcheck.js . && \
|
||||
rm docker_healthcheck.ts && \
|
||||
npm install && \
|
||||
npm run webpack && \
|
||||
npm prune --omit=dev && \
|
||||
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/. && \
|
||||
rm -rf src/public/app && \
|
||||
mkdir -p src/public/app/services && \
|
||||
cp -r build/src/public/app/services/mime_type_definitions.js src/public/app/services/mime_type_definitions.js && \
|
||||
rm src/services/asset_path.ts && \
|
||||
rm -r build
|
||||
|
||||
# Runtime stage
|
||||
FROM node:22.13.0-alpine
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache su-exec shadow
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy only necessary files from builder
|
||||
COPY --from=builder /usr/src/app/node_modules ./node_modules
|
||||
COPY --from=builder /usr/src/app/src ./src
|
||||
COPY --from=builder /usr/src/app/db ./db
|
||||
COPY --from=builder /usr/src/app/docker_healthcheck.js .
|
||||
COPY --from=builder /usr/src/app/start-docker.sh .
|
||||
COPY --from=builder /usr/src/app/package.json .
|
||||
COPY --from=builder /usr/src/app/config-sample.ini .
|
||||
COPY --from=builder /usr/src/app/images ./images
|
||||
COPY --from=builder /usr/src/app/translations ./translations
|
||||
COPY --from=builder /usr/src/app/libraries ./libraries
|
||||
|
||||
# Add application user
|
||||
RUN adduser -s /bin/false node; exit 0
|
||||
|
||||
# Configure container
|
||||
EXPOSE 8080
|
||||
CMD [ "./start-docker.sh" ]
|
||||
HEALTHCHECK --start-period=10s CMD exec su-exec node node docker_healthcheck.js
|
||||
97
README-ZH_CN.md
Normal file
97
README-ZH_CN.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# TriliumNext Notes
|
||||
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
TriliumNext Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)以快速了解:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## ⚠️ 为什么选择TriliumNext?
|
||||
|
||||
[原始的Trilium项目目前处于维护模式](https://github.com/zadam/trilium/issues/4620)
|
||||
|
||||
## 🗭 与我们讨论
|
||||
|
||||
欢迎加入我们的官方讨论和社区。我们专注于Trilium的开发,乐于听取您对功能、建议或问题的意见!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org)(用于同步讨论)
|
||||
- [Github Discussions](https://github.com/TriliumNext/Notes/discussions)(用于异步讨论)
|
||||
- [Wiki](https://triliumnext.github.io/Docs/)(用于常见操作问题和用户指南)
|
||||
|
||||
上面链接的两个房间是镜像的,所以您可以在任意平台上使用XMPP或者Matrix来和我们交流。
|
||||
|
||||
### 非官方社区
|
||||
|
||||
[Trilium Rocks](https://discord.gg/aqdX9mXX4r)
|
||||
|
||||
## 🎁 特性
|
||||
|
||||
* 笔记可以排列成任意深的树。单个笔记可以放在树中的多个位置(请参阅[克隆](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* 丰富的所见即所得笔记编辑功能,包括带有 Markdown [自动格式化功能的](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)表格,图像和[数学公式](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support)
|
||||
* 支持编辑[使用源代码的笔记](https://triliumnext.github.io/Docs/Wiki/code-notes),包括语法高亮显示
|
||||
* 笔记之间快速[导航](https://triliumnext.github.io/Docs/Wiki/note-navigation),全文搜索和[提升笔记](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* 无缝[笔记版本控制](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* 笔记[属性](https://triliumnext.github.io/Docs/Wiki/attributes)可用于笔记组织,查询和高级[脚本编写](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* [同步](https://triliumnext.github.io/Docs/Wiki/synchronization)与自托管同步服务器
|
||||
* 有一个[第三方提供的同步服务器托管服务](https://trilium.cc/paid-hosting)
|
||||
* 公开地[分享](https://triliumnext.github.io/Docs/Wiki/sharing)(发布)笔记到互联网
|
||||
* 具有按笔记粒度的强大的[笔记加密](https://triliumnext.github.io/Docs/Wiki/protected-notes)
|
||||
* 使用自带的 Excalidraw 来绘制图表(笔记类型“画布”)
|
||||
* [关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map),用于可视化笔记及其关系
|
||||
* [脚本](https://triliumnext.github.io/Docs/Wiki/scripts) - 请参阅[高级功能展示](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* 可用于自动化的 [REST API](https://triliumnext.github.io/Docs/Wiki/etapi)
|
||||
* 在拥有超过 10 万条笔记时仍能保持良好的可用性和性能
|
||||
* 针对智能手机和平板电脑进行优化的[用于移动设备的前端](https://triliumnext.github.io/Docs/Wiki/mobile-frontend)
|
||||
* [夜间主题](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) 和 [Markdown 导入导出](https://triliumnext.github.io/Docs/Wiki/markdown)功能
|
||||
* 使用[网页剪藏](https://triliumnext.github.io/Docs/Wiki/web-clipper)轻松保存互联网上的内容
|
||||
|
||||
✨ 查看以下第三方资源,获取更多关于TriliumNext的好东西:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium):提供第三方主题、脚本、插件等资源的列表。
|
||||
- [TriliumRocks!](https://trilium.rocks/):提供教程、指南等更多内容。
|
||||
|
||||
## 🏗 构建
|
||||
|
||||
Trilium 可以用作桌面应用程序(Linux 和 Windows)或服务器(Linux)上托管的 Web 应用程序。虽然有 macOS 版本的桌面应用程序,但它[不受支持](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support)。
|
||||
|
||||
* 如果要在桌面上使用 Trilium,请从[最新版本](https://github.com/TriliumNext/Notes/releases/latest)下载适用于您平台的二进制版本,解压缩该软件包并运行`trilium`可执行文件。
|
||||
* 如果要在服务器上安装 Trilium,请参考[此页面](https://triliumnext.github.io/Docs/Wiki/server-installation)。
|
||||
* 当前仅支持(测试过)最近发布的 Chrome 和 Firefox 浏览器。
|
||||
|
||||
Trilium 也提供 Flatpak:
|
||||
|
||||
[<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium)
|
||||
|
||||
## 📝 文档
|
||||
|
||||
[有关文档页面的完整列表,请参见 Wiki。](https://triliumnext.github.io/Docs/)
|
||||
|
||||
* [Wiki 的中文翻译版本](https://github.com/baddate/trilium/wiki/)
|
||||
|
||||
您还可以阅读[个人知识库模式](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge),以获取有关如何使用 Trilium 的灵感。
|
||||
|
||||
## 💻 贡献
|
||||
|
||||
|
||||
或者克隆本仓库到本地,并运行
|
||||
|
||||
```shell
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 👏 致谢
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市面上最好的所见即所得编辑器,拥有互动性强且聆听能力强的团队
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - 一个非常丰富的关于树的库,强大到没有对手。没有它,Trilium Notes 将不会如此。
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - 支持大量语言的代码编辑器
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - 强大的可视化连接库。用于[关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map)
|
||||
|
||||
## 🤝 捐赠
|
||||
|
||||
你可以通过 GitHub Sponsors,[PayPal](https://paypal.me/za4am) 或者比特币 (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) 来捐赠。
|
||||
|
||||
## 🔑 许可证
|
||||
|
||||
本程序是自由软件:你可以再发布本软件和/或修改本软件,只要你遵循 Free Software Foundation 发布的 GNU Affero General Public License 的第三版或者任何(由你选择)更晚的版本。
|
||||
106
README.es.md
Normal file
106
README.es.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# TriliumNext Notes
|
||||
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
TriliumNext Notes es una aplicación de toma de notas jerárquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal.
|
||||
|
||||
Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) para un vistazo rápido:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## ⚠️ ¿Por qué usar TriliumNext?
|
||||
|
||||
[El proyecto Trilium original está en modo de mantenimiento](https://github.com/zadam/trilium/issues/4620)
|
||||
|
||||
### ¿Cómo migrar desde Trilium?
|
||||
|
||||
No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Notes. Simplemente actualice su instancia de Trilium a la última versión e [instale TriliumNext/Notes como de costumbre](#-Instalación)
|
||||
|
||||
## 💬 Discuta con nosotros
|
||||
|
||||
Siéntase libre de unirse a nuestras conversaciones oficiales. ¡Nos encantaría escuchar de las características, sugerencias o problemas que pueda tener!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones síncronas)
|
||||
- La sala `General` es replicada a [XMPP](xmpp:discuss@trilium.thisgreat.party?join)
|
||||
- [Discusiones de GitHub](https://github.com/TriliumNext/Notes/discussions) (Para discusiones asíncronas)
|
||||
- [Wiki](https://triliumnext.github.io/Docs/) (Para preguntas frecuentes y guías de usuario)
|
||||
|
||||
## 🎁 Características
|
||||
|
||||
- Las notas pueden ser acomodadas en un árbol de profundidad arbitraria. Una sola nota puede ser colocada en múltiples lugares del árbol (vea [clonar](https://triliumnext.github.io/Docs/Wiki/cloning-notes)
|
||||
- Edición de notas WYSIWYG enriquecida que incluye, por ejemplo, tablas, imágenes y [matemáticas](https://triliumnext.github.io/Docs/Wiki/text-notes) con [autoformato](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) markdown
|
||||
- Soporte para editar [notas con código fuente](https://triliumnext.github.io/Docs/Wiki/code-notes), incluyendo resaltado de sintaxis
|
||||
- Rápida y sencilla [navegación entre notas](https://triliumnext.github.io/Docs/Wiki/note-navigation), búsqueda de texto completo y [elevación de notas](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
- [Versionado de notas](https://triliumnext.github.io/Docs/Wiki/note-revisions) sutil
|
||||
- Los [atributos](https://triliumnext.github.io/Docs/Wiki/attributes) de las notas pueden utilizarse para organización, realizar consultas y [scripts](https://triliumnext.github.io/Docs/Wiki/scripts) avanzados
|
||||
- [Sincronización](https://triliumnext.github.io/Docs/Wiki/synchronization) con servidor de sincronización propio
|
||||
- existe un [servicio de terceros para alojar el servidor de sincronización](https://trilium.cc/paid-hosting)
|
||||
- [Compartir](https://triliumnext.github.io/Docs/Wiki/sharing) (publicar) notas al Internet público
|
||||
- Fuerte [encriptación de notas](https://triliumnext.github.io/Docs/Wiki/protected-notes) con granularidad para cada nota
|
||||
- Esbozo de diagramas con Excalidraw incorporado (tipo de nota «canvas»)
|
||||
- [Mapas de relaciones](<https://triliumnext.github.io/Docs/Wiki/relation-map>) y [mapas de enlaces](https://triliumnext.github.io/Docs/Wiki/link-map) para visualizar las notas y sus relaciones
|
||||
- [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vea [casos de uso avanzados](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
- [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) para automatización
|
||||
- Escala bien tanto en uso como en rendimiento a partir de 100,000 notas
|
||||
- [Interfaz móvil](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) optimizada para teléfonos inteligentes y tabletas
|
||||
- [Tema nocturno](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
- Importación y exportación de [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) y [Markdown](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
- [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) para guardar fácilmente contenido web
|
||||
|
||||
✨ Consulte los/las siguientes recursos/comunidades de terceros para obtener más información sobre complementos para TriliumNext:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) para temas, scripts, plugins y más de terceros.
|
||||
- [TriliumRocks!](https://trilium.rocks/) para tutoriales, guías y mucho más.
|
||||
|
||||
## 🏗 Instalación
|
||||
|
||||
### Escritorio
|
||||
|
||||
Para usar TriliumNext en su máquina de escritorio (Linux, MacOS y Windows) tiene algunas opciones:
|
||||
|
||||
- Descargue la versión binaria para su plataforma desde la [página de lanzamientos](https://github.com/TriliumNext/Notes/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`.
|
||||
- Acceda a TriliumNext a través de la interfaz web de una instalación de servidor (ver más abajo)
|
||||
- Actualmente solo las últimas versiones de Chrome y Firefox son compatibles (y están probadas).
|
||||
- (Próximamente) TriliumNext también se proporcionará como un Flatpak
|
||||
|
||||
### Móvil
|
||||
|
||||
Para usar TriliumNext en un dispositivo móvil:
|
||||
|
||||
- Utilice un navegador web móvil para acceder a la interfaz móvil de una instalación de servidor (ver más abajo)
|
||||
- El uso de una aplicación móvil aún no está soportado ([vea aquí](https://github.com/TriliumNext/Notes/issues/72)) para seguir las mejoras móviles.
|
||||
|
||||
### Servidor
|
||||
|
||||
Para instalar TriliumNext en su servidor (incluyendo vía Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
|
||||
## 📝 Documentación
|
||||
|
||||
[Vea la Wiki para la lista completa de páginas de documentación.](https://triliumnext.github.io/Docs)
|
||||
|
||||
También puede leer [Patrones para una base de conocimiento personal](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) para obtener un poco de inspiración de como podría usar TriliumNext.
|
||||
|
||||
## 💻 Contribuir
|
||||
|
||||
Clone localmente y ejecute
|
||||
|
||||
```shell
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 👏 Reconocimientos
|
||||
|
||||
- [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el mejor editor WYSIWYG en el mercado, equipo muy interactivo y atento
|
||||
- [FancyTree](https://github.com/mar10/fancytree) - biblioteca de árbol muy rica en funciones sin competencia real. TriliumNext Notes no sería lo mismo sin esta.
|
||||
- [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con soporte para una gran cantidad de lenguajes
|
||||
- [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad visual sin competencia. Usado en [mapas de relación](https://triliumnext.github.io/Docs/Wiki/Relation-map) y [mapas de enlace](https://triliumnext.github.io/Docs/Wiki/Link-map)
|
||||
|
||||
## 🤝 Soporte
|
||||
|
||||
Puede apoyar al desarrollador original de Trilium usando GitHub Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
Apoyo para la organización TriliumNext será posible en un futuro próximo.
|
||||
|
||||
## 🔑 Licencia
|
||||
|
||||
Este programa es software libre: puede redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General de Affero GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior.
|
||||
93
README.it.md
Normal file
93
README.it.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# TriliumNext Notes
|
||||
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
TriliumNext Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni.
|
||||
|
||||
Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per una panoramica veloce:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## ⚠️ Perchè TriliumNext?
|
||||
[Il progetto originale Trilium è in modalità di manutenzione](https://github.com/zadam/trilium/issues/4620)
|
||||
|
||||
## 🗭 Discuti con noi
|
||||
Sentiti libero di unirti alle nostre discussioni ufficiali e alla nostra comunità. Siamo concentrati sullo sviluppo di Trilium e ci piacerebbe sapere quali funzioni, suggerimenti o eventuali problemi hai!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni sincrone)
|
||||
- [Discussioni Github](https://github.com/TriliumNext/Notes/discussions) (Per discussioni asincrone)
|
||||
- [Wiki](https://triliumnext.github.io/Docs/) (Per le domande più comuni e le guide per l'utente)
|
||||
|
||||
Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quindi puoi usare XMPP o Matrix da qualsiasi client tu preferisca, praticamente su qualsiasi piattaforma!
|
||||
### Comunità non ufficiali
|
||||
|
||||
[Trilium Rocks](https://discord.gg/aqdX9mXX4r)
|
||||
## 🎁 Funzionalità
|
||||
|
||||
* Gli appunti possono essere organizzati in un albero di profondità arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) e con [formattazione automatica](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) per markdown
|
||||
* Supporto per la modifica di [appunti con codice sorgente](https://triliumnext.github.io/Docs/Wiki/code-notes), con evidenziazione della sintassi
|
||||
* [Navigazione veloce](https://triliumnext.github.io/Docs/Wiki/note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Supporto integrato ed automatico per le [revisioni degli appunti](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Gli [attributi](https://triliumnext.github.io/Docs/Wiki/attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione).
|
||||
* [Sincronizzazione](https://triliumnext.github.io/Docs/Wiki/synchronization) con un server di sincronizzazione auto-ospitato
|
||||
* c'è un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting)
|
||||
* [Condivisione](https://triliumnext.github.io/Docs/Wiki/sharing) (pubblicazione) di appunti sull'internet pubblico
|
||||
* Robusta [crittografia](https://triliumnext.github.io/Docs/Wiki/protected-notes) configurabile singolarmente per ogni appunto
|
||||
* Disegno di diagrammi con Excalidraw (tipo di appunto "canvas")
|
||||
* [Mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map) per visualizzare gli appunti e le loro relazioni
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vedi [Esempi avanzati](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [API REST](https://triliumnext.github.io/Docs/Wiki/etapi) per l'automazione
|
||||
* Si adatta bene sia in termini di usabilità che di prestazioni fino ad oltre 100 000 appunti
|
||||
* Interfaccia utente ottimizzata per il [mobile](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) (smartphone e tablet)
|
||||
* [Tema Notturno](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* Supporto per importazione ed esportazione da e per [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) e [Markdown import](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) per il salvataggio facile di contenuti web
|
||||
|
||||
✨ Dai un'occhiata alle seguenti risorse di terze parti per scoprire altre bellezze legate a TriliumNext:
|
||||
|
||||
-[awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti.
|
||||
- [TriliumRocks!](https://trilium.rocks/) per tutorial, guide e molto altro.
|
||||
## 🏗 Rilasci
|
||||
|
||||
|
||||
Trilium è fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS è disponibile, ma [non è supportata](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support).
|
||||
|
||||
* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Notes/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```.
|
||||
* Se vuoi installare Trilium su un server, segui [questa pagina](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
* Per ora solo Chrome e Firefox sono i browser supportati (testati).
|
||||
|
||||
TriliumNext sarà fornito anche come Flatpak:
|
||||
|
||||
<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">
|
||||
|
||||
## 📝 Documentazione
|
||||
|
||||
[Vedi la wiki per una lista completa delle pagine di documentazione.](https://triliumnext.github.io/Docs/)
|
||||
|
||||
Puoi anche leggere ["Patterns of personal knowledge base"](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) per avere un'ispirazione su come potresti utilizzare Trilium.
|
||||
|
||||
## 💻 Contribuire
|
||||
|
||||
Clona localmente ed esegui
|
||||
|
||||
```shell
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 👏 Riconoscimenti
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - libreria per alberi molto ricca di funzionalità, senza pari. Trilium Notes non sarebbe lo stesso senza di essa.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantità di linguaggi.
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la connettività visuale senza pari. Utilizzata per [mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map).
|
||||
|
||||
## 🤝 Supporto
|
||||
|
||||
Puoi sostenere lo sviluppatore originale di Trilium utilizzando gli sponsor di GitHub, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
Il supporto all'organizzazione TriliumNext sarà possibile nel prossimo futuro.
|
||||
|
||||
## 🔑 Licenza
|
||||
|
||||
Questo programma è software libero: è possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva.
|
||||
73
README.ja.md
Normal file
73
README.ja.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# TriliumNext Notes
|
||||
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
Trilium Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)をご覧ください:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## 🎁 特徴
|
||||
|
||||
* ノートは、任意の深さのツリーに配置できます。単一のノートをツリー内の複数の場所に配置できます ([cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes) を参照)
|
||||
* マークダウン[オートフォーマット](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)による、表、画像、[数学](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support)などの豊富な WYSIWYG ノート編集機能
|
||||
* シンタックスハイライトを含む[ソースコード付きノート](https://triliumnext.github.io/Docs/Wiki/code-notes)の編集をサポート
|
||||
* [ノート間のナビゲーション](https://triliumnext.github.io/Docs/Wiki/note-navigation)、全文検索、[ノートホイスト](https://triliumnext.github.io/Docs/Wiki/note-hoisting)が高速かつ簡単に行えます
|
||||
* シームレスな[ノートのバージョン管理](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* ノート[属性](https://triliumnext.github.io/Docs/Wiki/Attributes)は、ノート整理、クエリ、高度な[スクリプト](https://triliumnext.github.io/Docs/Wiki/scripts)に使用できます
|
||||
* 自己ホスト型同期サーバーとの[同期](https://triliumnext.github.io/Docs/Wiki/synchronization)
|
||||
* [同期サーバーをホストするサードパーティ・サービス](https://trilium.cc/paid-hosting)があります
|
||||
* 公開インターネットへのノートの[共有](https://triliumnext.github.io/Docs/Wiki/sharing)(公開)
|
||||
* ノートごとの粒度を持つ強力な[ノート暗号化](https://triliumnext.github.io/Docs/Wiki/protected-notes)
|
||||
* 組み込みの Excalidraw を使用した図のスケッチ (ノート タイプ"キャンバス")
|
||||
* ノートとその関係を可視化するための[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)と[リンクマップ](https://triliumnext.github.io/Docs/Wiki/link-map)
|
||||
* [スクリプティング](https://triliumnext.github.io/Docs/Wiki/scripts) - [高度なショーケース](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)を参照
|
||||
* 自動化のための [REST API](https://triliumnext.github.io/Docs/Wiki/etapi)
|
||||
* ユーザビリティとパフォーマンスの両方で 100 000 ノート以上に拡張可能
|
||||
* スマートフォンとタブレット向けのタッチ最適化[モバイルフロントエンド](https://triliumnext.github.io/Docs/Wiki/mobile-frontend)
|
||||
* [ナイトテーマ](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) と [Markdown のインポートとエクスポート](https://triliumnext.github.io/Docs/Wiki/Markdown)
|
||||
* Web コンテンツを簡単に保存するための [Web クリッパー](https://triliumnext.github.io/Docs/Wiki/web-clipper)
|
||||
|
||||
サードパーティのテーマ、スクリプト、プラグインなどは、 [awesome-trilium](https://github.com/Nriver/awesome-trilium) をチェックしてください。
|
||||
|
||||
## 🏗 ビルド
|
||||
|
||||
Trilium は、デスクトップアプリケーション(Linux、Windows)またはサーバー上でホストされるウェブアプリケーション(Linux)として提供されます。 Mac OS のデスクトップビルドも利用可能ですが、 [unsupported](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support) となっています。
|
||||
|
||||
* デスクトップで Trilium を使用したい場合は、 [latest release](https://github.com/TriliumNext/Notes/releases/latest) からお使いのプラットフォームのバイナリリリースをダウンロードし、パッケージを解凍して ``trilium`` の実行ファイルを実行してください。
|
||||
* サーバーに Trilium をインストールする場合は、[このページ](https://triliumnext.github.io/Docs/Wiki/server-installation)に従ってください。
|
||||
* 現在、対応(動作確認)しているブラウザは、最近の Chrome と Firefox のみです。
|
||||
|
||||
Trilium は Flatpak としても提供されます:
|
||||
|
||||
[<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium)
|
||||
|
||||
## 📝 ドキュメント
|
||||
|
||||
[ドキュメントページの全リストはwikiをご覧ください。](https://triliumnext.github.io/Docs/)
|
||||
|
||||
また、[個人的な知識基盤のパターン](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)を読むと、 Trilium の使い方のヒントを得ることができます。
|
||||
|
||||
## 💻 コントリビュート
|
||||
|
||||
または、ローカルにクローンして実行
|
||||
|
||||
```shell
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 📢 シャウトアウト
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市場で最高の WYSIWYG エディター、非常にインタラクティブで聞き上手なチーム
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - 真の競争相手がいない、非常に機能豊富なツリーライブラリです。 Trilium Notes は、これなしでは成り立たないでしょう。
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - 膨大な数の言語をサポートするコードエディタ
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - 競合のないビジュアルコネクティビティライブラリです。[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)、[リンク図](https://triliumnext.github.io/Docs/Wiki/link-map)で使用。
|
||||
|
||||
## 🤝 サポート
|
||||
|
||||
GitHub スポンサー、[PayPal](https://paypal.me/za4am)もしくは Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) にて Trilium をサポートすることができます。
|
||||
|
||||
## 🔑 ライセンス
|
||||
|
||||
このプログラムはフリーソフトウェアです:フリーソフトウェア財団が発行した GNU Affero General Public License のバージョン3、またはそれ以降のバージョンのいずれかに従って、再配布および/または改変することができます。
|
||||
202
README.md
202
README.md
@@ -1,218 +1,126 @@
|
||||
<div align="center">
|
||||
<sup>Special thanks to:</sup><br />
|
||||
<a href="https://go.warp.dev/Trilium" target="_blank">
|
||||
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/blob/main/Github/Sponsor/Warp-Github-LG-03.png"><br />
|
||||
Warp, built for coding with multiple AI agents<br />
|
||||
</a>
|
||||
<sup>Available for macOS, Linux and Windows</sup>
|
||||
</div>
|
||||
# TriliumNext Notes
|
||||
|
||||
<hr />
|
||||
 
|
||||
|
||||
# Trilium Notes
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
 
|
||||

|
||||

|
||||
[](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) [](https://hosted.weblate.org/engage/trilium/)
|
||||
|
||||
[English](./README.md) | [Chinese (Simplified)](./docs/README-ZH_CN.md) | [Chinese (Traditional)](./docs/README-ZH_TW.md) | [Russian](./docs/README-ru.md) | [Japanese](./docs/README-ja.md) | [Italian](./docs/README-it.md) | [Spanish](./docs/README-es.md)
|
||||
|
||||
Trilium Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
||||
TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
||||
|
||||
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## ⏬ Download
|
||||
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – stable version, recommended for most users.
|
||||
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – unstable development version, updated daily with the latest features and fixes.
|
||||
## ⚠️ Why TriliumNext?
|
||||
|
||||
## 📚 Documentation
|
||||
[The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620)
|
||||
|
||||
**Visit our comprehensive documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/)**
|
||||
### Migrating from Trilium?
|
||||
|
||||
Our documentation is available in multiple formats:
|
||||
- **Online Documentation**: Browse the full documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/)
|
||||
- **In-App Help**: Press `F1` within Trilium to access the same documentation directly in the application
|
||||
- **GitHub**: Navigate through the [User Guide](./docs/User%20Guide/User%20Guide/) in this repository
|
||||
There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and [install TriliumNext/Notes as usual](#-installation)
|
||||
|
||||
### Quick Links
|
||||
- [Getting Started Guide](https://docs.triliumnotes.org/)
|
||||
- [Installation Instructions](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md)
|
||||
- [Docker Setup](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
|
||||
- [Upgrading TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
|
||||
- [Basic Concepts and Features](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
|
||||
- [Patterns of Personal Knowledge Base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
|
||||
Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented.
|
||||
|
||||
## 💬 Discuss with us
|
||||
|
||||
Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions)
|
||||
- The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join)
|
||||
- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions)
|
||||
- [Wiki](https://triliumnext.github.io/Docs/) (For common how-to questions and user guides)
|
||||
|
||||
## 🎁 Features
|
||||
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Rich WYSIWYG note editor including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Rich WYSIWYG note editing including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional)
|
||||
* Direct [OpenID and TOTP integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md) for more secure login
|
||||
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server
|
||||
* there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting)
|
||||
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet
|
||||
* Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity
|
||||
* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type "canvas")
|
||||
* Sketching diagrams with built-in Excalidraw (note type "canvas")
|
||||
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations
|
||||
* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/)
|
||||
* [Geo maps](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) with location pins and GPX tracks
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets
|
||||
* Built-in [dark theme](https://triliumnext.github.io/Docs/Wiki/themes), support for user themes
|
||||
* [Night theme](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content
|
||||
* Customizable UI (sidebar buttons, user-defined widgets, ...)
|
||||
* [Metrics](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics.md), along with a [Grafana Dashboard](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics/grafana-dashboard.json)
|
||||
|
||||
✨ Check out the following third-party resources/communities for more TriliumNext related goodies:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more.
|
||||
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
|
||||
|
||||
## ❓Why TriliumNext?
|
||||
|
||||
The original Trilium developer ([Zadam](https://github.com/zadam)) has graciously given the Trilium repository to the community project which resides at https://github.com/TriliumNext
|
||||
|
||||
### ⬆️Migrating from Zadam/Trilium?
|
||||
|
||||
There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Trilium instance. Simply [install TriliumNext/Trilium](#-installation) as usual and it will use your existing database.
|
||||
|
||||
Versions up to and including [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext/Trilium have their sync versions incremented which prevents direct migration.
|
||||
|
||||
## 💬 Discuss with us
|
||||
|
||||
Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions.)
|
||||
- The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join)
|
||||
- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For asynchronous discussions.)
|
||||
- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug reports and feature requests.)
|
||||
|
||||
## 🏗 Installation
|
||||
|
||||
### Windows / MacOS
|
||||
### Desktop
|
||||
|
||||
Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable.
|
||||
To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options:
|
||||
|
||||
### Linux
|
||||
* Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the ```trilium``` executable.
|
||||
* Access TriliumNext via the web interface of a server installation (see below)
|
||||
* Currently only the latest versions of Chrome & Firefox are supported (and tested).
|
||||
* (Coming Soon) TriliumNext will also be provided as a Flatpak
|
||||
|
||||
If your distribution is listed in the table below, use your distribution's package.
|
||||
#### MacOS
|
||||
Currently when running TriliumNext/Notes on MacOS, you may get the following error:
|
||||
> Apple could not verify "TriliumNext Notes" is free of malware and may harm your Mac or compromise your privacy.
|
||||
|
||||
[](https://repology.org/project/triliumnext/versions)
|
||||
You will need to run the command on your shell to resolve the error (documented [here](https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137)):
|
||||
|
||||
You may also download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable.
|
||||
|
||||
TriliumNext is also provided as a Flatpak, but not yet published on FlatHub.
|
||||
|
||||
### Browser (any OS)
|
||||
|
||||
If you use a server installation (see below), you can directly access the web interface (which is almost identical to the desktop app).
|
||||
|
||||
Currently only the latest versions of Chrome & Firefox are supported (and tested).
|
||||
```bash
|
||||
xattr -c "/path/to/Trilium Next.app"
|
||||
```
|
||||
|
||||
### Mobile
|
||||
|
||||
To use TriliumNext on a mobile device, you can use a mobile web browser to access the mobile interface of a server installation (see below).
|
||||
To use TriliumNext on a mobile device:
|
||||
|
||||
See issue https://github.com/TriliumNext/Trilium/issues/4962 for more information on mobile app support.
|
||||
|
||||
If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid).
|
||||
Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid).
|
||||
Note: It is best to disable automatic updates on your server installation (see below) when using TriliumDroid since the sync version must match between Trilium and TriliumDroid.
|
||||
* Use a mobile web browser to access the mobile interface of a server installation (see below)
|
||||
* Use of a mobile app is not yet supported ([see here](https://github.com/TriliumNext/Notes/issues/72)) to track mobile improvements.
|
||||
|
||||
### Server
|
||||
|
||||
To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
|
||||
## 📝 Documentation
|
||||
|
||||
[See wiki for complete list of documentation pages.](https://triliumnext.github.io/Docs)
|
||||
|
||||
You can also read [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) to get some inspiration on how you might use TriliumNext.
|
||||
|
||||
## 💻 Contribute
|
||||
|
||||
### Translations
|
||||
|
||||
If you are a native speaker, help us translate Trilium by heading over to our [Weblate page](https://hosted.weblate.org/engage/trilium/).
|
||||
|
||||
Here's the language coverage we have so far:
|
||||
|
||||
[](https://hosted.weblate.org/engage/trilium/)
|
||||
|
||||
### Code
|
||||
|
||||
Download the repository, install dependencies using `pnpm` and then run the server (available at http://localhost:8080):
|
||||
```shell
|
||||
git clone https://github.com/TriliumNext/Trilium.git
|
||||
cd Trilium
|
||||
pnpm install
|
||||
pnpm run server:start
|
||||
git clone https://github.com/TriliumNext/Notes.git
|
||||
cd Notes
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
Download the repository, install dependencies using `pnpm` and then run the environment required to edit the documentation:
|
||||
```shell
|
||||
git clone https://github.com/TriliumNext/Trilium.git
|
||||
cd Trilium
|
||||
pnpm install
|
||||
pnpm edit-docs:edit-docs
|
||||
```
|
||||
|
||||
### Building the Executable
|
||||
Download the repository, install dependencies using `pnpm` and then build the desktop app for Windows:
|
||||
```shell
|
||||
git clone https://github.com/TriliumNext/Trilium.git
|
||||
cd Trilium
|
||||
pnpm install
|
||||
pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32
|
||||
```
|
||||
|
||||
For more details, see the [development docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide).
|
||||
|
||||
### Developer Documentation
|
||||
|
||||
Please view the [documentation guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) for details. If you have more questions, feel free to reach out via the links described in the "Discuss with us" section above.
|
||||
Head on over to our [Docs repo](https://github.com/TriliumNext/Docs)
|
||||
|
||||
## 👏 Shoutouts
|
||||
|
||||
* [zadam](https://github.com/zadam) for the original concept and implementation of the application.
|
||||
* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the application icon.
|
||||
* [nriver](https://github.com/nriver) for his work on internationalization.
|
||||
* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas.
|
||||
* [antoniotejada](https://github.com/nriver) for the original syntax highlight widget.
|
||||
* [Dosu](https://dosu.dev/) for providing us with the automated responses to GitHub issues and discussions.
|
||||
* [Tabler Icons](https://tabler.io/icons) for the system tray icons.
|
||||
|
||||
Trilium would not be possible without the technologies behind it:
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind text notes. We are grateful for being offered a set of the premium features.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages.
|
||||
* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite whiteboard used in Canvas notes.
|
||||
* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the mind map functionality.
|
||||
* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical maps.
|
||||
* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive table used in collections.
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library without real competition.
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)
|
||||
|
||||
## 🤝 Support
|
||||
|
||||
Trilium is built and maintained with [hundreds of hours of work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your support keeps it open-source, improves features, and covers costs such as hosting.
|
||||
|
||||
Consider supporting the main developer ([eliandoran](https://github.com/eliandoran)) of the application via:
|
||||
|
||||
- [GitHub Sponsors](https://github.com/sponsors/eliandoran)
|
||||
- [PayPal](https://paypal.me/eliandoran)
|
||||
- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran)
|
||||
|
||||
You can support the original Trilium developer using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2).
|
||||
Support for the TriliumNext organization will be possible in the near future.
|
||||
|
||||
## 🔑 License
|
||||
|
||||
Copyright 2017-2025 zadam, Elian Doran, and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
59
README.ru.md
Normal file
59
README.ru.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# TriliumNext Notes
|
||||
|
||||
[English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
|
||||
|
||||
Trilium Notes – это приложение для заметок с иерархической структурой, ориентированное на создание больших персональных баз знаний. Для быстрого ознакомления посмотрите [скриншот-тур](https://triliumnext.github.io/Docs/Wiki/screenshot-tour):
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## 🎁 Возможности
|
||||
|
||||
* Заметки можно расположить в виде дерева произвольной глубины. Отдельную заметку можно разместить в нескольких местах дерева (см. [клонирование](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Продвинутый визуальный редактор (WYSIWYG) позволяет работать с таблицами, изображениями, [формулами](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) и разметкой markdown, имеет [автоформатирование](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Редактирование [заметок с исходным кодом](https://triliumnext.github.io/Docs/Wiki/code-notes), включая подсветку синтаксиса
|
||||
* Быстрая и простая [навигация между заметками](https://triliumnext.github.io/Docs/Wiki/note-navigation), полнотекстовый поиск и [выделение заметок](https://triliumnext.github.io/Docs/Wiki/note-hoisting) в отдельный блок
|
||||
* Бесшовное [версионирование заметки](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Специальные [атрибуты](https://triliumnext.github.io/Docs/Wiki/attributes) позволяют гибко организовать структуру, используются для поиска и продвинутого [скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* [Синхронизация](https://triliumnext.github.io/Docs/Wiki/synchronization) заметок со своим сервером
|
||||
* Надёжное [шифрование](https://triliumnext.github.io/Docs/Wiki/protected-notes) с детализацией по каждой заметке
|
||||
* [Карты связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [карты ссылок](https://triliumnext.github.io/Docs/Wiki/link-map) для визуализации их взяимосвязей
|
||||
* [Скрипты](https://triliumnext.github.io/Docs/Wiki/scripts) - см. [продвинутые примеры](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* Хорошо масштабируется, как по удобству использования, так и по производительности до 100000 заметок
|
||||
* Оптимизированный [мобильный фронтенд](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) смартфонов и планшетов
|
||||
* [Темная тема](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* Импорт и экпорт [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) и данных в [markdown](https://triliumnext.github.io/Docs/Wiki/markdown) формате
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) для удобного сохранения веб-контента
|
||||
|
||||
## 🏗 Сборки
|
||||
|
||||
Trilium предоставляется в виде десктопного приложения (Linux и Windows) или веб-приложения, размещенного на вашем сервере (Linux). Доступна сборка Mac OS, но она [не поддерживается](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support).
|
||||
|
||||
* Если вы хотите использовать Trilium на десктопе, скачайте архив для своей платформы со страницы [релизов](https://github.com/TriliumNext/Notes/releases/latest), распакуйте и запустите исполняемый файл ```trilium```.
|
||||
* Если вы хотите установить Trilium на сервере, следуйте этой [инструкции](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
* В данный момент поддерживаются (протестированы) последние версии браузеров Chrome и Firefox.
|
||||
|
||||
## 📝 Документация
|
||||
|
||||
[Полный список страниц документации доступен в Wiki.](https://triliumnext.github.io/Docs/)
|
||||
|
||||
Вы также можете ознакомиться с [шаблонами персональных баз знаний](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge), чтобы получить представление о том, как можно использовать Trilium.
|
||||
|
||||
## 💻 Участвуйте в разработке
|
||||
|
||||
Или склонируйте на своё устройство и запустите
|
||||
|
||||
```shell
|
||||
npm install
|
||||
npm run start-server
|
||||
```
|
||||
|
||||
## 👏 Благодарности
|
||||
|
||||
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - лучший WYSIWYG редактор, очень активная и внимательная команда.
|
||||
* [FancyTree](https://github.com/mar10/fancytree) - многофункциональная библиотека для создания древовидных структур. Вне конкуренции. Без него Trilium Notes не были бы таким.
|
||||
* [CodeMirror](https://github.com/codemirror/CodeMirror) - редактор кода с поддержкой огромного количество языков.
|
||||
* [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека для визуализации связей. Вне конкуренции. Используется в [картах связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [картах ссылок](https://triliumnext.github.io/Docs/Wiki/link-map).
|
||||
|
||||
## 🔑 Лицензия
|
||||
|
||||
Эта программа является бесплатным программным обеспечением: вы можете распространять и/или изменять ее в соответствии с условиями GNU Affero General Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, либо (по вашему выбору) любой более поздней версии.
|
||||
13
_check_ts_progress.sh
Executable file
13
_check_ts_progress.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd src/public
|
||||
echo Summary
|
||||
cloc HEAD \
|
||||
--git --md \
|
||||
--include-lang=javascript,typescript
|
||||
|
||||
echo By file
|
||||
cloc HEAD \
|
||||
--git --md \
|
||||
--include-lang=javascript,typescript \
|
||||
--by-file | grep \.js\|
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
echo "Missing argument of new version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "Missing command: jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
|
||||
if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ;
|
||||
then
|
||||
echo "Version ${VERSION} isn't in format X.Y.Z"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
echo "There are uncommitted changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Releasing Trilium $VERSION"
|
||||
|
||||
jq '.version = "'$VERSION'"' package.json > package.json.tmp
|
||||
mv package.json.tmp package.json
|
||||
|
||||
git add package.json
|
||||
|
||||
npm run chore:update-build-info
|
||||
|
||||
git add src/services/build.ts
|
||||
|
||||
TAG=v$VERSION
|
||||
|
||||
echo "Committing package.json version change"
|
||||
|
||||
git commit -m "chore(release): $VERSION"
|
||||
git push
|
||||
|
||||
echo "Tagging commit with $TAG"
|
||||
|
||||
git tag $TAG
|
||||
git push origin $TAG
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,51 +0,0 @@
|
||||
import eslint from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
||||
|
||||
export default tseslint.config(
|
||||
eslint.configs.recommended,
|
||||
tseslint.configs.recommended,
|
||||
// consider using rules below, once we have a full TS codebase and can be more strict
|
||||
// tseslint.configs.strictTypeChecked,
|
||||
// tseslint.configs.stylisticTypeChecked,
|
||||
// tseslint.configs.recommendedTypeChecked,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
plugins: {
|
||||
"simple-import-sort": simpleImportSort
|
||||
}
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
// add rule overrides here
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_"
|
||||
}
|
||||
],
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
ignores: [
|
||||
"build/*",
|
||||
"dist/*",
|
||||
"docs/*",
|
||||
"demo/*",
|
||||
"src/public/app-dist/*",
|
||||
"src/public/app/doc_notes/*"
|
||||
]
|
||||
}
|
||||
);
|
||||
@@ -1,47 +0,0 @@
|
||||
import stylistic from "@stylistic/eslint-plugin";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
|
||||
// eslint config just for formatting rules
|
||||
// potentially to be merged with the linting rules into one single config,
|
||||
// once we have fixed the majority of lint errors
|
||||
|
||||
// Go to https://eslint.style/rules/default/${rule_without_prefix} to check the rule details
|
||||
export const stylisticRules = {
|
||||
"@stylistic/indent": [ "error", 4 ],
|
||||
"@stylistic/quotes": [ "error", "double", { avoidEscape: true, allowTemplateLiterals: "always" } ],
|
||||
"@stylistic/semi": [ "error", "always" ],
|
||||
"@stylistic/quote-props": [ "error", "consistent-as-needed" ],
|
||||
"@stylistic/max-len": [ "error", { code: 100 } ],
|
||||
"@stylistic/comma-dangle": [ "error", "never" ],
|
||||
"@stylistic/linebreak-style": [ "error", "unix" ],
|
||||
"@stylistic/array-bracket-spacing": [ "error", "always" ],
|
||||
"@stylistic/object-curly-spacing": [ "error", "always" ],
|
||||
"@stylistic/padded-blocks": [ "error", { classes: "always" } ]
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
files: [ "**/*.{js,ts,mjs,cjs}" ],
|
||||
languageOptions: {
|
||||
parser: tsParser
|
||||
},
|
||||
plugins: {
|
||||
"@stylistic": stylistic
|
||||
},
|
||||
rules: {
|
||||
...stylisticRules
|
||||
}
|
||||
},
|
||||
{
|
||||
ignores: [
|
||||
"build/*",
|
||||
"dist/*",
|
||||
"docs/*",
|
||||
"demo/*",
|
||||
// TriliumNextTODO: check if we want to format packages here as well - for now skipping it
|
||||
"packages/*",
|
||||
"src/public/app-dist/*",
|
||||
"src/public/app/doc_notes/*"
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"main": "./electron-main.js",
|
||||
"bin": {
|
||||
"trilium": "src/main.js"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nodemon src/main.ts",
|
||||
"server:start-no-dir": "cross-env TRILIUM_ENV=dev nodemon src/main.ts",
|
||||
"server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts",
|
||||
"server:qstart": "npm run server:switch && npm run server:start",
|
||||
"server:switch": "rimraf ./node_modules/better-sqlite3 && npm install",
|
||||
"electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev TRILIUM_PORT=37742 electron --inspect=5858 .",
|
||||
"electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
||||
"electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev TRILIUM_PORT=37742 nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"",
|
||||
"electron:start-prod-no-dir": "npm run build:prepare-dist && cross-env TRILIUM_ENV=prod electron --inspect=5858 .",
|
||||
"electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
||||
"electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"",
|
||||
"electron:qstart": "npm run electron:switch && npm run electron:start",
|
||||
"electron:switch": "electron-rebuild",
|
||||
"docs:build": "typedoc",
|
||||
"test": "npm run client:test && npm run server:test",
|
||||
"client:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app",
|
||||
"client:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app --coverage",
|
||||
"test:playwright": "playwright test --workers 1",
|
||||
"test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
"test:integration-mem-db": "cross-env nodemon src/main.ts",
|
||||
"test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
"dev:watch-dist": "tsx ./bin/watch-dist.ts",
|
||||
"dev:format-check": "eslint -c eslint.format.config.js .",
|
||||
"dev:format-fix": "eslint -c eslint.format.config.js . --fix",
|
||||
"dev:linter-check": "eslint .",
|
||||
"dev:linter-fix": "eslint . --fix",
|
||||
"chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000",
|
||||
"chore:generate-openapi": "tsx bin/generate-openapi.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.57.0",
|
||||
"@stylistic/eslint-plugin": "5.6.1",
|
||||
"@types/express": "5.0.5",
|
||||
"@types/node": "24.10.1",
|
||||
"@types/yargs": "17.0.35",
|
||||
"@vitest/coverage-v8": "4.0.14",
|
||||
"eslint": "9.39.1",
|
||||
"eslint-plugin-simple-import-sort": "12.1.1",
|
||||
"esm": "3.2.25",
|
||||
"jsdoc": "4.0.5",
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"rcedit": "5.0.2",
|
||||
"rimraf": "6.1.2",
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"appdmg": "0.6.6"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import etapi from "../support/etapi.js";
|
||||
/* TriliumNextTODO: port to Vitest
|
||||
etapi.describeEtapi("app_info", () => {
|
||||
it("get", async () => {
|
||||
const appInfo = await etapi.getEtapi("app-info");
|
||||
expect(appInfo.clipperProtocolVersion).toEqual("1.0");
|
||||
});
|
||||
});
|
||||
*/
|
||||
@@ -1,10 +0,0 @@
|
||||
import etapi from "../support/etapi.js";
|
||||
|
||||
/* TriliumNextTODO: port to Vitest
|
||||
etapi.describeEtapi("backup", () => {
|
||||
it("create", async () => {
|
||||
const response = await etapi.putEtapiContent("backup/etapi_test");
|
||||
expect(response.status).toEqual(204);
|
||||
});
|
||||
});
|
||||
*/
|
||||
@@ -1,26 +0,0 @@
|
||||
import etapi from "../support/etapi.js";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
/* TriliumNextTODO: port to Vitest
|
||||
etapi.describeEtapi("import", () => {
|
||||
// temporarily skip this test since test-export.zip is missing
|
||||
xit("import", async () => {
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const zipFileBuffer = fs.readFileSync(path.resolve(scriptDir, "test-export.zip"));
|
||||
|
||||
const response = await etapi.postEtapiContent("notes/root/import", zipFileBuffer);
|
||||
expect(response.status).toEqual(201);
|
||||
|
||||
const { note, branch } = await response.json();
|
||||
|
||||
expect(note.title).toEqual("test-export");
|
||||
expect(branch.parentNoteId).toEqual("root");
|
||||
|
||||
const content = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text();
|
||||
expect(content).toContain("test export content");
|
||||
});
|
||||
});
|
||||
*/
|
||||
@@ -1,103 +0,0 @@
|
||||
import crypto from "crypto";
|
||||
import etapi from "../support/etapi.js";
|
||||
|
||||
/* TriliumNextTODO: port to Vitest
|
||||
etapi.describeEtapi("notes", () => {
|
||||
it("create", async () => {
|
||||
const { note, branch } = await etapi.postEtapi("create-note", {
|
||||
parentNoteId: "root",
|
||||
type: "text",
|
||||
title: "Hello World!",
|
||||
content: "Content",
|
||||
prefix: "Custom prefix"
|
||||
});
|
||||
|
||||
expect(note.title).toEqual("Hello World!");
|
||||
expect(branch.parentNoteId).toEqual("root");
|
||||
expect(branch.prefix).toEqual("Custom prefix");
|
||||
|
||||
const rNote = await etapi.getEtapi(`notes/${note.noteId}`);
|
||||
expect(rNote.title).toEqual("Hello World!");
|
||||
|
||||
const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text();
|
||||
expect(rContent).toEqual("Content");
|
||||
|
||||
const rBranch = await etapi.getEtapi(`branches/${branch.branchId}`);
|
||||
expect(rBranch.parentNoteId).toEqual("root");
|
||||
expect(rBranch.prefix).toEqual("Custom prefix");
|
||||
});
|
||||
|
||||
it("patch", async () => {
|
||||
const { note } = await etapi.postEtapi("create-note", {
|
||||
parentNoteId: "root",
|
||||
type: "text",
|
||||
title: "Hello World!",
|
||||
content: "Content"
|
||||
});
|
||||
|
||||
await etapi.patchEtapi(`notes/${note.noteId}`, {
|
||||
title: "new title",
|
||||
type: "code",
|
||||
mime: "text/apl",
|
||||
dateCreated: "2000-01-01 12:34:56.999+0200",
|
||||
utcDateCreated: "2000-01-01 10:34:56.999Z"
|
||||
});
|
||||
|
||||
const rNote = await etapi.getEtapi(`notes/${note.noteId}`);
|
||||
expect(rNote.title).toEqual("new title");
|
||||
expect(rNote.type).toEqual("code");
|
||||
expect(rNote.mime).toEqual("text/apl");
|
||||
expect(rNote.dateCreated).toEqual("2000-01-01 12:34:56.999+0200");
|
||||
expect(rNote.utcDateCreated).toEqual("2000-01-01 10:34:56.999Z");
|
||||
});
|
||||
|
||||
it("update content", async () => {
|
||||
const { note } = await etapi.postEtapi("create-note", {
|
||||
parentNoteId: "root",
|
||||
type: "text",
|
||||
title: "Hello World!",
|
||||
content: "Content"
|
||||
});
|
||||
|
||||
await etapi.putEtapiContent(`notes/${note.noteId}/content`, "new content");
|
||||
|
||||
const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text();
|
||||
expect(rContent).toEqual("new content");
|
||||
});
|
||||
|
||||
it("create / update binary content", async () => {
|
||||
const { note } = await etapi.postEtapi("create-note", {
|
||||
parentNoteId: "root",
|
||||
type: "file",
|
||||
title: "Hello World!",
|
||||
content: "ZZZ"
|
||||
});
|
||||
|
||||
const updatedContent = crypto.randomBytes(16);
|
||||
|
||||
await etapi.putEtapiContent(`notes/${note.noteId}/content`, updatedContent);
|
||||
|
||||
const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).arrayBuffer();
|
||||
expect(Buffer.from(new Uint8Array(rContent))).toEqual(updatedContent);
|
||||
});
|
||||
|
||||
it("delete note", async () => {
|
||||
const { note } = await etapi.postEtapi("create-note", {
|
||||
parentNoteId: "root",
|
||||
type: "text",
|
||||
title: "Hello World!",
|
||||
content: "Content"
|
||||
});
|
||||
|
||||
await etapi.deleteEtapi(`notes/${note.noteId}`);
|
||||
|
||||
const resp = await etapi.getEtapiResponse(`notes/${note.noteId}`);
|
||||
expect(resp.status).toEqual(404);
|
||||
|
||||
const error = await resp.json();
|
||||
expect(error.status).toEqual(404);
|
||||
expect(error.code).toEqual("NOTE_NOT_FOUND");
|
||||
expect(error.message).toEqual(`Note '${note.noteId}' not found.`);
|
||||
});
|
||||
});
|
||||
*/
|
||||
@@ -1,152 +0,0 @@
|
||||
import { describe, beforeAll, afterAll } from "vitest";
|
||||
|
||||
let etapiAuthToken: string | undefined;
|
||||
|
||||
const getEtapiAuthorizationHeader = (): string => "Basic " + Buffer.from(`etapi:${etapiAuthToken}`).toString("base64");
|
||||
|
||||
const PORT: string = "9999";
|
||||
const HOST: string = "http://localhost:" + PORT;
|
||||
|
||||
type SpecDefinitionsFunc = () => void;
|
||||
|
||||
function describeEtapi(description: string, specDefinitions: SpecDefinitionsFunc): void {
|
||||
describe(description, () => {
|
||||
beforeAll(async () => {});
|
||||
|
||||
afterAll(() => {});
|
||||
|
||||
specDefinitions();
|
||||
});
|
||||
}
|
||||
|
||||
async function getEtapiResponse(url: string): Promise<Response> {
|
||||
return await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getEtapi(url: string): Promise<any> {
|
||||
const response = await getEtapiResponse(url);
|
||||
return await processEtapiResponse(response);
|
||||
}
|
||||
|
||||
async function getEtapiContent(url: string): Promise<Response> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
}
|
||||
});
|
||||
|
||||
checkStatus(response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function postEtapi(url: string, data: Record<string, unknown> = {}): Promise<any> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
return await processEtapiResponse(response);
|
||||
}
|
||||
|
||||
async function postEtapiContent(url: string, data: BodyInit): Promise<Response> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
},
|
||||
body: data
|
||||
});
|
||||
|
||||
checkStatus(response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function putEtapi(url: string, data: Record<string, unknown> = {}): Promise<any> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
return await processEtapiResponse(response);
|
||||
}
|
||||
|
||||
async function putEtapiContent(url: string, data?: BodyInit): Promise<Response> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
},
|
||||
body: data
|
||||
});
|
||||
|
||||
checkStatus(response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function patchEtapi(url: string, data: Record<string, unknown> = {}): Promise<any> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
return await processEtapiResponse(response);
|
||||
}
|
||||
|
||||
async function deleteEtapi(url: string): Promise<any> {
|
||||
const response = await fetch(`${HOST}/etapi/${url}`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: getEtapiAuthorizationHeader()
|
||||
}
|
||||
});
|
||||
return await processEtapiResponse(response);
|
||||
}
|
||||
|
||||
async function processEtapiResponse(response: Response): Promise<any> {
|
||||
const text = await response.text();
|
||||
|
||||
if (response.status < 200 || response.status >= 300) {
|
||||
throw new Error(`ETAPI error ${response.status}: ${text}`);
|
||||
}
|
||||
|
||||
return text?.trim() ? JSON.parse(text) : null;
|
||||
}
|
||||
|
||||
function checkStatus(response: Response): void {
|
||||
if (response.status < 200 || response.status >= 300) {
|
||||
throw new Error(`ETAPI error ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
describeEtapi,
|
||||
getEtapi,
|
||||
getEtapiResponse,
|
||||
getEtapiContent,
|
||||
postEtapi,
|
||||
postEtapiContent,
|
||||
putEtapi,
|
||||
putEtapiContent,
|
||||
patchEtapi,
|
||||
deleteEtapi
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "build-docs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/main.ts",
|
||||
"scripts": {
|
||||
"start": "tsx ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Elian Doran <contact@eliandoran.me>",
|
||||
"license": "AGPL-3.0-only",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"devDependencies": {
|
||||
"@redocly/cli": "2.12.0",
|
||||
"archiver": "7.0.1",
|
||||
"fs-extra": "11.3.2",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"typedoc": "0.28.15",
|
||||
"typedoc-plugin-missing-exports": "4.1.2"
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* The backend script API is accessible to code notes with the "JS (backend)" language.
|
||||
*
|
||||
* The entire API is exposed as a single global: {@link api}
|
||||
*
|
||||
* @module Backend Script API
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file creates the entrypoint for TypeDoc that simulates the context from within a
|
||||
* script note on the server side.
|
||||
*
|
||||
* Make sure to keep in line with backend's `script_context.ts`.
|
||||
*/
|
||||
|
||||
export type { default as AbstractBeccaEntity } from "../../server/src/becca/entities/abstract_becca_entity.js";
|
||||
export type { default as BAttachment } from "../../server/src/becca/entities/battachment.js";
|
||||
export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js";
|
||||
export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js";
|
||||
export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js";
|
||||
export type { BNote };
|
||||
export type { default as BOption } from "../../server/src/becca/entities/boption.js";
|
||||
export type { default as BRecentNote } from "../../server/src/becca/entities/brecent_note.js";
|
||||
export type { default as BRevision } from "../../server/src/becca/entities/brevision.js";
|
||||
|
||||
import BNote from "../../server/src/becca/entities/bnote.js";
|
||||
import BackendScriptApi, { type Api } from "../../server/src/services/backend_script_api.js";
|
||||
|
||||
export type { Api };
|
||||
|
||||
const fakeNote = new BNote();
|
||||
|
||||
/**
|
||||
* The `api` global variable allows access to the backend script API, which is documented in {@link Api}.
|
||||
*/
|
||||
export const api: Api = new BackendScriptApi(fakeNote, {});
|
||||
@@ -1,147 +0,0 @@
|
||||
process.env.TRILIUM_INTEGRATION_TEST = "memory-no-store";
|
||||
process.env.TRILIUM_RESOURCE_DIR = "../server/src";
|
||||
process.env.NODE_ENV = "development";
|
||||
|
||||
import cls from "@triliumnext/server/src/services/cls.js";
|
||||
import { dirname, join, resolve } from "path";
|
||||
import * as fs from "fs/promises";
|
||||
import * as fsExtra from "fs-extra";
|
||||
import archiver from "archiver";
|
||||
import { WriteStream } from "fs";
|
||||
import { execSync } from "child_process";
|
||||
import BuildContext from "./context.js";
|
||||
|
||||
const DOCS_ROOT = "../../../docs";
|
||||
const OUTPUT_DIR = "../../site";
|
||||
|
||||
async function importAndExportDocs(sourcePath: string, outputSubDir: string) {
|
||||
const note = await importData(sourcePath);
|
||||
|
||||
// Use a meaningful name for the temporary zip file
|
||||
const zipName = outputSubDir || "user-guide";
|
||||
const zipFilePath = `output-${zipName}.zip`;
|
||||
try {
|
||||
const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js")).default;
|
||||
const branch = note.getParentBranches()[0];
|
||||
const taskContext = new (await import("@triliumnext/server/src/services/task_context.js")).default(
|
||||
"no-progress-reporting",
|
||||
"export",
|
||||
null
|
||||
);
|
||||
const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
|
||||
await exportToZip(taskContext, branch, "share", fileOutputStream);
|
||||
await waitForStreamToFinish(fileOutputStream);
|
||||
|
||||
// Output to root directory if outputSubDir is empty, otherwise to subdirectory
|
||||
const outputPath = outputSubDir ? join(OUTPUT_DIR, outputSubDir) : OUTPUT_DIR;
|
||||
await extractZip(zipFilePath, outputPath);
|
||||
} finally {
|
||||
if (await fsExtra.exists(zipFilePath)) {
|
||||
await fsExtra.rm(zipFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function buildDocsInner() {
|
||||
const i18n = await import("@triliumnext/server/src/services/i18n.js");
|
||||
await i18n.initializeTranslations();
|
||||
|
||||
const sqlInit = (await import("../../server/src/services/sql_init.js")).default;
|
||||
await sqlInit.createInitialDatabase(true);
|
||||
|
||||
// Wait for becca to be loaded before importing data
|
||||
const beccaLoader = await import("../../server/src/becca/becca_loader.js");
|
||||
await beccaLoader.beccaLoaded;
|
||||
|
||||
// Build User Guide
|
||||
console.log("Building User Guide...");
|
||||
await importAndExportDocs(join(__dirname, DOCS_ROOT, "User Guide"), "user-guide");
|
||||
|
||||
// Build Developer Guide
|
||||
console.log("Building Developer Guide...");
|
||||
await importAndExportDocs(join(__dirname, DOCS_ROOT, "Developer Guide"), "developer-guide");
|
||||
|
||||
// Copy favicon.
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "user-guide", "favicon.ico"));
|
||||
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "developer-guide", "favicon.ico"));
|
||||
|
||||
console.log("Documentation built successfully!");
|
||||
}
|
||||
|
||||
export async function importData(path: string) {
|
||||
const buffer = await createImportZip(path);
|
||||
const importService = (await import("../../server/src/services/import/zip.js")).default;
|
||||
const TaskContext = (await import("../../server/src/services/task_context.js")).default;
|
||||
const context = new TaskContext("no-progress-reporting", "importNotes", null);
|
||||
const becca = (await import("../../server/src/becca/becca.js")).default;
|
||||
|
||||
const rootNote = becca.getRoot();
|
||||
if (!rootNote) {
|
||||
throw new Error("Missing root note for import.");
|
||||
}
|
||||
return await importService.importZip(context, buffer, rootNote, {
|
||||
preserveIds: true
|
||||
});
|
||||
}
|
||||
|
||||
async function createImportZip(path: string) {
|
||||
const inputFile = "input.zip";
|
||||
const archive = archiver("zip", {
|
||||
zlib: { level: 0 }
|
||||
});
|
||||
|
||||
console.log("Archive path is ", resolve(path))
|
||||
archive.directory(path, "/");
|
||||
|
||||
const outputStream = fsExtra.createWriteStream(inputFile);
|
||||
archive.pipe(outputStream);
|
||||
archive.finalize();
|
||||
await waitForStreamToFinish(outputStream);
|
||||
|
||||
try {
|
||||
return await fsExtra.readFile(inputFile);
|
||||
} finally {
|
||||
await fsExtra.rm(inputFile);
|
||||
}
|
||||
}
|
||||
|
||||
function waitForStreamToFinish(stream: WriteStream) {
|
||||
return new Promise<void>((res, rej) => {
|
||||
stream.on("finish", () => res());
|
||||
stream.on("error", (err) => rej(err));
|
||||
});
|
||||
}
|
||||
|
||||
export async function extractZip(zipFilePath: string, outputPath: string, ignoredFiles?: Set<string>) {
|
||||
const { readZipFile, readContent } = (await import("@triliumnext/server/src/services/import/zip.js"));
|
||||
await readZipFile(await fs.readFile(zipFilePath), async (zip, entry) => {
|
||||
// We ignore directories since they can appear out of order anyway.
|
||||
if (!entry.fileName.endsWith("/") && !ignoredFiles?.has(entry.fileName)) {
|
||||
const destPath = join(outputPath, entry.fileName);
|
||||
const fileContent = await readContent(zip, entry);
|
||||
|
||||
await fsExtra.mkdirs(dirname(destPath));
|
||||
await fs.writeFile(destPath, fileContent);
|
||||
}
|
||||
|
||||
zip.readEntry();
|
||||
});
|
||||
}
|
||||
|
||||
export default async function buildDocs({ gitRootDir }: BuildContext) {
|
||||
// Build the share theme.
|
||||
execSync(`pnpm run --filter share-theme build`, {
|
||||
stdio: "inherit",
|
||||
cwd: gitRootDir
|
||||
});
|
||||
|
||||
// Trigger the actual build.
|
||||
await new Promise((res, rej) => {
|
||||
cls.init(() => {
|
||||
buildDocsInner()
|
||||
.catch(rej)
|
||||
.then(res);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export default interface BuildContext {
|
||||
gitRootDir: string;
|
||||
baseDir: string;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* The front script API is accessible to code notes with the "JS (frontend)" language.
|
||||
*
|
||||
* The entire API is exposed as a single global: {@link api}
|
||||
*
|
||||
* @module Frontend Script API
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file creates the entrypoint for TypeDoc that simulates the context from within a
|
||||
* script note.
|
||||
*
|
||||
* Make sure to keep in line with frontend's `script_context.ts`.
|
||||
*/
|
||||
|
||||
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
|
||||
export type { default as FAttachment } from "../../client/src/entities/fattachment.js";
|
||||
export type { default as FAttribute } from "../../client/src/entities/fattribute.js";
|
||||
export type { default as FBranch } from "../../client/src/entities/fbranch.js";
|
||||
export type { default as FNote } from "../../client/src/entities/fnote.js";
|
||||
export type { Api } from "../../client/src/services/frontend_script_api.js";
|
||||
export type { default as NoteContextAwareWidget } from "../../client/src/widgets/note_context_aware_widget.js";
|
||||
export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js";
|
||||
|
||||
import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js";
|
||||
|
||||
//@ts-expect-error
|
||||
export const api: Api = new FrontendScriptApi();
|
||||
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=/user-guide">
|
||||
<title>Redirecting...</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>If you are not redirected automatically, <a href="/user-guide">click here</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
import { join } from "path";
|
||||
import BuildContext from "./context";
|
||||
import buildSwagger from "./swagger";
|
||||
import { cpSync, existsSync, mkdirSync, rmSync } from "fs";
|
||||
import buildDocs from "./build-docs";
|
||||
import buildScriptApi from "./script-api";
|
||||
|
||||
const context: BuildContext = {
|
||||
gitRootDir: join(__dirname, "../../../"),
|
||||
baseDir: join(__dirname, "../../../site")
|
||||
};
|
||||
|
||||
async function main() {
|
||||
// Clean input dir.
|
||||
if (existsSync(context.baseDir)) {
|
||||
rmSync(context.baseDir, { recursive: true });
|
||||
}
|
||||
mkdirSync(context.baseDir);
|
||||
|
||||
// Start building.
|
||||
await buildDocs(context);
|
||||
buildSwagger(context);
|
||||
buildScriptApi(context);
|
||||
|
||||
// Copy index and 404 files.
|
||||
cpSync(join(__dirname, "index.html"), join(context.baseDir, "index.html"));
|
||||
cpSync(join(context.baseDir, "user-guide/404.html"), join(context.baseDir, "404.html"));
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,15 +0,0 @@
|
||||
import { execSync } from "child_process";
|
||||
import BuildContext from "./context";
|
||||
import { join } from "path";
|
||||
|
||||
export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) {
|
||||
// Generate types
|
||||
execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir });
|
||||
|
||||
for (const config of [ "backend", "frontend" ]) {
|
||||
const outDir = join(baseDir, "script-api", config);
|
||||
execSync(`pnpm typedoc --options typedoc.${config}.json --html "${outDir}"`, {
|
||||
stdio: "inherit"
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import BuildContext from "./context";
|
||||
import { join } from "path";
|
||||
import { execSync } from "child_process";
|
||||
import { mkdirSync } from "fs";
|
||||
|
||||
interface BuildInfo {
|
||||
specPath: string;
|
||||
outDir: string;
|
||||
}
|
||||
|
||||
const DIR_PREFIX = "rest-api";
|
||||
|
||||
const buildInfos: BuildInfo[] = [
|
||||
{
|
||||
// Paths are relative to Git root.
|
||||
specPath: "apps/server/internal.openapi.yaml",
|
||||
outDir: `${DIR_PREFIX}/internal`
|
||||
},
|
||||
{
|
||||
specPath: "apps/server/etapi.openapi.yaml",
|
||||
outDir: `${DIR_PREFIX}/etapi`
|
||||
}
|
||||
];
|
||||
|
||||
export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) {
|
||||
for (const { specPath, outDir } of buildInfos) {
|
||||
const absSpecPath = join(gitRootDir, specPath);
|
||||
const targetDir = join(baseDir, outDir);
|
||||
mkdirSync(targetDir, { recursive: true });
|
||||
execSync(`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, { stdio: "inherit" });
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"target": "ES2020",
|
||||
"outDir": "dist",
|
||||
"strict": false,
|
||||
"types": [
|
||||
"node",
|
||||
"express"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"../server/src/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"eslint.config.js",
|
||||
"eslint.config.cjs",
|
||||
"eslint.config.mjs"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../server/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "../desktop/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "../client/tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../server"
|
||||
},
|
||||
{
|
||||
"path": "../client"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"$schema": "https://typedoc.org/schema.json",
|
||||
"name": "Trilium Backend API",
|
||||
"entryPoints": [
|
||||
"src/backend_script_entrypoint.ts"
|
||||
],
|
||||
"plugin": [
|
||||
"typedoc-plugin-missing-exports"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"$schema": "https://typedoc.org/schema.json",
|
||||
"name": "Trilium Frontend API",
|
||||
"entryPoints": [
|
||||
"src/frontend_script_entrypoint.ts"
|
||||
],
|
||||
"plugin": [
|
||||
"typedoc-plugin-missing-exports"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# The development license key for premium CKEditor features.
|
||||
# Note: This key must only be used for the Trilium Notes project.
|
||||
VITE_CKEDITOR_KEY=eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3ODcyNzA0MDAsImp0aSI6IjkyMWE1MWNlLTliNDMtNGRlMC1iOTQwLTc5ZjM2MDBkYjg1NyIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOiJ0cmlsaXVtIiwiZmVhdHVyZXMiOlsiVFJJTElVTSJdLCJ2YyI6ImU4YzRhMjBkIn0.hny77p-U4-jTkoqbwPytrEar5ylGCWBN7Ez3SlB8i6_mJCBIeCSTOlVQk_JMiOEq3AGykUMHzWXzjdMFwgniOw
|
||||
VITE_CKEDITOR_ENABLE_INSPECTOR=false
|
||||
@@ -1 +0,0 @@
|
||||
VITE_CKEDITOR_ENABLE_INSPECTOR=false
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript"
|
||||
},
|
||||
"target": "es2016"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import baseConfig from "../../eslint.config.mjs";
|
||||
|
||||
export default [
|
||||
...baseConfig
|
||||
];
|
||||
@@ -1,82 +0,0 @@
|
||||
{
|
||||
"name": "@triliumnext/client",
|
||||
"version": "0.100.0",
|
||||
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0-only",
|
||||
"author": {
|
||||
"name": "Trilium Notes Team",
|
||||
"email": "contact@eliandoran.me",
|
||||
"url": "https://github.com/TriliumNext/Trilium"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build",
|
||||
"test": "vitest",
|
||||
"circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint/js": "9.39.1",
|
||||
"@excalidraw/excalidraw": "0.18.0",
|
||||
"@fullcalendar/core": "6.1.19",
|
||||
"@fullcalendar/daygrid": "6.1.19",
|
||||
"@fullcalendar/interaction": "6.1.19",
|
||||
"@fullcalendar/list": "6.1.19",
|
||||
"@fullcalendar/multimonth": "6.1.19",
|
||||
"@fullcalendar/timegrid": "6.1.19",
|
||||
"@maplibre/maplibre-gl-leaflet": "0.1.3",
|
||||
"@mermaid-js/layout-elk": "0.2.0",
|
||||
"@mind-elixir/node-menu": "5.0.1",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@triliumnext/ckeditor5": "workspace:*",
|
||||
"@triliumnext/codemirror": "workspace:*",
|
||||
"@triliumnext/commons": "workspace:*",
|
||||
"@triliumnext/highlightjs": "workspace:*",
|
||||
"@triliumnext/share-theme": "workspace:*",
|
||||
"@triliumnext/split.js": "workspace:*",
|
||||
"autocomplete.js": "0.38.1",
|
||||
"bootstrap": "5.3.8",
|
||||
"boxicons": "2.1.4",
|
||||
"clsx": "2.1.1",
|
||||
"color": "5.0.3",
|
||||
"debounce": "3.0.0",
|
||||
"draggabilly": "3.0.0",
|
||||
"force-graph": "1.51.0",
|
||||
"globals": "16.5.0",
|
||||
"i18next": "25.6.3",
|
||||
"i18next-http-backend": "3.0.2",
|
||||
"jquery": "3.7.1",
|
||||
"jquery.fancytree": "2.38.5",
|
||||
"jsplumb": "2.15.6",
|
||||
"katex": "0.16.25",
|
||||
"knockout": "3.5.1",
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-gpx": "2.2.0",
|
||||
"mark.js": "8.11.1",
|
||||
"marked": "17.0.1",
|
||||
"mermaid": "11.12.1",
|
||||
"mind-elixir": "5.3.7",
|
||||
"normalize.css": "8.0.1",
|
||||
"panzoom": "9.4.3",
|
||||
"preact": "10.27.2",
|
||||
"react-i18next": "16.3.5",
|
||||
"reveal.js": "5.2.1",
|
||||
"svg-pan-zoom": "3.6.2",
|
||||
"tabulator-tables": "6.3.1",
|
||||
"vanilla-js-wheel-zoom": "9.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ckeditor/ckeditor5-inspector": "5.0.0",
|
||||
"@preact/preset-vite": "2.10.2",
|
||||
"@types/bootstrap": "5.2.10",
|
||||
"@types/jquery": "3.5.33",
|
||||
"@types/leaflet": "1.9.21",
|
||||
"@types/leaflet-gpx": "1.3.8",
|
||||
"@types/mark.js": "8.11.12",
|
||||
"@types/reveal.js": "5.2.1",
|
||||
"@types/tabulator-tables": "6.3.0",
|
||||
"copy-webpack-plugin": "13.0.1",
|
||||
"happy-dom": "20.0.11",
|
||||
"script-loader": "0.7.2",
|
||||
"vite-plugin-static-copy": "3.1.4"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import packageJson from "../package.json" with { type: "json" };
|
||||
|
||||
export default `assets/v${packageJson.version}`;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user