Merge branch 'develop' into chore_eslint-fixes_src-routes
@ -1,10 +1,37 @@
|
||||
.git
|
||||
.idea
|
||||
# ignored Files
|
||||
.dockerignore
|
||||
.editorconfig
|
||||
.git*
|
||||
.prettier*
|
||||
electron*
|
||||
entitlements.plist
|
||||
forge.config.cjs
|
||||
nodemon.json
|
||||
renovate.json
|
||||
trilium.iml
|
||||
Dockerfile
|
||||
Dockerfile.*
|
||||
npm-debug.log
|
||||
/src/**/*.spec.ts
|
||||
|
||||
# ignored folders
|
||||
/.cache
|
||||
/.git
|
||||
/.github
|
||||
/.idea
|
||||
/.vscode
|
||||
/bin
|
||||
/build
|
||||
/dist
|
||||
/docs
|
||||
/npm-debug.log
|
||||
node_modules
|
||||
/dump-db
|
||||
/e2e
|
||||
/integration-tests
|
||||
/spec
|
||||
/test
|
||||
/test-etapi
|
||||
/node_modules
|
||||
|
||||
src/**/*.ts
|
||||
!src/services/asset_path.ts
|
||||
|
||||
# exceptions
|
||||
!/bin/copy-dist.ts
|
24
.github/workflows/dev.yml
vendored
@ -44,16 +44,6 @@ jobs:
|
||||
- test_dev
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- name: Run 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:
|
||||
@ -82,20 +72,6 @@ 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:
|
||||
|
15
.github/workflows/main-docker.yml
vendored
@ -57,9 +57,6 @@ jobs:
|
||||
- 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:
|
||||
@ -154,18 +151,6 @@ 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: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
|
6
.vscode/extensions.json
vendored
@ -1,3 +1,7 @@
|
||||
{
|
||||
"recommendations": ["lokalise.i18n-ally", "editorconfig.editorconfig"]
|
||||
"recommendations": [
|
||||
"lokalise.i18n-ally",
|
||||
"editorconfig.editorconfig",
|
||||
"vitest.explorer"
|
||||
]
|
||||
}
|
||||
|
4
.vscode/launch.json
vendored
@ -5,8 +5,8 @@
|
||||
{
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"name": "nodemon server:start",
|
||||
"program": "${workspaceFolder}/src/main",
|
||||
"name": "nodemon start-server",
|
||||
"program": "${workspaceFolder}/src/www",
|
||||
"request": "launch",
|
||||
"restart": true,
|
||||
"runtimeExecutable": "nodemon",
|
||||
|
9
.vscode/settings.json
vendored
@ -19,5 +19,12 @@
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "vscode.css-language-features"
|
||||
},
|
||||
"npm.exclude": ["**/build", "**/dist", "**/out/**"]
|
||||
"npm.exclude": [
|
||||
"**/build",
|
||||
"**/dist",
|
||||
"**/out/**"
|
||||
],
|
||||
"[xml]": {
|
||||
"editor.defaultFormatter": "redhat.vscode-xml"
|
||||
}
|
||||
}
|
||||
|
72
Dockerfile
@ -1,62 +1,46 @@
|
||||
# Build stage
|
||||
FROM node:22.14.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
|
||||
WORKDIR /usr/src/app/build
|
||||
|
||||
# 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 build:webpack && \
|
||||
npm prune --omit=dev && \
|
||||
RUN npm ci && \
|
||||
npm run build:prepare-dist && \
|
||||
npm cache clean --force && \
|
||||
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
|
||||
rm -rf dist/node_modules && \
|
||||
mv dist/* \
|
||||
start-docker.sh \
|
||||
/usr/src/app/ && \
|
||||
rm -rf \
|
||||
/usr/src/app/build \
|
||||
/tmp/node-compile-cache
|
||||
|
||||
#TODO: improve node_modules handling in copy-dist/Dockerfile -> remove duplicated work
|
||||
# currently copy-dist will copy certain node_module folders, but in the Dockerfile we delete them again (to keep image size down),
|
||||
# as we install necessary dependencies in runtime buildstage anyways
|
||||
|
||||
# Runtime stage
|
||||
FROM node:22.14.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
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
gosu && \
|
||||
rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/cache/apt/*
|
||||
|
||||
COPY --from=builder /usr/src/app ./
|
||||
|
||||
RUN sed -i "/electron/d" package.json && \
|
||||
npm ci --omit=dev && \
|
||||
npm cache clean --force && \
|
||||
rm -rf /tmp/node-compile-cache
|
||||
|
||||
# Configure container
|
||||
EXPOSE 8080
|
||||
|
@ -1,38 +1,26 @@
|
||||
# Build stage
|
||||
FROM node:22.14.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
|
||||
WORKDIR /usr/src/app/build
|
||||
|
||||
# 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 build:webpack && \
|
||||
npm prune --omit=dev && \
|
||||
RUN npm ci && \
|
||||
npm run build:prepare-dist && \
|
||||
npm cache clean --force && \
|
||||
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
|
||||
rm -rf dist/node_modules && \
|
||||
mv dist/* \
|
||||
start-docker.sh \
|
||||
/usr/src/app/ && \
|
||||
rm -rf \
|
||||
/usr/src/app/build \
|
||||
/tmp/node-compile-cache
|
||||
|
||||
#TODO: improve node_modules handling in copy-dist/Dockerfile -> remove duplicated work
|
||||
# currently copy-dist will copy certain node_module folders, but in the Dockerfile we delete them again (to keep image size down),
|
||||
# as we install necessary dependencies in runtime buildstage anyways
|
||||
|
||||
# Runtime stage
|
||||
FROM node:22.14.0-alpine
|
||||
@ -42,17 +30,12 @@ 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
|
||||
COPY --from=builder /usr/src/app ./
|
||||
|
||||
RUN sed -i "/electron/d" package.json && \
|
||||
npm ci --omit=dev && \
|
||||
npm cache clean --force && \
|
||||
rm -rf /tmp/node-compile-cache
|
||||
|
||||
# Add application user
|
||||
RUN adduser -s /bin/false node; exit 0
|
||||
|
@ -5,11 +5,6 @@ set -e # Fail on any command error
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
SERIES=${VERSION:0:4}-latest
|
||||
|
||||
cat package.json | grep -v electron > server-package.json
|
||||
|
||||
echo "Compiling typescript..."
|
||||
npx tsc
|
||||
|
||||
sudo docker build -t triliumnext/notes:$VERSION --network host -t triliumnext/notes:$SERIES .
|
||||
|
||||
if [[ $VERSION != *"beta"* ]]; then
|
||||
|
@ -2,8 +2,6 @@ import fs from "fs-extra";
|
||||
import path from "path";
|
||||
|
||||
const DEST_DIR = "./dist";
|
||||
const DEST_DIR_SRC = path.join(DEST_DIR, "src");
|
||||
const DEST_DIR_NODE_MODULES = path.join(DEST_DIR, "node_modules");
|
||||
|
||||
const VERBOSE = process.env.VERBOSE;
|
||||
|
||||
@ -13,43 +11,37 @@ function log(...args: any[]) {
|
||||
}
|
||||
}
|
||||
|
||||
async function copyNodeModuleFileOrFolder(source: string) {
|
||||
const adjustedSource = source.substring(13);
|
||||
const destination = path.join(DEST_DIR_NODE_MODULES, adjustedSource);
|
||||
|
||||
function copyNodeModuleFileOrFolder(source: string) {
|
||||
const destination = path.join(DEST_DIR, source);
|
||||
log(`Copying ${source} to ${destination}`);
|
||||
await fs.ensureDir(path.dirname(destination));
|
||||
await fs.copy(source, destination);
|
||||
fs.ensureDirSync(path.dirname(destination));
|
||||
fs.copySync(source, destination);
|
||||
}
|
||||
|
||||
const copy = async () => {
|
||||
for (const srcFile of fs.readdirSync("build")) {
|
||||
const destFile = path.join(DEST_DIR, path.basename(srcFile));
|
||||
log(`Copying source ${srcFile} -> ${destFile}.`);
|
||||
fs.copySync(path.join("build", srcFile), destFile, { recursive: true });
|
||||
}
|
||||
try {
|
||||
|
||||
const filesToCopy = [
|
||||
"config-sample.ini",
|
||||
"tsconfig.webpack.json",
|
||||
const assetsToCopy = new Set([
|
||||
"./images",
|
||||
"./libraries",
|
||||
"./translations",
|
||||
"./db",
|
||||
"./config-sample.ini",
|
||||
"./package-lock.json",
|
||||
"./package.json",
|
||||
"./src/views/",
|
||||
"./src/etapi/etapi.openapi.yaml",
|
||||
"./src/routes/api/openapi.json"
|
||||
];
|
||||
for (const file of filesToCopy) {
|
||||
log(`Copying ${file}`);
|
||||
await fs.copy(file, path.join(DEST_DIR, file));
|
||||
}
|
||||
"./src/routes/api/openapi.json",
|
||||
"./src/public/icon.png",
|
||||
"./src/public/manifest.webmanifest",
|
||||
"./src/public/robots.txt",
|
||||
"./src/public/fonts",
|
||||
"./src/public/stylesheets",
|
||||
"./src/public/translations"
|
||||
]);
|
||||
|
||||
const dirsToCopy = ["images", "libraries", "translations", "db"];
|
||||
for (const dir of dirsToCopy) {
|
||||
log(`Copying ${dir}`);
|
||||
await fs.copy(dir, path.join(DEST_DIR, dir));
|
||||
}
|
||||
|
||||
const srcDirsToCopy = ["./src/public", "./src/views", "./build"];
|
||||
for (const dir of srcDirsToCopy) {
|
||||
log(`Copying ${dir}`);
|
||||
await fs.copy(dir, path.join(DEST_DIR_SRC, path.basename(dir)));
|
||||
for (const asset of assetsToCopy) {
|
||||
log(`Copying ${asset}`);
|
||||
fs.copySync(asset, path.join(DEST_DIR, asset));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,10 +50,10 @@ const copy = async () => {
|
||||
const publicDirsToCopy = ["./src/public/app/doc_notes"];
|
||||
const PUBLIC_DIR = path.join(DEST_DIR, "src", "public", "app-dist");
|
||||
for (const dir of publicDirsToCopy) {
|
||||
await fs.copy(dir, path.join(PUBLIC_DIR, path.basename(dir)));
|
||||
fs.copySync(dir, path.join(PUBLIC_DIR, path.basename(dir)));
|
||||
}
|
||||
|
||||
const nodeModulesFile = [
|
||||
const nodeModulesFile = new Set([
|
||||
"node_modules/react/umd/react.production.min.js",
|
||||
"node_modules/react/umd/react.development.js",
|
||||
"node_modules/react-dom/umd/react-dom.production.min.js",
|
||||
@ -71,13 +63,9 @@ const copy = async () => {
|
||||
"node_modules/katex/dist/contrib/auto-render.min.js",
|
||||
"node_modules/@highlightjs/cdn-assets/highlight.min.js",
|
||||
"node_modules/@mind-elixir/node-menu/dist/node-menu.umd.cjs"
|
||||
];
|
||||
]);
|
||||
|
||||
for (const file of nodeModulesFile) {
|
||||
await copyNodeModuleFileOrFolder(file);
|
||||
}
|
||||
|
||||
const nodeModulesFolder = [
|
||||
const nodeModulesFolder = new Set([
|
||||
"node_modules/@excalidraw/excalidraw/dist/",
|
||||
"node_modules/katex/dist/",
|
||||
"node_modules/dayjs/",
|
||||
@ -104,13 +92,15 @@ const copy = async () => {
|
||||
"node_modules/@highlightjs/cdn-assets/languages",
|
||||
"node_modules/@highlightjs/cdn-assets/styles",
|
||||
"node_modules/leaflet/dist"
|
||||
];
|
||||
]);
|
||||
|
||||
for (const folder of nodeModulesFolder) {
|
||||
await copyNodeModuleFileOrFolder(folder);
|
||||
|
||||
|
||||
for (const nodeModuleItem of [...nodeModulesFile, ...nodeModulesFolder]) {
|
||||
copyNodeModuleFileOrFolder(nodeModuleItem);
|
||||
}
|
||||
};
|
||||
console.log("Copying complete!")
|
||||
|
||||
copy()
|
||||
.then(() => console.log("Copying complete!"))
|
||||
.catch((err) => console.error("Error during copy:", err));
|
||||
} catch(err) {
|
||||
console.error("Error during copy:", err)
|
||||
}
|
@ -14,7 +14,7 @@ fi
|
||||
|
||||
# Trigger the TypeScript build
|
||||
echo TypeScript build start
|
||||
npx tsc
|
||||
npm run build:ts
|
||||
echo TypeScript build finished
|
||||
|
||||
# Copy the TypeScript artifacts
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
echo "Missing argument of new version"
|
||||
exit 1
|
||||
|
@ -1,10 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "tasks"
|
||||
(
|
||||
"taskId" TEXT NOT NULL PRIMARY KEY,
|
||||
"parentNoteId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL DEFAULT "",
|
||||
"dueDate" INTEGER,
|
||||
"isDone" INTEGER NOT NULL DEFAULT 0,
|
||||
"isDeleted" INTEGER NOT NULL DEFAULT 0,
|
||||
"utcDateModified" TEXT NOT NULL
|
||||
);
|
@ -132,14 +132,3 @@ CREATE INDEX IDX_attachments_ownerId_role
|
||||
CREATE INDEX IDX_notes_blobId on notes (blobId);
|
||||
CREATE INDEX IDX_revisions_blobId on revisions (blobId);
|
||||
CREATE INDEX IDX_attachments_blobId on attachments (blobId);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "tasks"
|
||||
(
|
||||
"taskId" TEXT NOT NULL PRIMARY KEY,
|
||||
"parentNoteId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL DEFAULT "",
|
||||
"dueDate" INTEGER,
|
||||
"isDone" INTEGER NOT NULL DEFAULT 0,
|
||||
"isDeleted" INTEGER NOT NULL DEFAULT 0,
|
||||
"utcDateModified" TEXT NOT NULL
|
||||
);
|
@ -14,7 +14,7 @@ npm install
|
||||
|
||||
## Running
|
||||
|
||||
See output of `npx esrun dump.ts --help`:
|
||||
See output of `npx tsx dump.ts --help`:
|
||||
|
||||
```
|
||||
dump-db.ts <path_to_document> <target_directory>
|
||||
|
858
dump-db/package-lock.json
generated
@ -18,9 +18,9 @@
|
||||
"homepage": "https://github.com/TriliumNext/Notes/blob/master/dump-db/README.md",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^11.1.2",
|
||||
"esrun": "^3.2.26",
|
||||
"mime-types": "^2.1.34",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"tsx": "^4.19.3",
|
||||
"yargs": "^17.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -42,14 +42,16 @@ test("User can change language from settings", async ({ page, context }) => {
|
||||
|
||||
// Check that the default value (English) is set.
|
||||
await expect(app.currentNoteSplit).toContainText("Theme");
|
||||
const languageCombobox = await app.currentNoteSplit.getByRole("combobox").first();
|
||||
const languageCombobox = app.currentNoteSplit.getByRole("combobox").first();
|
||||
await expect(languageCombobox).toHaveValue("en");
|
||||
|
||||
// Select Chinese and ensure the translation is set.
|
||||
await languageCombobox.selectOption("cn");
|
||||
await expect(app.currentNoteSplit).toContainText("主题", { timeout: 15000 });
|
||||
await expect(languageCombobox).toHaveValue("cn");
|
||||
|
||||
// Select English again.
|
||||
await languageCombobox.selectOption("en");
|
||||
await expect(app.currentNoteSplit).toContainText("Language", { timeout: 15000 });
|
||||
await expect(languageCombobox).toHaveValue("en");
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ export default class App {
|
||||
url = "/";
|
||||
}
|
||||
|
||||
await this.page.goto(url, { waitUntil: "networkidle" });
|
||||
await this.page.goto(url, { waitUntil: "networkidle", timeout: 30_000 });
|
||||
|
||||
// Wait for the page to load.
|
||||
if (url === "/") {
|
||||
|
28
libraries/codemirror/eslint.js
vendored
@ -35,39 +35,13 @@
|
||||
return [];
|
||||
}
|
||||
|
||||
await glob.requireLibrary(glob.ESLINT);
|
||||
|
||||
if (text.length > 20000) {
|
||||
console.log("Skipping linting because of large size: ", text.length);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
const errors = new eslint().verify(text, {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
ecmaVersion: "2019"
|
||||
},
|
||||
extends: ['eslint:recommended', 'airbnb-base'],
|
||||
env: {
|
||||
'browser': true,
|
||||
'node': true
|
||||
},
|
||||
rules: {
|
||||
'import/no-unresolved': 'off',
|
||||
'func-names': 'off',
|
||||
'comma-dangle': ['warn'],
|
||||
'padded-blocks': 'off',
|
||||
'linebreak-style': 'off',
|
||||
'class-methods-use-this': 'off',
|
||||
'no-unused-vars': ['warn', { vars: 'local', args: 'after-used' }],
|
||||
'no-nested-ternary': 'off',
|
||||
'no-underscore-dangle': ['error', {'allow': ['_super', '_lookupFactory']}]
|
||||
},
|
||||
globals: {
|
||||
"api": "readonly"
|
||||
}
|
||||
});
|
||||
const errors = await glob.linter(text);
|
||||
|
||||
console.log(errors);
|
||||
|
||||
|
112883
libraries/eslint/eslint.js
vendored
246
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.92.2-beta",
|
||||
"version": "0.92.3-beta",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "trilium",
|
||||
"version": "0.92.2-beta",
|
||||
"version": "0.92.3-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "7.1.1",
|
||||
@ -23,7 +23,7 @@
|
||||
"archiver": "7.0.1",
|
||||
"async-mutex": "0.5.0",
|
||||
"autocomplete.js": "0.38.1",
|
||||
"axios": "1.8.1",
|
||||
"axios": "1.8.2",
|
||||
"better-sqlite3": "11.8.1",
|
||||
"boxicons": "2.1.4",
|
||||
"chardet": "2.1.0",
|
||||
@ -44,10 +44,11 @@
|
||||
"electron-squirrel-startup": "1.0.1",
|
||||
"electron-window-state": "5.0.3",
|
||||
"escape-html": "1.0.3",
|
||||
"eslint-linter-browserify": "9.22.0",
|
||||
"express": "4.21.2",
|
||||
"express-rate-limit": "7.5.0",
|
||||
"express-session": "1.18.1",
|
||||
"force-graph": "1.49.2",
|
||||
"force-graph": "1.49.3",
|
||||
"fs-extra": "11.3.0",
|
||||
"helmet": "8.0.0",
|
||||
"html": "1.0.0",
|
||||
@ -114,8 +115,8 @@
|
||||
"@electron-forge/maker-zip": "7.7.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@eslint/js": "9.21.0",
|
||||
"@playwright/test": "1.50.1",
|
||||
"@eslint/js": "9.22.0",
|
||||
"@playwright/test": "1.51.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
@ -140,7 +141,7 @@
|
||||
"@types/leaflet-gpx": "1.3.7",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/multer": "1.4.12",
|
||||
"@types/node": "22.13.8",
|
||||
"@types/node": "22.13.9",
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"@types/safe-compare": "1.1.2",
|
||||
@ -154,18 +155,19 @@
|
||||
"@types/swagger-ui-express": "4.1.8",
|
||||
"@types/tmp": "0.2.6",
|
||||
"@types/turndown": "5.0.5",
|
||||
"@types/ws": "8.5.14",
|
||||
"@types/ws": "8.18.0",
|
||||
"@types/xml2js": "0.4.14",
|
||||
"@types/yargs": "17.0.33",
|
||||
"@vitest/coverage-v8": "3.0.7",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"autoprefixer": "10.4.20",
|
||||
"bootstrap": "5.3.3",
|
||||
"cross-env": "7.0.3",
|
||||
"css-loader": "7.1.2",
|
||||
"electron": "34.3.0",
|
||||
"eslint": "9.21.0",
|
||||
"electron": "34.3.1",
|
||||
"eslint": "9.22.0",
|
||||
"esm": "3.2.25",
|
||||
"happy-dom": "17.2.2",
|
||||
"globals": "16.0.0",
|
||||
"happy-dom": "17.4.0",
|
||||
"i18next-http-backend": "3.0.2",
|
||||
"jsdoc": "4.0.4",
|
||||
"knockout": "3.5.1",
|
||||
@ -187,7 +189,7 @@
|
||||
"typedoc": "0.27.9",
|
||||
"typescript": "5.8.2",
|
||||
"typescript-eslint": "8.26.0",
|
||||
"vitest": "3.0.7",
|
||||
"vitest": "3.0.8",
|
||||
"webpack": "5.98.0",
|
||||
"webpack-cli": "6.0.1",
|
||||
"webpack-dev-middleware": "7.4.2"
|
||||
@ -2187,6 +2189,16 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-helpers": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz",
|
||||
"integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/core": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
|
||||
@ -2241,6 +2253,19 @@
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
@ -2249,9 +2274,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz",
|
||||
"integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==",
|
||||
"version": "9.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz",
|
||||
"integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -3806,13 +3831,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.1.tgz",
|
||||
"integrity": "sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==",
|
||||
"version": "1.51.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.0.tgz",
|
||||
"integrity": "sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.50.1"
|
||||
"playwright": "1.51.0"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@ -4861,9 +4886,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.8.tgz",
|
||||
"integrity": "sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==",
|
||||
"version": "22.13.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz",
|
||||
"integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
@ -5099,9 +5124,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
|
||||
"integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5352,9 +5377,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.7.tgz",
|
||||
"integrity": "sha512-Av8WgBJLTrfLOer0uy3CxjlVuWK4CzcLBndW1Nm2vI+3hZ2ozHututkfc7Blu1u6waeQ7J8gzPK/AsBRnWA5mQ==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.8.tgz",
|
||||
"integrity": "sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5375,8 +5400,8 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitest/browser": "3.0.7",
|
||||
"vitest": "3.0.7"
|
||||
"@vitest/browser": "3.0.8",
|
||||
"vitest": "3.0.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vitest/browser": {
|
||||
@ -5385,14 +5410,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.7.tgz",
|
||||
"integrity": "sha512-QP25f+YJhzPfHrHfYHtvRn+uvkCFCqFtW9CktfBxmB+25QqWsx7VB2As6f4GmwllHLDhXNHvqedwhvMmSnNmjw==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz",
|
||||
"integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "3.0.7",
|
||||
"@vitest/utils": "3.0.7",
|
||||
"@vitest/spy": "3.0.8",
|
||||
"@vitest/utils": "3.0.8",
|
||||
"chai": "^5.2.0",
|
||||
"tinyrainbow": "^2.0.0"
|
||||
},
|
||||
@ -5401,13 +5426,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.7.tgz",
|
||||
"integrity": "sha512-qui+3BLz9Eonx4EAuR/i+QlCX6AUZ35taDQgwGkK/Tw6/WgwodSrjN1X2xf69IA/643ZX5zNKIn2svvtZDrs4w==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz",
|
||||
"integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "3.0.7",
|
||||
"@vitest/spy": "3.0.8",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.17"
|
||||
},
|
||||
@ -5428,9 +5453,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz",
|
||||
"integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz",
|
||||
"integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5441,13 +5466,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.7.tgz",
|
||||
"integrity": "sha512-WeEl38Z0S2ZcuRTeyYqaZtm4e26tq6ZFqh5y8YD9YxfWuu0OFiGFUbnxNynwLjNRHPsXyee2M9tV7YxOTPZl2g==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz",
|
||||
"integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/utils": "3.0.7",
|
||||
"@vitest/utils": "3.0.8",
|
||||
"pathe": "^2.0.3"
|
||||
},
|
||||
"funding": {
|
||||
@ -5462,13 +5487,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.7.tgz",
|
||||
"integrity": "sha512-eqTUryJWQN0Rtf5yqCGTQWsCFOQe4eNz5Twsu21xYEcnFJtMU5XvmG0vgebhdLlrHQTSq5p8vWHJIeJQV8ovsA==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz",
|
||||
"integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "3.0.7",
|
||||
"@vitest/pretty-format": "3.0.8",
|
||||
"magic-string": "^0.30.17",
|
||||
"pathe": "^2.0.3"
|
||||
},
|
||||
@ -5484,9 +5509,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.7.tgz",
|
||||
"integrity": "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz",
|
||||
"integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5497,13 +5522,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.7.tgz",
|
||||
"integrity": "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz",
|
||||
"integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "3.0.7",
|
||||
"@vitest/pretty-format": "3.0.8",
|
||||
"loupe": "^3.1.3",
|
||||
"tinyrainbow": "^2.0.0"
|
||||
},
|
||||
@ -6296,9 +6321,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz",
|
||||
"integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
|
||||
"integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@ -9011,9 +9036,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "34.3.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-34.3.0.tgz",
|
||||
"integrity": "sha512-I238qRnYTAsuwJ/rS7HGaFNY4NNKAcjX8nlj7mnNmj1TK3z4HvNoD1r7Zud81DYDFx8AITuLd76EPrEnnfF9Bg==",
|
||||
"version": "34.3.1",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-34.3.1.tgz",
|
||||
"integrity": "sha512-Vsgxc4FDGg7hjduKyvTP5qfNDxZHTliZIiWD1HlR5hHXx3BFjyVv3db/uEH1GaCU0KKyeNsBXRwS4WAOMaSH5g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -9733,9 +9758,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@types/node": {
|
||||
"version": "20.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.19.tgz",
|
||||
"integrity": "sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==",
|
||||
"version": "20.17.23",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.23.tgz",
|
||||
"integrity": "sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
@ -10058,18 +10083,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.21.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz",
|
||||
"integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==",
|
||||
"version": "9.22.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz",
|
||||
"integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
"@eslint/config-array": "^0.19.2",
|
||||
"@eslint/config-helpers": "^0.1.0",
|
||||
"@eslint/core": "^0.12.0",
|
||||
"@eslint/eslintrc": "^3.3.0",
|
||||
"@eslint/js": "9.21.0",
|
||||
"@eslint/js": "9.22.0",
|
||||
"@eslint/plugin-kit": "^0.2.7",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
@ -10081,7 +10107,7 @@
|
||||
"cross-spawn": "^7.0.6",
|
||||
"debug": "^4.3.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^8.2.0",
|
||||
"eslint-scope": "^8.3.0",
|
||||
"eslint-visitor-keys": "^4.2.0",
|
||||
"espree": "^10.3.0",
|
||||
"esquery": "^1.5.0",
|
||||
@ -10117,6 +10143,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-linter-browserify": {
|
||||
"version": "9.22.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-linter-browserify/-/eslint-linter-browserify-9.22.0.tgz",
|
||||
"integrity": "sha512-b70x+ilh1XkugEZZvGJ6LNPE1+jxjsn4KIdj1OBMBGbzYj7l2lr3N/Y4NHKhFxq2a4v/J8WqojIOvy0AFDmrXw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -10172,9 +10204,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/eslint-scope": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
|
||||
"integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
|
||||
"integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
@ -11091,9 +11123,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/force-graph": {
|
||||
"version": "1.49.2",
|
||||
"resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.49.2.tgz",
|
||||
"integrity": "sha512-dXArBN/5Aj9pYf2/vdab8C8v/1/HtZ7lrRSGoWgaofHwbopAgpGYTkveBOkeI9+u6xfgBA+02Wgau2QnZpREXQ==",
|
||||
"version": "1.49.3",
|
||||
"resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.49.3.tgz",
|
||||
"integrity": "sha512-blBqeFq3vdIzqGgvWrML9xA2R0nS5nvjHsEt9lcWVZ29IcdWQ6wa4G0CG/Uv8bP9olwpsJPZSJe3W8vNhiMCnQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tweenjs/tween.js": "18 - 25",
|
||||
@ -11598,9 +11630,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz",
|
||||
"integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -11684,9 +11716,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/happy-dom": {
|
||||
"version": "17.2.2",
|
||||
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.2.2.tgz",
|
||||
"integrity": "sha512-3I1/CrNi780sdOhuhUnFtgTWhloSc3quSZwsylI41jycx8o97M6Y4aQAu0phSexGusT7+59BxATh4L4xiY0HcA==",
|
||||
"version": "17.4.0",
|
||||
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.0.tgz",
|
||||
"integrity": "sha512-LN2BIuvdFZ8snmF6LtQB2vYBzRmgCx+uqlFX9JpKVRHQ44NODNnOchB4ZW8404djHhdbQgEHRAkXCZ0zGOyzew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -15286,13 +15318,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.50.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz",
|
||||
"integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==",
|
||||
"version": "1.51.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.0.tgz",
|
||||
"integrity": "sha512-442pTfGM0xxfCYxuBa/Pu6B2OqxqqaYq39JS8QDMGThUvIOCd6s0ANDog3uwA0cHavVlnTQzGCN7Id2YekDSXA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.50.1"
|
||||
"playwright-core": "1.51.0"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@ -15305,9 +15337,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.50.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz",
|
||||
"integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==",
|
||||
"version": "1.51.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.0.tgz",
|
||||
"integrity": "sha512-x47yPE3Zwhlil7wlNU/iktF7t2r/URR3VLbH6EknJd/04Qc/PSJ0EY3CMXipmglLG+zyRxW6HNo2EGbKLHPWMg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@ -19154,9 +19186,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-node": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.7.tgz",
|
||||
"integrity": "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz",
|
||||
"integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -19199,19 +19231,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.7.tgz",
|
||||
"integrity": "sha512-IP7gPK3LS3Fvn44x30X1dM9vtawm0aesAa2yBIZ9vQf+qB69NXC5776+Qmcr7ohUXIQuLhk7xQR0aSUIDPqavg==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz",
|
||||
"integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/expect": "3.0.7",
|
||||
"@vitest/mocker": "3.0.7",
|
||||
"@vitest/pretty-format": "^3.0.7",
|
||||
"@vitest/runner": "3.0.7",
|
||||
"@vitest/snapshot": "3.0.7",
|
||||
"@vitest/spy": "3.0.7",
|
||||
"@vitest/utils": "3.0.7",
|
||||
"@vitest/expect": "3.0.8",
|
||||
"@vitest/mocker": "3.0.8",
|
||||
"@vitest/pretty-format": "^3.0.8",
|
||||
"@vitest/runner": "3.0.8",
|
||||
"@vitest/snapshot": "3.0.8",
|
||||
"@vitest/spy": "3.0.8",
|
||||
"@vitest/utils": "3.0.8",
|
||||
"chai": "^5.2.0",
|
||||
"debug": "^4.4.0",
|
||||
"expect-type": "^1.1.0",
|
||||
@ -19223,7 +19255,7 @@
|
||||
"tinypool": "^1.0.2",
|
||||
"tinyrainbow": "^2.0.0",
|
||||
"vite": "^5.0.0 || ^6.0.0",
|
||||
"vite-node": "3.0.7",
|
||||
"vite-node": "3.0.8",
|
||||
"why-is-node-running": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
@ -19239,8 +19271,8 @@
|
||||
"@edge-runtime/vm": "*",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
||||
"@vitest/browser": "3.0.7",
|
||||
"@vitest/ui": "3.0.7",
|
||||
"@vitest/browser": "3.0.8",
|
||||
"@vitest/ui": "3.0.8",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
},
|
||||
|
34
package.json
@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "TriliumNext Notes",
|
||||
"description": "Build your personal knowledge base with TriliumNext Notes",
|
||||
"version": "0.92.2-beta",
|
||||
"version": "0.92.3-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "./dist/electron-main.js",
|
||||
"author": {
|
||||
@ -43,14 +43,16 @@
|
||||
"docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts",
|
||||
"docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
|
||||
"docs:build": "npm run docs:build-backend && npm run docs:build-frontend",
|
||||
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts",
|
||||
"build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts",
|
||||
"build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts --progress",
|
||||
"build:ts": "tsc -p tsconfig.build.json",
|
||||
"build:clean": "rimraf ./dist ./build",
|
||||
"build:prepare-dist": "npm run build:clean && npm run build:ts && npm run build:webpack && tsx ./bin/copy-dist.ts",
|
||||
"test": "npm run client:test && npm run server:test",
|
||||
"server:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest",
|
||||
"server:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --coverage",
|
||||
"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",
|
||||
"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 TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
"test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts",
|
||||
@ -79,7 +81,7 @@
|
||||
"archiver": "7.0.1",
|
||||
"async-mutex": "0.5.0",
|
||||
"autocomplete.js": "0.38.1",
|
||||
"axios": "1.8.1",
|
||||
"axios": "1.8.2",
|
||||
"better-sqlite3": "11.8.1",
|
||||
"boxicons": "2.1.4",
|
||||
"chardet": "2.1.0",
|
||||
@ -100,10 +102,11 @@
|
||||
"electron-squirrel-startup": "1.0.1",
|
||||
"electron-window-state": "5.0.3",
|
||||
"escape-html": "1.0.3",
|
||||
"eslint-linter-browserify": "9.22.0",
|
||||
"express": "4.21.2",
|
||||
"express-rate-limit": "7.5.0",
|
||||
"express-session": "1.18.1",
|
||||
"force-graph": "1.49.2",
|
||||
"force-graph": "1.49.3",
|
||||
"fs-extra": "11.3.0",
|
||||
"helmet": "8.0.0",
|
||||
"html": "1.0.0",
|
||||
@ -167,8 +170,8 @@
|
||||
"@electron-forge/maker-zip": "7.7.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@eslint/js": "9.21.0",
|
||||
"@playwright/test": "1.50.1",
|
||||
"@eslint/js": "9.22.0",
|
||||
"@playwright/test": "1.51.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
@ -193,7 +196,7 @@
|
||||
"@types/leaflet-gpx": "1.3.7",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/multer": "1.4.12",
|
||||
"@types/node": "22.13.8",
|
||||
"@types/node": "22.13.9",
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"@types/safe-compare": "1.1.2",
|
||||
@ -207,18 +210,19 @@
|
||||
"@types/swagger-ui-express": "4.1.8",
|
||||
"@types/tmp": "0.2.6",
|
||||
"@types/turndown": "5.0.5",
|
||||
"@types/ws": "8.5.14",
|
||||
"@types/ws": "8.18.0",
|
||||
"@types/xml2js": "0.4.14",
|
||||
"@types/yargs": "17.0.33",
|
||||
"@vitest/coverage-v8": "3.0.7",
|
||||
"@vitest/coverage-v8": "3.0.8",
|
||||
"autoprefixer": "10.4.20",
|
||||
"bootstrap": "5.3.3",
|
||||
"cross-env": "7.0.3",
|
||||
"css-loader": "7.1.2",
|
||||
"electron": "34.3.0",
|
||||
"eslint": "9.21.0",
|
||||
"electron": "34.3.1",
|
||||
"eslint": "9.22.0",
|
||||
"esm": "3.2.25",
|
||||
"happy-dom": "17.2.2",
|
||||
"globals": "16.0.0",
|
||||
"happy-dom": "17.4.0",
|
||||
"i18next-http-backend": "3.0.2",
|
||||
"jsdoc": "4.0.4",
|
||||
"knockout": "3.5.1",
|
||||
@ -240,7 +244,7 @@
|
||||
"typedoc": "0.27.9",
|
||||
"typescript": "5.8.2",
|
||||
"typescript-eslint": "8.26.0",
|
||||
"vitest": "3.0.7",
|
||||
"vitest": "3.0.8",
|
||||
"webpack": "5.98.0",
|
||||
"webpack-cli": "6.0.1",
|
||||
"webpack-dev-middleware": "7.4.2"
|
||||
|
@ -12,7 +12,6 @@ import type { AttachmentRow, BlobRow, RevisionRow } from "./entities/rows.js";
|
||||
import BBlob from "./entities/bblob.js";
|
||||
import BRecentNote from "./entities/brecent_note.js";
|
||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import type BTask from "./entities/btask.js";
|
||||
|
||||
interface AttachmentOpts {
|
||||
includeContentLength?: boolean;
|
||||
@ -33,7 +32,6 @@ export default class Becca {
|
||||
attributeIndex!: Record<string, BAttribute[]>;
|
||||
options!: Record<string, BOption>;
|
||||
etapiTokens!: Record<string, BEtapiToken>;
|
||||
tasks!: Record<string, BTask>;
|
||||
|
||||
allNoteSetCache: NoteSet | null;
|
||||
|
||||
@ -50,7 +48,6 @@ export default class Becca {
|
||||
this.attributeIndex = {};
|
||||
this.options = {};
|
||||
this.etapiTokens = {};
|
||||
this.tasks = {};
|
||||
|
||||
this.dirtyNoteSetCache();
|
||||
|
||||
@ -216,14 +213,6 @@ export default class Becca {
|
||||
return this.etapiTokens[etapiTokenId];
|
||||
}
|
||||
|
||||
getTasks(): BTask[] {
|
||||
return Object.values(this.tasks);
|
||||
}
|
||||
|
||||
getTask(taskId: string): BTask | null {
|
||||
return this.tasks[taskId];
|
||||
}
|
||||
|
||||
getEntity<T extends AbstractBeccaEntity<T>>(entityName: string, entityId: string): AbstractBeccaEntity<T> | null {
|
||||
if (!entityName || !entityId) {
|
||||
return null;
|
||||
|
@ -11,10 +11,9 @@ import BOption from "./entities/boption.js";
|
||||
import BEtapiToken from "./entities/betapi_token.js";
|
||||
import cls from "../services/cls.js";
|
||||
import entityConstructor from "../becca/entity_constructor.js";
|
||||
import type { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow, TaskRow } from "./entities/rows.js";
|
||||
import type { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow } from "./entities/rows.js";
|
||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import ws from "../services/ws.js";
|
||||
import BTask from "./entities/btask.js";
|
||||
|
||||
const beccaLoaded = new Promise<void>(async (res, rej) => {
|
||||
const sqlInit = (await import("../services/sql_init.js")).default;
|
||||
@ -64,17 +63,6 @@ function load() {
|
||||
for (const row of sql.getRows<EtapiTokenRow>(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
|
||||
new BEtapiToken(row);
|
||||
}
|
||||
|
||||
try {
|
||||
for (const row of sql.getRows<TaskRow>(`SELECT taskId, parentNoteId, title, dueDate, isDone, isDeleted FROM tasks WHERE isDeleted = 0`)) {
|
||||
new BTask(row);
|
||||
}
|
||||
} catch (e: any) {
|
||||
// Some older migrations trigger becca which would fail since the "tasks" table is not yet defined (didn't reach the right migration).
|
||||
if (!(e.message.includes("no such table"))) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const noteId in becca.notes) {
|
||||
|
@ -1,84 +0,0 @@
|
||||
import date_utils from "../../services/date_utils.js";
|
||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import type BOption from "./boption.js";
|
||||
import type { TaskRow } from "./rows.js";
|
||||
|
||||
export default class BTask extends AbstractBeccaEntity<BOption> {
|
||||
|
||||
static get entityName() {
|
||||
return "tasks";
|
||||
}
|
||||
|
||||
static get primaryKeyName() {
|
||||
return "taskId";
|
||||
}
|
||||
|
||||
static get hashedProperties() {
|
||||
return ["taskId", "parentNoteId", "title", "dueDate", "isDone", "isDeleted"];
|
||||
}
|
||||
|
||||
taskId?: string;
|
||||
parentNoteId!: string;
|
||||
title!: string;
|
||||
dueDate?: string;
|
||||
isDone!: boolean;
|
||||
private _isDeleted?: boolean;
|
||||
|
||||
constructor(row?: TaskRow) {
|
||||
super();
|
||||
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateFromRow(row);
|
||||
this.init();
|
||||
}
|
||||
|
||||
get isDeleted() {
|
||||
return !!this._isDeleted;
|
||||
}
|
||||
|
||||
updateFromRow(row: TaskRow) {
|
||||
this.taskId = row.taskId;
|
||||
this.parentNoteId = row.parentNoteId;
|
||||
this.title = row.title;
|
||||
this.dueDate = row.dueDate;
|
||||
this.isDone = !!row.isDone;
|
||||
this._isDeleted = !!row.isDeleted;
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
|
||||
if (this.taskId) {
|
||||
this.becca.tasks[this.taskId] = this;
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.taskId) {
|
||||
this.becca.tasks[this.taskId] = this;
|
||||
}
|
||||
}
|
||||
|
||||
protected beforeSaving(opts?: {}): void {
|
||||
super.beforeSaving();
|
||||
|
||||
this.utcDateModified = date_utils.utcNowDateTime();
|
||||
|
||||
if (this.taskId) {
|
||||
this.becca.tasks[this.taskId] = this;
|
||||
}
|
||||
}
|
||||
|
||||
getPojo() {
|
||||
return {
|
||||
taskId: this.taskId,
|
||||
parentNoteId: this.parentNoteId,
|
||||
title: this.title,
|
||||
dueDate: this.dueDate,
|
||||
isDone: this.isDone,
|
||||
isDeleted: this.isDeleted,
|
||||
utcDateModified: this.utcDateModified
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -139,13 +139,3 @@ export interface NoteRow {
|
||||
utcDateModified: string;
|
||||
content?: string | Buffer;
|
||||
}
|
||||
|
||||
export interface TaskRow {
|
||||
taskId?: string;
|
||||
parentNoteId: string;
|
||||
title: string;
|
||||
dueDate?: string;
|
||||
isDone?: boolean;
|
||||
isDeleted?: boolean;
|
||||
utcDateModified?: string;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import BNote from "./entities/bnote.js";
|
||||
import BOption from "./entities/boption.js";
|
||||
import BRecentNote from "./entities/brecent_note.js";
|
||||
import BRevision from "./entities/brevision.js";
|
||||
import BTask from "./entities/btask.js";
|
||||
|
||||
type EntityClass = new (row?: any) => AbstractBeccaEntity<any>;
|
||||
|
||||
@ -22,8 +21,7 @@ const ENTITY_NAME_TO_ENTITY: Record<string, ConstructorData<any> & EntityClass>
|
||||
notes: BNote,
|
||||
options: BOption,
|
||||
recent_notes: BRecentNote,
|
||||
revisions: BRevision,
|
||||
tasks: BTask
|
||||
revisions: BRevision
|
||||
};
|
||||
|
||||
function getEntityFromEntityName(entityName: keyof typeof ENTITY_NAME_TO_ENTITY) {
|
||||
|
@ -551,10 +551,12 @@ $(window).on("beforeunload", () => {
|
||||
});
|
||||
|
||||
$(window).on("hashchange", function () {
|
||||
const { notePath, ntxId, viewScope } = linkService.parseNavigationStateFromUrl(window.location.href);
|
||||
const { notePath, ntxId, viewScope, searchString } = linkService.parseNavigationStateFromUrl(window.location.href);
|
||||
|
||||
if (notePath || ntxId) {
|
||||
appContext.tabManager.switchToNoteContext(ntxId, notePath, viewScope);
|
||||
} else if (searchString) {
|
||||
appContext.triggerCommand("searchNotes", { searchString });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -369,7 +369,8 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
|
||||
|
||||
const { note, viewScope } = this;
|
||||
|
||||
let title = viewScope?.viewMode === "default" ? note.title : `${note.title}: ${viewScope?.viewMode}`;
|
||||
const isNormalView = (viewScope?.viewMode === "default" || viewScope?.viewMode === "contextual-help");
|
||||
let title = (isNormalView ? note.title : `${note.title}: ${viewScope?.viewMode}`);
|
||||
|
||||
if (viewScope?.attachmentId) {
|
||||
// assuming the attachment has been already loaded
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"formatVersion": 2,
|
||||
"appVersion": "0.92.0-beta",
|
||||
"appVersion": "0.92.2-beta",
|
||||
"files": [
|
||||
{
|
||||
"isClone": false,
|
||||
@ -34,7 +34,7 @@
|
||||
"OkOZllzB3fqN",
|
||||
"yoAe4jV2yzbd"
|
||||
],
|
||||
"title": "Features",
|
||||
"title": "New Features",
|
||||
"notePosition": 40,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
@ -47,53 +47,91 @@
|
||||
"value": "bx bx-star",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "sorted",
|
||||
"value": "dateCreated",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "sortDirection",
|
||||
"value": "desc",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"attachments": [],
|
||||
"dirFileName": "Features",
|
||||
"dirFileName": "New Features",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "13D1lOc9sqmZ",
|
||||
"noteId": "3I277VKYxWDH",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"yoAe4jV2yzbd",
|
||||
"13D1lOc9sqmZ"
|
||||
"3I277VKYxWDH"
|
||||
],
|
||||
"title": "Export as PDF",
|
||||
"notePosition": 20,
|
||||
"title": "Right-to-left text notes",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-align-right",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Export as PDF.html",
|
||||
"dataFileName": "Right-to-left text notes.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "xsGM34t8ssKV",
|
||||
"attachmentId": "PSBNAvDyj5Vy",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Export as PDF_image.png"
|
||||
"dataFileName": "Right-to-left text notes_i.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "cvyes4f1Vhmm",
|
||||
"attachmentId": "YXYIJznak915",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "1_Export as PDF_image.png"
|
||||
"dataFileName": "1_Right-to-left text notes_i.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "b3v1pLE6TF1Y",
|
||||
"attachmentId": "Do0S17lDl7uu",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "2_Export as PDF_image.png"
|
||||
"dataFileName": "2_Right-to-left text notes_i.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "D3lyhPvPvocb",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "3_Right-to-left text notes_i.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "Tu7llk3GgRkA",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "4_Right-to-left text notes_i.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -106,12 +144,20 @@
|
||||
"B3YLYM4erjnW"
|
||||
],
|
||||
"title": "Zen mode",
|
||||
"notePosition": 30,
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-yin-yang",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Zen mode.html",
|
||||
"attachments": [
|
||||
@ -180,6 +226,50 @@
|
||||
"dataFileName": "7_Zen mode_image.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "13D1lOc9sqmZ",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"yoAe4jV2yzbd",
|
||||
"13D1lOc9sqmZ"
|
||||
],
|
||||
"title": "Export as PDF",
|
||||
"notePosition": 30,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-file-pdf",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Export as PDF.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "xsGM34t8ssKV",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Export as PDF_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "b3v1pLE6TF1Y",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "1_Export as PDF_image.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -233,8 +323,47 @@
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Text.html",
|
||||
"attachments": []
|
||||
"attachments": [],
|
||||
"dirFileName": "Text",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "B0lcI9xz1r8K",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"wmegHv51MJMd",
|
||||
"crJtzsol4olb",
|
||||
"B0lcI9xz1r8K"
|
||||
],
|
||||
"title": "Content language",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "3I277VKYxWDH",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Content language.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "OpIv6CnYCLVa",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Content language_image.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
@ -382,7 +511,7 @@
|
||||
"title": "Book",
|
||||
"notePosition": 70,
|
||||
"prefix": null,
|
||||
"isExpanded": true,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
@ -576,6 +705,14 @@
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "18_Calendar View_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "JM6AU8N4MIgB",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "19_Calendar View_image.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -697,7 +834,7 @@
|
||||
"wmegHv51MJMd",
|
||||
"foPEtsL51pD2"
|
||||
],
|
||||
"title": "Geo Map",
|
||||
"title": "Geo map",
|
||||
"notePosition": 120,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
@ -713,23 +850,15 @@
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Geo Map.html",
|
||||
"dataFileName": "Geo map.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "J0baLTpafs7C",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Geo Map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "kcYjOvJDFkbS",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "1_Geo Map_image.png"
|
||||
"dataFileName": "Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "FDP3JzIVSnuJ",
|
||||
@ -737,7 +866,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "2_Geo Map_image.png"
|
||||
"dataFileName": "1_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "eUrcqc8RRuZG",
|
||||
@ -745,7 +874,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "3_Geo Map_image.png"
|
||||
"dataFileName": "2_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "1quk4yxJpeHZ",
|
||||
@ -753,7 +882,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "4_Geo Map_image.png"
|
||||
"dataFileName": "3_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "iSpyhQ5Ya6Nk",
|
||||
@ -761,7 +890,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "5_Geo Map_image.png"
|
||||
"dataFileName": "4_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "ut6vm2aXVfXI",
|
||||
@ -769,7 +898,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "6_Geo Map_image.png"
|
||||
"dataFileName": "5_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "uYdb9wWf5Nuv",
|
||||
@ -777,15 +906,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "7_Geo Map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "GhHYO2LteDmZ",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "8_Geo Map_image.png"
|
||||
"dataFileName": "6_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "viN50n5G4kB0",
|
||||
@ -793,7 +914,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "9_Geo Map_image.png"
|
||||
"dataFileName": "7_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "mgwGrtQZjxxb",
|
||||
@ -801,7 +922,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "10_Geo Map_image.png"
|
||||
"dataFileName": "8_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "PMqmCbNLlZOG",
|
||||
@ -809,7 +930,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "11_Geo Map_image.png"
|
||||
"dataFileName": "9_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "0AwaQMqt3FVA",
|
||||
@ -817,7 +938,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "12_Geo Map_image.png"
|
||||
"dataFileName": "10_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "gR2c2Thmfy3I",
|
||||
@ -825,7 +946,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "13_Geo Map_image.png"
|
||||
"dataFileName": "11_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "JULizn130rVI",
|
||||
@ -833,7 +954,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "14_Geo Map_image.png"
|
||||
"dataFileName": "12_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "MdC0DpifJwu4",
|
||||
@ -841,7 +962,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "15_Geo Map_image.png"
|
||||
"dataFileName": "13_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "gFR2Izzp18LQ",
|
||||
@ -849,7 +970,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "16_Geo Map_image.png"
|
||||
"dataFileName": "14_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "42AncDs7SSAf",
|
||||
@ -857,15 +978,7 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "17_Geo Map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "pKdtiq4r0eFY",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "18_Geo Map_image.png"
|
||||
"dataFileName": "15_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "FXRVvYpOxWyR",
|
||||
@ -873,7 +986,23 @@
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "19_Geo Map_image.png"
|
||||
"dataFileName": "16_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "qudP7UCtwIq3",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/jpg",
|
||||
"position": 10,
|
||||
"dataFileName": "17_Geo map_image.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "utecGxWk08QY",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "18_Geo map_image.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -943,173 +1072,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "DtJJ20yEozPA",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"DtJJ20yEozPA"
|
||||
],
|
||||
"title": "Theme development",
|
||||
"notePosition": 130,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-palette",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"attachments": [],
|
||||
"dirFileName": "Theme development",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "5HH79ztN0fZA",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"DtJJ20yEozPA",
|
||||
"5HH79ztN0fZA"
|
||||
],
|
||||
"title": "Creating a custom theme",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "aH8Dk5aMiq7R",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Creating a custom theme.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "AJHVfQtIQgJ7",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Creating a custom theme_im.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "gXLyv5KXjfxg",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "1_Creating a custom theme_im.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "on1gD7BzCWdN",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "2_Creating a custom theme_im.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "17p6z24yW5eP",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "3_Creating a custom theme_im.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "K3cdwj8f90m0",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "4_Creating a custom theme_im.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "bn93hwF7C8sR",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "5_Creating a custom theme_im.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "aH8Dk5aMiq7R",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"DtJJ20yEozPA",
|
||||
"aH8Dk5aMiq7R"
|
||||
],
|
||||
"title": "Customize the Next theme",
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
"format": "html",
|
||||
"dataFileName": "Customize the Next theme.html",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "5z4bC0x0eH0P",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Customize the Next theme_i.png"
|
||||
},
|
||||
{
|
||||
"attachmentId": "u0zkXkD7rGXA",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "1_Customize the Next theme_i.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "pMq6N1oBV9oo",
|
||||
"notePath": [
|
||||
"OkOZllzB3fqN",
|
||||
"DtJJ20yEozPA",
|
||||
"pMq6N1oBV9oo"
|
||||
],
|
||||
"title": "Reference",
|
||||
"notePosition": 30,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "po38jIc0LD2H",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
}
|
||||
],
|
||||
"format": "html",
|
||||
"dataFileName": "Reference.html",
|
||||
"attachments": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "LTnkDnYmmZ7s",
|
||||
@ -1283,7 +1245,7 @@
|
||||
"title": "ETAPI",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": true,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
@ -1333,7 +1295,7 @@
|
||||
"title": "Internal API",
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": true,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
@ -23,7 +23,7 @@
|
||||
as PDF. On the server or PWA (mobile), the option is not available due
|
||||
to technical constraints and it will be hidden.</p>
|
||||
<p>To print a note, select the
|
||||
<img src="2_Export as PDF_image.png" width="29"
|
||||
<img src="1_Export as PDF_image.png" width="29"
|
||||
height="31">button to the right of the note and select <i>Export as PDF</i>.</p>
|
||||
<p>Afterwards you will be prompted to select where to save the PDF file.
|
||||
Upon confirmation, the resulting PDF will be opened automatically using
|
||||
@ -33,7 +33,7 @@
|
||||
<a
|
||||
href="#root/OeKBfN6JbMIq/jRV1MPt4mNSP/hrC6xn7hnDq5">report the issue</a>. In this case, it's best to offer a sample note (click
|
||||
on the
|
||||
<img src="2_Export as PDF_image.png" width="29" height="31">button, select Export note → This note and all of its descendants → HTML
|
||||
<img src="1_Export as PDF_image.png" width="29" height="31">button, select Export note → This note and all of its descendants → HTML
|
||||
in ZIP archive). Make sure not to accidentally leak any personal information.</p>
|
||||
<h2>Landscape mode</h2>
|
||||
<p>When exporting to PDF, there are no customizable settings such as page
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
@ -0,0 +1,56 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Right-to-left text notes</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Right-to-left text notes</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<p>Trilium now has basic support for right-to-left text, at note level.</p>
|
||||
<figure
|
||||
class="table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:906/557;" src="3_Right-to-left text notes_i.png"
|
||||
width="906" height="557">
|
||||
</figure>
|
||||
</td>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:906/557;" src="2_Right-to-left text notes_i.png"
|
||||
width="906" height="557">
|
||||
</figure>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<p>Note that only the Text note type supports this.</p>
|
||||
<p>The list of languages is configurable via the a new dedicated settings
|
||||
page:</p>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:1248/635;" src="4_Right-to-left text notes_i.png"
|
||||
width="1248" height="635">
|
||||
</figure>
|
||||
<p>To select the corresponding language of the text, go to “Basic Properties”
|
||||
and select your desired language.</p>
|
||||
<p>
|
||||
<img src="1_Right-to-left text notes_i.png" width="635" height="492">
|
||||
</p>
|
||||
<p>Feel free to report any issues regarding right to left support.</p>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 323 KiB After Width: | Height: | Size: 323 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 515 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 397 KiB After Width: | Height: | Size: 397 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 4.6 KiB |
@ -118,6 +118,12 @@
|
||||
<td>When present (regardless of value), it will show the number of the week
|
||||
on the calendar.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>~child:template</code>
|
||||
</td>
|
||||
<td>Defines the template for newly created notes in the calendar (via dragging
|
||||
or clicking).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
@ -175,6 +181,36 @@
|
||||
than the title, either a label (e.g. <code>#assignee</code>) or a relation
|
||||
(e.g. <code>~for</code>). See <i>Advanced use-cases</i> for more information.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#calendar:promotedAttributes</code>
|
||||
</td>
|
||||
<td>
|
||||
<p>Allows displaying the value of one or more promoted attributes in the
|
||||
calendar like this:
|
||||
<img src="19_Calendar View_image.png" width="131" height="113">
|
||||
</p><pre><code class="language-text-x-trilium-auto">#label:weight="promoted,number,single,precision=1"
|
||||
#label:mood="promoted,alias=Mood,single,text"
|
||||
#calendar:promotedAttributes="label:weight,label:mood" </code></pre>
|
||||
<p>It can also be used with relations, case in which it will display the
|
||||
title of the target note:</p><pre><code class="language-text-x-trilium-auto">#relation:assignee="promoted,alias=Assignee,single,text"
|
||||
#calendar:promotedAttributes="relation:assignee"
|
||||
~assignee=@My assignee </code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#calendar:startDate</code>
|
||||
</td>
|
||||
<td>Allows using a different label to represent the start date, other than <code>#startDate</code> (e.g. <code>#expiryDate</code>).
|
||||
The label name must be prefixed with <code>#</code>. If the label is not
|
||||
defined for a note, the default will be used instead.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#calendar:endDate</code>
|
||||
</td>
|
||||
<td>Allows using a different label to represent the start date, other than <code>#endDate</code>.
|
||||
The label name must be prefixed with <code>#</code>. If the label is not
|
||||
defined for a note, the default will be used instead.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
|
Before Width: | Height: | Size: 6.5 KiB |
@ -5,12 +5,12 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Geo Map</title>
|
||||
<title data-trilium-title>Geo map</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Geo Map</h1>
|
||||
<h1 data-trilium-h1>Geo map</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<h2>Creating a new geo map</h2>
|
||||
@ -26,7 +26,7 @@
|
||||
<th>1</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:1256/1044;" src="9_Geo Map_image.png" width="1256"
|
||||
<img style="aspect-ratio:1256/1044;" src="7_Geo map_image.png" width="1256"
|
||||
height="1044">
|
||||
</figure>
|
||||
</td>
|
||||
@ -36,7 +36,7 @@
|
||||
<th>2</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:1720/1396;" src="3_Geo Map_image.png" width="1720"
|
||||
<img style="aspect-ratio:1720/1396;" src="2_Geo map_image.png" width="1720"
|
||||
height="1396">
|
||||
</figure>
|
||||
</td>
|
||||
@ -69,18 +69,18 @@
|
||||
<p>To create a marker, first navigate to the desired point on the map. Then
|
||||
press the
|
||||
<img class="image_resized" style="aspect-ratio:72/66;width:7.37%;"
|
||||
src="4_Geo Map_image.png" width="72" height="66">button on the top-right of the map.</p>
|
||||
src="3_Geo map_image.png" width="72" height="66">button on the top-right of the map.</p>
|
||||
<p>If the button is not visible, make sure the button section is visible
|
||||
by pressing the chevron button (
|
||||
<img class="image_resized" style="aspect-ratio:72/66;width:7.51%;"
|
||||
src="10_Geo Map_image.png" width="72" height="66">) in the top-right of the map.</p>
|
||||
src="8_Geo map_image.png" width="72" height="66">) in the top-right of the map.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:1730/416;" src="14_Geo Map_image.png" width="1730"
|
||||
<img style="aspect-ratio:1730/416;" src="12_Geo map_image.png" width="1730"
|
||||
height="416">
|
||||
</figure>
|
||||
<p> </p>
|
||||
@ -96,7 +96,7 @@
|
||||
<th>3</th>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:1586/404;" src="1_Geo Map_image.png" width="1586"
|
||||
<img style="aspect-ratio:1586/404;" src="Geo map_image.png" width="1586"
|
||||
height="404">
|
||||
</figure>
|
||||
<p> </p>
|
||||
@ -107,7 +107,7 @@
|
||||
<th>4</th>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:1696/608;" src="6_Geo Map_image.png" width="1696"
|
||||
<img style="aspect-ratio:1696/608;" src="5_Geo map_image.png" width="1696"
|
||||
height="608">
|
||||
</figure>
|
||||
<p> </p>
|
||||
@ -122,7 +122,7 @@
|
||||
<p>The location of a marker is stored in the <code>#geolocation</code> attribute
|
||||
of the child notes:</p>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:1288/278;" src="12_Geo Map_image.png" width="1288"
|
||||
<img style="aspect-ratio:1288/278;" src="10_Geo map_image.png" width="1288"
|
||||
height="278">
|
||||
</figure>
|
||||
<p>This value can be added manually if needed. The value of the attribute
|
||||
@ -155,6 +155,13 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Icon and color of the markers</h2>
|
||||
<p>
|
||||
<img src="18_Geo map_image.png" alt="image" width="523" height="295">
|
||||
</p>
|
||||
<p>The markers will have the same icon as the note.</p>
|
||||
<p>It's possible to add a custom color to a marker by assigning them a <code>#color</code> attribute
|
||||
such as <code>#color=green</code>.</p>
|
||||
<h2>Adding the coordinates manually</h2>
|
||||
<p>In a nutshell, create a child note and set the <code>#geolocation</code> attribute
|
||||
to the coordinates.</p>
|
||||
@ -168,7 +175,7 @@
|
||||
<th>1</th>
|
||||
<td>
|
||||
<figure class="image image-style-align-center image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:732/918;" src="16_Geo Map_image.png" width="732"
|
||||
<img style="aspect-ratio:732/918;" src="14_Geo map_image.png" width="732"
|
||||
height="918">
|
||||
</figure>
|
||||
</td>
|
||||
@ -185,7 +192,7 @@
|
||||
<th>2</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:518/84;" src="19_Geo Map_image.png" width="518"
|
||||
<img style="aspect-ratio:518/84;" src="16_Geo map_image.png" width="518"
|
||||
height="84">
|
||||
</figure>
|
||||
</td>
|
||||
@ -199,7 +206,7 @@
|
||||
<th>3</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:1074/276;" src="11_Geo Map_image.png" width="1074"
|
||||
<img style="aspect-ratio:1074/276;" src="9_Geo map_image.png" width="1074"
|
||||
height="276">
|
||||
</figure>
|
||||
</td>
|
||||
@ -225,7 +232,7 @@
|
||||
<th>1</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:562/454;" src="17_Geo Map_image.png" width="562"
|
||||
<img style="aspect-ratio:562/454;" src="15_Geo map_image.png" width="562"
|
||||
height="454">
|
||||
</figure>
|
||||
</td>
|
||||
@ -236,7 +243,7 @@
|
||||
<th>2</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:696/480;" src="13_Geo Map_image.png" width="696"
|
||||
<img style="aspect-ratio:696/480;" src="11_Geo map_image.png" width="696"
|
||||
height="480">
|
||||
</figure>
|
||||
</td>
|
||||
@ -250,7 +257,7 @@
|
||||
<th>3</th>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:640/276;" src="2_Geo Map_image.png" width="640"
|
||||
<img style="aspect-ratio:640/276;" src="1_Geo map_image.png" width="640"
|
||||
height="276">
|
||||
</figure>
|
||||
</td>
|
||||
@ -275,7 +282,7 @@
|
||||
<th>1</th>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:226/74;" src="7_Geo Map_image.png" width="226"
|
||||
<img style="aspect-ratio:226/74;" src="6_Geo map_image.png" width="226"
|
||||
height="74">
|
||||
</figure>
|
||||
</td>
|
||||
@ -286,7 +293,7 @@
|
||||
<th>2</th>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:322/222;" src="5_Geo Map_image.png" width="322"
|
||||
<img style="aspect-ratio:322/222;" src="4_Geo map_image.png" width="322"
|
||||
height="222">
|
||||
</figure>
|
||||
</td>
|
||||
@ -297,7 +304,7 @@
|
||||
<th>3</th>
|
||||
<td>
|
||||
<figure class="image image_resized" style="width:100%;">
|
||||
<img style="aspect-ratio:620/530;" src="15_Geo Map_image.png" width="620"
|
||||
<img style="aspect-ratio:620/530;" src="13_Geo map_image.png" width="620"
|
||||
height="530">
|
||||
</figure>
|
||||
</td>
|
||||
@ -310,9 +317,16 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<h2>Troubleshooting</h2>
|
||||
<h3>Grid-like artifacts on the map</h3>
|
||||
<p>
|
||||
<img class="image_resized" style="aspect-ratio:678/499;width:58%;" src="17_Geo map_image.png"
|
||||
width="678" height="499">
|
||||
</p>
|
||||
<p>This occurs if the application is not at 100% zoom which causes the pixels
|
||||
of the map to not render correctly due to fractional scaling. The only
|
||||
possible solution i to set the UI zoom at 100% (default keyboard shortcut
|
||||
is Ctrl+0).</p>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
@ -1,19 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Text</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Text</h1>
|
||||
|
||||
<div class="ck-content"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,34 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Content language</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Content language</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<p>A language hint can be provided for text notes. This option informs the
|
||||
browser or the desktop application about the language the note is written
|
||||
in (for example this might help with spellchecking), and it also determines
|
||||
whether the text is displayed from right-to-left for languages such as
|
||||
Arabic, Hebrew, etc.</p>
|
||||
<p>For more information about right-to-left support, see <a class="reference-link"
|
||||
href="../../New%20Features/Right-to-left%20text%20notes.html">Right-to-left text notes</a>.</p>
|
||||
<p>To set the language of the content, go to “Basic Properties” and look
|
||||
for the “Language” field. By default there will be no content languages
|
||||
set, they can be configured by going to settings or by selecting the “Configure
|
||||
languages” item in the list.</p>
|
||||
<p>
|
||||
<img src="Content language_image.png" width="635" height="492">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 4.7 KiB |
@ -1,94 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Creating a custom theme</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Creating a custom theme</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<h2>Step 1. Find a place to place the themes</h2>
|
||||
<p>Organization is an important aspect of managing a knowledge base. When
|
||||
developing a new theme or importing an existing one it's a good idea to
|
||||
keep them into one place.</p>
|
||||
<p>As such, the first step is to create a new note to gather all the themes.</p>
|
||||
<p>
|
||||
<img src="5_Creating a custom theme_im.png" width="181" height="84">
|
||||
</p>
|
||||
<h2>Step 2. Create the theme</h2>
|
||||
<figure class="table" style="width:100%;">
|
||||
<table class="ck-table-resized">
|
||||
<colgroup>
|
||||
<col style="width:32.47%;">
|
||||
<col style="width:67.53%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:651/220;" src="3_Creating a custom theme_im.png"
|
||||
width="651" height="220">
|
||||
</figure>
|
||||
</td>
|
||||
<td style="vertical-align:top;">Themes are code notes with a special attribute. Start by creating a new
|
||||
code note.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:302/349;" src="1_Creating a custom theme_im.png"
|
||||
width="302" height="349">
|
||||
</figure>
|
||||
</td>
|
||||
<td style="vertical-align:top;">Then change the note type to a CSS code.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<figure class="image">
|
||||
<img style="aspect-ratio:316/133;" src="Creating a custom theme_im.png"
|
||||
width="316" height="133">
|
||||
</figure>
|
||||
</td>
|
||||
<td style="vertical-align:top;">In the <i>Owned Attributes</i> section define the <code>#appTheme</code> attribute
|
||||
to point to any desired name. This is the name that will show up in the
|
||||
appearance section in settings.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<h2>Step 3. Define the theme's CSS</h2>
|
||||
<p>As a very simple example we will change the background color of the launcher
|
||||
pane to a shade of blue.</p>
|
||||
<p>To alter the different variables of the theme:</p><pre><code class="language-text-css">:root {
|
||||
--launcher-pane-background-color: #0d6efd;
|
||||
}</code></pre>
|
||||
<h2>Step 4. Activating the theme</h2>
|
||||
<p>Refresh the application (Ctrl+Shift+R is a good way to do so) and go to
|
||||
settings. You should see the newly created theme:</p>
|
||||
<p>
|
||||
<img src="2_Creating a custom theme_im.png" width="631" height="481">
|
||||
</p>
|
||||
<p>Afterwards the application will refresh itself with the new theme:</p>
|
||||
<p>
|
||||
<img src="4_Creating a custom theme_im.png" width="653" height="554">
|
||||
</p>
|
||||
<p>Do note that the theme will be based off of the legacy theme. To override
|
||||
that and base the theme on the new TriliumNext theme, see: <a class="reference-link"
|
||||
href="Customize%20the%20Next%20theme.html">Theme base (legacy vs. next)</a>
|
||||
</p>
|
||||
<h2>Step 5. Making changes</h2>
|
||||
<p>Simply go back to the note and change according to needs. To apply the
|
||||
changes to the current window, press Ctrl+Shift+R to refresh.</p>
|
||||
<p>It's a good idea to keep two windows, one for editing and the other one
|
||||
for previewing the changes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Before Width: | Height: | Size: 11 KiB |
@ -1,36 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Customize the Next theme</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Customize the Next theme</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<p>By default, any custom theme will be based on the legacy light theme.
|
||||
To use the TriliumNext theme instead, add the <code>#appThemeBase=next</code> attribute
|
||||
onto the existing theme. The <code>appTheme</code> attribute must also be
|
||||
present.</p>
|
||||
<p>
|
||||
<img src="Customize the Next theme_i.png" width="424" height="140">
|
||||
</p>
|
||||
<p>When <code>appThemeBase</code> is set to <code>next</code> it will use the
|
||||
“TriliumNext (auto)” theme. Any other value is ignored and will use the
|
||||
legacy white theme instead.</p>
|
||||
<h2>Overrides</h2>
|
||||
<p>Do note that the TriliumNext theme has a few more overrides than the legacy
|
||||
theme, so you might need to suffix <code>!important</code> if the style changes
|
||||
are not applied.</p><pre><code class="language-text-css">:root {
|
||||
--launcher-pane-background-color: #0d6efd !important;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Before Width: | Height: | Size: 14 KiB |
@ -1,180 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
<base target="_parent">
|
||||
<title data-trilium-title>Reference</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1 data-trilium-h1>Reference</h1>
|
||||
|
||||
<div class="ck-content">
|
||||
<h2>Detecting mobile vs. desktop</h2>
|
||||
<p>The mobile layout is different than the one on the desktop. Use <code>body.mobile</code> and <code>body.desktop</code> to
|
||||
differentiate between them.</p><pre><code class="language-text-css">body.mobile #root-widget {
|
||||
/* Do something on mobile */
|
||||
}
|
||||
|
||||
body.desktop #root-widget {
|
||||
/* Do something on desktop */
|
||||
}</code></pre>
|
||||
<p>Do note that there is also a “tablet mode” in the mobile layout. For that
|
||||
particular case media queries are required:</p><pre><code class="language-text-css">@media (max-width: 991px) {
|
||||
|
||||
#launcher-pane {
|
||||
|
||||
/* Do something on mobile layout */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (min-width: 992px) {
|
||||
|
||||
#launcher-pane {
|
||||
|
||||
/* Do something on mobile tablet + desktop layout */
|
||||
|
||||
}
|
||||
|
||||
}</code></pre>
|
||||
<h2>Detecting horizontal vs. vertical layout</h2>
|
||||
<p>The user can select between vertical layout (the classical one, where
|
||||
the launcher bar is on the left) and a horizontal layout (where the launcher
|
||||
bar is on the top and tabs are full-width).</p>
|
||||
<p>Different styles can be applied by using classes at <code>body</code> level:</p><pre><code class="language-text-x-trilium-auto">body.layout-vertical #left-pane {
|
||||
/* Do something */
|
||||
}
|
||||
|
||||
body.layout-horizontal #center-pane {
|
||||
/* Do something else */
|
||||
}</code></pre>
|
||||
<p>The two different layouts use different containers (but they are present
|
||||
in the DOM regardless of the user's choice), for example <code>#horizontal-main-container</code> and <code>#vertical-main-container</code> can
|
||||
be used to customize the background of the content section.</p>
|
||||
<h2>Detecting platform (Windows, macOS) or Electron</h2>
|
||||
<p>It is possible to add particular styles that only apply to a given platform
|
||||
by using the classes in <code>body</code>:</p>
|
||||
<figure class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Windows</th>
|
||||
<th>macOS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><pre><code class="language-text-x-trilium-auto">body.platform-win32 {
|
||||
background: red;
|
||||
}</code></pre>
|
||||
</td>
|
||||
<td><pre><code class="language-text-x-trilium-auto">body.platform-darwin {
|
||||
background: red;
|
||||
}</code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<p>It is also possible to only apply a style if running under Electron (desktop
|
||||
application):</p><pre><code class="language-text-x-trilium-auto">body.electron {
|
||||
background: blue;
|
||||
}</code></pre>
|
||||
<h3>Native title bar</h3>
|
||||
<p>It's possible to detect if the user has selected the native title bar
|
||||
or the custom title bar by querying against <code>body</code>:</p><pre><code class="language-text-x-trilium-auto">body.electron.native-titlebar {
|
||||
/* Do something */
|
||||
}
|
||||
|
||||
body.electron:not(.native-titlebar) {
|
||||
/* Do something else */
|
||||
}</code></pre>
|
||||
<h3>Native window buttons</h3>
|
||||
<p>When running under Electron with native title bar off, a feature was introduced
|
||||
to use the platform-specific window buttons such as the semaphore on macOS.</p>
|
||||
<p>See <a href="https://github.com/TriliumNext/Notes/pull/702">Native title bar buttons by eliandoran · Pull Request #702 · TriliumNext/Notes</a> for
|
||||
the original implementation of this feature, including screenshots.</p>
|
||||
<h4>On Windows</h4>
|
||||
<p>The colors of the native window button area can be adjusted using a RGB
|
||||
hex color:</p><pre><code class="language-text-x-trilium-auto">body {
|
||||
--native-titlebar-foreground: #ffffff;
|
||||
--native-titlebar-background: #ff0000;
|
||||
}</code></pre>
|
||||
<p>It is also possible to use transparency at the cost of reduced hover colors
|
||||
using a RGBA hex color:</p><pre><code class="language-text-x-trilium-auto">body {
|
||||
--native-titlebar-background: #ff0000aa;
|
||||
}</code></pre>
|
||||
<p>Note that the value is read when the window is initialized and then it
|
||||
is refreshed only when the user changes their light/dark mode preference.</p>
|
||||
<h4>On macOS</h4>
|
||||
<p>On macOS the semaphore window buttons are enabled by default when the
|
||||
native title bar is disabled. The offset of the buttons can be adjusted
|
||||
using:</p><pre><code class="language-text-css">body {
|
||||
--native-titlebar-darwin-x-offset: 12;
|
||||
--native-titlebar-darwin-y-offset: 14 !important;
|
||||
}</code></pre>
|
||||
<h3>Background/transparency effects on Windows (Mica)</h3>
|
||||
<p>Windows 11 offers a special background/transparency effect called Mica,
|
||||
which can be enabled by themes by setting the <code>--background-material</code> variable
|
||||
at <code>body</code> level:</p><pre><code class="language-text-css">body.electron.platform-win32 {
|
||||
--background-material: tabbed;
|
||||
}</code></pre>
|
||||
<p>The value can be either <code>tabbed</code> (especially useful for the horizontal
|
||||
layout) or <code>mica</code> (ideal for the vertical layout).</p>
|
||||
<p>Do note that the Mica effect is applied at <code>body</code> level and the
|
||||
theme needs to make the entire hierarchy (semi-)transparent in order for
|
||||
it to be visible. Use the TrilumNext theme as an inspiration.</p>
|
||||
<h2>Note icons, tab workspace accent color</h2>
|
||||
<p>Theme capabilities are small adjustments done through CSS variables that
|
||||
can affect the layout or the visual aspect of the application.</p>
|
||||
<p>In the tab bar, to display the icons of notes instead of the icon of the
|
||||
workspace:</p><pre><code class="language-text-css">:root {
|
||||
--tab-note-icons: true;
|
||||
}</code></pre>
|
||||
<p>When a workspace is hoisted for a given tab, it is possible to get the
|
||||
background color of that workspace, for example to apply a small strip
|
||||
on the tab instead of the whole background color:</p><pre><code class="language-text-css">.note-tab .note-tab-wrapper {
|
||||
--tab-background-color: initial !important;
|
||||
}
|
||||
|
||||
.note-tab .note-tab-wrapper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background-color: var(--workspace-tab-background-color);
|
||||
}</code></pre>
|
||||
<h2>Custom fonts</h2>
|
||||
<p>Currently the only way to include a custom font is to use <a class="reference-link"
|
||||
href="../Advanced%20topics/Custom%20resource%20providers.html">Custom resource providers</a>.
|
||||
Basically import a font into Trilium and assign it <code>#customResourceProvider=fonts/myfont.ttf</code> and
|
||||
then import the font in CSS via <code>/custom/fonts/myfont.ttf</code>.</p>
|
||||
<h2>Dark and light themes</h2>
|
||||
<p>A light theme needs to have the following CSS:</p><pre><code class="language-text-css">:root {
|
||||
--theme-style: light;
|
||||
}</code></pre>
|
||||
<p>if the theme is dark, then <code>--theme-style</code> needs to be <code>dark</code>.</p>
|
||||
<p>If the theme is auto (e.g. supports both light or dark based on <code>prefers-color-scheme</code>)
|
||||
it must also declare (in addition to setting <code>--theme-style</code> to
|
||||
either <code>light</code> or <code>dark</code>):</p><pre><code class="language-text-css">:root {
|
||||
|
||||
--theme-style-auto: true;
|
||||
|
||||
}</code></pre>
|
||||
<p>This will affect the behavior of the Electron application by informing
|
||||
the operating system of the color preference (e.g. background effects will
|
||||
appear correct on Windows).</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -6,6 +6,6 @@
|
||||
</head>
|
||||
<frameset cols="25%,75%">
|
||||
<frame name="navigation" src="navigation.html">
|
||||
<frame name="detail" src="User%20Guide/Features/Export%20as%20PDF.html">
|
||||
<frame name="detail" src="User%20Guide/New%20Features/Right-to-left%20text%20notes.html">
|
||||
</frameset>
|
||||
</html>
|
@ -9,17 +9,24 @@
|
||||
<ul>
|
||||
<li>User Guide
|
||||
<ul>
|
||||
<li>Features
|
||||
<li>New Features
|
||||
<ul>
|
||||
<li><a href="User%20Guide/Features/Export%20as%20PDF.html" target="detail">Export as PDF</a>
|
||||
<li><a href="User%20Guide/New%20Features/Right-to-left%20text%20notes.html"
|
||||
target="detail">Right-to-left text notes</a>
|
||||
</li>
|
||||
<li><a href="User%20Guide/Features/Zen%20mode.html" target="detail">Zen mode</a>
|
||||
<li><a href="User%20Guide/New%20Features/Zen%20mode.html" target="detail">Zen mode</a>
|
||||
</li>
|
||||
<li><a href="User%20Guide/New%20Features/Export%20as%20PDF.html" target="detail">Export as PDF</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Note Types
|
||||
<ul>
|
||||
<li><a href="User%20Guide/Note%20Types/Text.html" target="detail">Text</a>
|
||||
<li>Text
|
||||
<ul>
|
||||
<li><a href="User%20Guide/Note%20Types/Text/Content%20language.html" target="detail">Content language</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="User%20Guide/Note%20Types/Code.html" target="detail">Code</a>
|
||||
</li>
|
||||
@ -45,7 +52,7 @@
|
||||
</li>
|
||||
<li><a href="User%20Guide/Note%20Types/Mind%20Map.html" target="detail">Mind Map</a>
|
||||
</li>
|
||||
<li><a href="User%20Guide/Note%20Types/Geo%20Map.html" target="detail">Geo Map</a>
|
||||
<li><a href="User%20Guide/Note%20Types/Geo%20map.html" target="detail">Geo map</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -56,18 +63,6 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Theme development
|
||||
<ul>
|
||||
<li><a href="User%20Guide/Theme%20development/Creating%20a%20custom%20theme.html"
|
||||
target="detail">Creating a custom theme</a>
|
||||
</li>
|
||||
<li><a href="User%20Guide/Theme%20development/Customize%20the%20Next%20theme.html"
|
||||
target="detail">Customize the Next theme</a>
|
||||
</li>
|
||||
<li><a href="User%20Guide/Theme%20development/Reference.html" target="detail">Reference</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Scripting
|
||||
<ul>
|
||||
<li>Examples
|
||||
|
@ -28,8 +28,7 @@ const NOTE_TYPE_ICONS = {
|
||||
doc: "bx bxs-file-doc",
|
||||
contentWidget: "bx bxs-widget",
|
||||
mindMap: "bx bx-sitemap",
|
||||
geoMap: "bx bx-map-alt",
|
||||
taskList: "bx bx-list-check"
|
||||
geoMap: "bx bx-map-alt"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -37,25 +36,7 @@ const NOTE_TYPE_ICONS = {
|
||||
* end user. Those types should be used only for checking against, they are
|
||||
* not for direct use.
|
||||
*/
|
||||
export type NoteType =
|
||||
| "file"
|
||||
| "image"
|
||||
| "search"
|
||||
| "noteMap"
|
||||
| "launcher"
|
||||
| "doc"
|
||||
| "contentWidget"
|
||||
| "text"
|
||||
| "relationMap"
|
||||
| "render"
|
||||
| "canvas"
|
||||
| "mermaid"
|
||||
| "book"
|
||||
| "webView"
|
||||
| "code"
|
||||
| "mindMap"
|
||||
| "geoMap"
|
||||
| "taskList";
|
||||
export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "geoMap";
|
||||
|
||||
export interface NotePathRecord {
|
||||
isArchived: boolean;
|
||||
|
@ -1,34 +0,0 @@
|
||||
import type { Froca } from "../services/froca-interface.js";
|
||||
|
||||
export interface FTaskRow {
|
||||
taskId: string;
|
||||
parentNoteId: string;
|
||||
title: string;
|
||||
dueDate?: string;
|
||||
isDone?: boolean;
|
||||
utcDateModified: string;
|
||||
}
|
||||
|
||||
export default class FTask {
|
||||
private froca: Froca;
|
||||
taskId!: string;
|
||||
parentNoteId!: string;
|
||||
title!: string;
|
||||
dueDate?: string;
|
||||
isDone!: boolean;
|
||||
utcDateModified!: string;
|
||||
|
||||
constructor(froca: Froca, row: FTaskRow) {
|
||||
this.froca = froca;
|
||||
this.update(row);
|
||||
}
|
||||
|
||||
update(row: FTaskRow) {
|
||||
this.taskId = row.taskId;
|
||||
this.parentNoteId = row.parentNoteId;
|
||||
this.title = row.title;
|
||||
this.dueDate = row.dueDate;
|
||||
this.isDone = !!row.isDone;
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
}
|
||||
}
|
@ -23,6 +23,28 @@ async function removeAttributeById(noteId: string, attributeId: string) {
|
||||
await server.remove(`notes/${noteId}/attributes/${attributeId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute of the given note to the provided value if its truthy, or removes the attribute if the value is falsy.
|
||||
* For an attribute with an empty value, pass an empty string instead.
|
||||
*
|
||||
* @param note the note to set the attribute to.
|
||||
* @param type the type of attribute (label or relation).
|
||||
* @param name the name of the attribute to set.
|
||||
* @param value the value of the attribute to set.
|
||||
*/
|
||||
async function setAttribute(note: FNote, type: "label" | "relation", name: string, value: string | null | undefined) {
|
||||
if (value) {
|
||||
// Create or update the attribute.
|
||||
await server.put(`notes/${note.noteId}/set-attribute`, { type, name, value });
|
||||
} else {
|
||||
// Remove the attribute if it exists on the server but we don't define a value for it.
|
||||
const attributeId = note.getAttribute(type, name)?.attributeId;
|
||||
if (attributeId) {
|
||||
await server.remove(`notes/${note.noteId}/attributes/${attributeId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns - returns true if this attribute has the potential to influence the note in the argument.
|
||||
* That can happen in multiple ways:
|
||||
@ -66,6 +88,7 @@ function isAffecting(attrRow: AttributeRow, affectedNote: FNote | null | undefin
|
||||
export default {
|
||||
addLabel,
|
||||
setLabel,
|
||||
setAttribute,
|
||||
removeAttributeById,
|
||||
isAffecting
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ import FNote from "../entities/fnote.js";
|
||||
import FAttachment from "../entities/fattachment.js";
|
||||
import imageContextMenuService from "../menus/image_context_menu.js";
|
||||
import { applySingleBlockSyntaxHighlight, applySyntaxHighlight } from "./syntax_highlight.js";
|
||||
import { loadElkIfNeeded } from "./mermaid.js";
|
||||
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
||||
|
||||
let idCounter = 1;
|
||||
@ -226,7 +226,7 @@ async function renderMermaid(note: FNote | FAttachment, $renderedContent: JQuery
|
||||
await loadElkIfNeeded(content);
|
||||
const { svg } = await mermaid.mermaidAPI.render("in-mermaid-graph-" + idCounter++, content);
|
||||
|
||||
$renderedContent.append($(svg));
|
||||
$renderedContent.append($(postprocessMermaidSvg(svg)));
|
||||
} catch (e) {
|
||||
const $error = $("<p>The diagram could not displayed.</p>");
|
||||
|
||||
|
48
src/public/app/services/eslint.spec.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { lint } from "./eslint.js";
|
||||
import { trimIndentation } from "../../../../spec/support/utils.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("Linter", () => {
|
||||
it("reports some basic errors", async () => {
|
||||
const result = await lint(trimIndentation`
|
||||
for (const i = 0; i<10; i++) {
|
||||
}
|
||||
`);
|
||||
expect(result).toMatchObject([
|
||||
{ message: "'i' is constant.", },
|
||||
{ message: "Empty block statement." }
|
||||
]);
|
||||
});
|
||||
|
||||
it("reports no error for correct script", async () => {
|
||||
const result = await lint(trimIndentation`
|
||||
const foo = "bar";
|
||||
console.log(foo.toString());
|
||||
for (const x of [ 1, 2, 3]) {
|
||||
console.log(x?.toString());
|
||||
}
|
||||
|
||||
api.showMessage("Hi");
|
||||
`);
|
||||
expect(result.length).toBe(0);
|
||||
});
|
||||
|
||||
it("reports unused functions as warnings", async () => {
|
||||
const result = await lint(trimIndentation`
|
||||
function hello() { }
|
||||
function world() { }
|
||||
|
||||
console.log("Hello world");
|
||||
`);
|
||||
expect(result).toMatchObject([
|
||||
{
|
||||
message: "'hello' is defined but never used.",
|
||||
severity: 1
|
||||
},
|
||||
{
|
||||
message: "'world' is defined but never used.",
|
||||
severity: 1
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
25
src/public/app/services/eslint.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export async function lint(code: string) {
|
||||
|
||||
const Linter = (await import("eslint-linter-browserify")).Linter;
|
||||
const js = (await import("@eslint/js"));
|
||||
const globals = (await import("globals"));
|
||||
|
||||
return new Linter().verify(code, [
|
||||
js.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaVersion: 2024
|
||||
},
|
||||
globals: {
|
||||
...globals.browser,
|
||||
api: "readonly"
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"no-unused-vars": [ "warn", { vars: "local", args: "after-used" }]
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
}
|
@ -6,8 +6,6 @@ import appContext from "../components/app_context.js";
|
||||
import FBlob, { type FBlobRow } from "../entities/fblob.js";
|
||||
import FAttachment, { type FAttachmentRow } from "../entities/fattachment.js";
|
||||
import type { Froca } from "./froca-interface.js";
|
||||
import FTask from "../entities/ftask.js";
|
||||
import type { FTaskRow } from "../entities/ftask.js";
|
||||
|
||||
interface SubtreeResponse {
|
||||
notes: FNoteRow[];
|
||||
@ -39,7 +37,6 @@ class FrocaImpl implements Froca {
|
||||
attributes!: Record<string, FAttribute>;
|
||||
attachments!: Record<string, FAttachment>;
|
||||
blobPromises!: Record<string, Promise<void | FBlob> | null>;
|
||||
tasks!: Record<string, FTask>;
|
||||
|
||||
constructor() {
|
||||
this.initializedPromise = this.loadInitialTree();
|
||||
@ -55,7 +52,6 @@ class FrocaImpl implements Froca {
|
||||
this.attributes = {};
|
||||
this.attachments = {};
|
||||
this.blobPromises = {};
|
||||
this.tasks = {};
|
||||
|
||||
this.addResp(resp);
|
||||
}
|
||||
@ -372,24 +368,6 @@ class FrocaImpl implements Froca {
|
||||
});
|
||||
}
|
||||
|
||||
getTask(taskId: string) {
|
||||
return this.tasks[taskId];
|
||||
}
|
||||
|
||||
async getTasks(parentNoteId: string) {
|
||||
const taskRows = await server.get<FTaskRow[]>(`tasks/${parentNoteId}`);
|
||||
return this.processTaskRow(taskRows);
|
||||
}
|
||||
|
||||
processTaskRow(taskRows: FTaskRow[]): FTask[] {
|
||||
return taskRows.map((taskRow) => {
|
||||
const task = new FTask(this, taskRow);
|
||||
this.tasks[task.taskId] = task;
|
||||
|
||||
return task;
|
||||
});
|
||||
}
|
||||
|
||||
async getBlob(entityType: string, entityId: string) {
|
||||
// I'm not sure why we're not using blobIds directly, it would save us this composite key ...
|
||||
// perhaps one benefit is that we're always requesting the latest blob, not relying on perhaps faulty/slow
|
||||
|
@ -8,8 +8,6 @@ import FAttribute, { type FAttributeRow } from "../entities/fattribute.js";
|
||||
import FAttachment, { type FAttachmentRow } from "../entities/fattachment.js";
|
||||
import type { default as FNote, FNoteRow } from "../entities/fnote.js";
|
||||
import type { EntityChange } from "../server_types.js";
|
||||
import type { FTaskRow } from "../entities/ftask.js";
|
||||
import FTask from "../entities/ftask.js";
|
||||
|
||||
async function processEntityChanges(entityChanges: EntityChange[]) {
|
||||
const loadResults = new LoadResults(entityChanges);
|
||||
@ -39,8 +37,6 @@ async function processEntityChanges(entityChanges: EntityChange[]) {
|
||||
processAttachment(loadResults, ec);
|
||||
} else if (ec.entityName === "blobs" || ec.entityName === "etapi_tokens") {
|
||||
// NOOP
|
||||
} else if (ec.entityName === "tasks") {
|
||||
processTaskChange(loadResults, ec);
|
||||
} else {
|
||||
throw new Error(`Unknown entityName '${ec.entityName}'`);
|
||||
}
|
||||
@ -310,35 +306,6 @@ function processAttachment(loadResults: LoadResults, ec: EntityChange) {
|
||||
loadResults.addAttachmentRow(attachmentEntity);
|
||||
}
|
||||
|
||||
function processTaskChange(loadResults: LoadResults, ec: EntityChange) {
|
||||
if (ec.isErased && ec.entityId in froca.tasks) {
|
||||
utils.reloadFrontendApp(`${ec.entityName} '${ec.entityId}' is erased, need to do complete reload.`);
|
||||
return;
|
||||
}
|
||||
|
||||
let task = froca.tasks[ec.entityId];
|
||||
const taskEntity = ec.entity as FTaskRow;
|
||||
|
||||
if (ec.isErased || (ec.entity as any)?.isDeleted) {
|
||||
if (task) {
|
||||
delete froca.tasks[ec.entityId];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ec.entity) {
|
||||
if (task) {
|
||||
task.update(ec.entity as FTaskRow);
|
||||
} else {
|
||||
task = new FTask(froca, ec.entity as FTaskRow);
|
||||
froca.tasks[task.taskId] = task;
|
||||
}
|
||||
}
|
||||
|
||||
loadResults.addTaskRow(taskEntity);
|
||||
}
|
||||
|
||||
export default {
|
||||
processEntityChanges
|
||||
};
|
||||
|