mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
Merge branch 'develop' into refactor_replace-csurf
This commit is contained in:
commit
c8c501d717
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +1,2 @@
|
||||
package-lock.json linguist-generated=true
|
||||
**/package-lock.json linguist-generated=true
|
46
.github/workflows/dev.yml
vendored
46
.github/workflows/dev.yml
vendored
@ -16,27 +16,6 @@ env:
|
||||
TEST_TAG: ${{ github.repository_owner }}/notes:test
|
||||
|
||||
jobs:
|
||||
build_docker:
|
||||
name: Build Docker image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up node & dependencies
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
- name: Create server-package.json
|
||||
run: cat package.json | grep -v electron > server-package.json
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
test_dev:
|
||||
name: Test development
|
||||
runs-on: ubuntu-latest
|
||||
@ -54,9 +33,34 @@ jobs:
|
||||
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
build_docker:
|
||||
name: Build Docker image
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- test_dev
|
||||
steps:
|
||||
- uses: actions/checkout@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:
|
||||
context: .
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
test_docker:
|
||||
name: Check Docker build
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build_docker
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
|
17
.github/workflows/main-docker.yml
vendored
17
.github/workflows/main-docker.yml
vendored
@ -48,7 +48,11 @@ jobs:
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
|
||||
- run: npm ci
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Run the TypeScript build
|
||||
run: npx tsc
|
||||
@ -68,7 +72,7 @@ jobs:
|
||||
|
||||
- name: Validate container run output
|
||||
run: |
|
||||
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --name trilium_local ${{ env.TEST_TAG }})
|
||||
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --network=host -e TRILIUM_PORT=8082 --volume ./integration-tests/db:/home/node/trilium-data --name trilium_local ${{ env.TEST_TAG }})
|
||||
echo "Container ID: $CONTAINER_ID"
|
||||
|
||||
- name: Wait for the healthchecks to pass
|
||||
@ -78,6 +82,15 @@ jobs:
|
||||
wait-time: 50
|
||||
require-status: running
|
||||
require-healthy: true
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: TRILIUM_DOCKER=1 npx playwright test
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: Playwright report (${{ matrix.dockerfile }})
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
# Print the entire log of the container thus far, regardless if the healthcheck failed or succeeded
|
||||
- name: Print entire log
|
||||
|
57
e2e/i18n.spec.ts
Normal file
57
e2e/i18n.spec.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { test, expect, Page } from "@playwright/test";
|
||||
import App from "./support/app";
|
||||
|
||||
test.afterEach(async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
// Ensure English is set after each locale change to avoid any leaks to other tests.
|
||||
await app.setOption("locale", "en");
|
||||
});
|
||||
|
||||
test("Displays translation on desktop", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
await expect(page.locator("#left-pane .quick-search input"))
|
||||
.toHaveAttribute("placeholder", "Quick search");
|
||||
});
|
||||
|
||||
test("Displays translation on mobile", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto({ isMobile: true });
|
||||
|
||||
await expect(page.locator("#mobile-sidebar-wrapper .quick-search input"))
|
||||
.toHaveAttribute("placeholder", "Quick search");
|
||||
});
|
||||
|
||||
test("Displays translations in Settings", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.closeAllTabs();
|
||||
await app.goToSettings();
|
||||
await app.noteTree.getByText("Appearance").click();
|
||||
|
||||
await expect(app.currentNoteSplit).toContainText("Localization");
|
||||
await expect(app.currentNoteSplit).toContainText("Language");
|
||||
});
|
||||
|
||||
test("User can change language from settings", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
await app.closeAllTabs();
|
||||
await app.goToSettings();
|
||||
await app.noteTree.getByText("Appearance").click();
|
||||
|
||||
// Check that the default value (English) is set.
|
||||
await expect(app.currentNoteSplit).toContainText("Theme");
|
||||
const languageCombobox = await 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 });
|
||||
|
||||
// Select English again.
|
||||
await languageCombobox.selectOption("en");
|
||||
await expect(app.currentNoteSplit).toContainText("Language", { timeout: 15000 });
|
||||
});
|
@ -3,8 +3,8 @@ import App from "../support/app";
|
||||
|
||||
const NOTE_TITLE = "Trilium Integration Test DB";
|
||||
|
||||
test("Can drag tabs around", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Can drag tabs around", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
// [1]: Trilium Integration Test DB note
|
||||
@ -29,8 +29,8 @@ test("Can drag tabs around", async ({ page }) => {
|
||||
await expect(app.getTab(0)).toContainText(NOTE_TITLE);
|
||||
});
|
||||
|
||||
test("Can drag tab to new window", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Can drag tab to new window", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
|
||||
await app.closeAllTabs();
|
||||
@ -49,11 +49,11 @@ test("Can drag tab to new window", async ({ page }) => {
|
||||
await page.mouse.move(x, y + tabPos.height + 100, { steps: 5 });
|
||||
await page.mouse.up();
|
||||
} else {
|
||||
fail("Unable to determine tab position");
|
||||
test.fail(true, "Unable to determine tab position");
|
||||
}
|
||||
|
||||
// Wait for the popup to show
|
||||
const popup = await popupPromise;
|
||||
const popupApp = new App(popup);
|
||||
const popupApp = new App(popup, context);
|
||||
await expect(popupApp.getActiveTab()).toHaveText(NOTE_TITLE);
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { test, expect, Page } from "@playwright/test";
|
||||
import App from "../support/app";
|
||||
|
||||
test("Displays lint warnings for backend script", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Displays lint warnings for backend script", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.closeAllTabs();
|
||||
await app.goToNoteInNewTab("Backend script with lint warnings");
|
||||
@ -10,7 +10,7 @@ test("Displays lint warnings for backend script", async ({ page }) => {
|
||||
const codeEditor = app.currentNoteSplit.locator(".CodeMirror");
|
||||
|
||||
// Expect two warning signs in the gutter.
|
||||
expect(codeEditor.locator(".CodeMirror-gutter-wrapper .CodeMirror-lint-marker-warning")).toHaveCount(2);
|
||||
await expect(codeEditor.locator(".CodeMirror-gutter-wrapper .CodeMirror-lint-marker-warning")).toHaveCount(2);
|
||||
|
||||
// Hover over hello
|
||||
await codeEditor.getByText("hello").first().hover();
|
||||
@ -21,8 +21,8 @@ test("Displays lint warnings for backend script", async ({ page }) => {
|
||||
await expectTooltip(page, "'world' is defined but never used.");
|
||||
});
|
||||
|
||||
test("Displays lint errors for backend script", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Displays lint errors for backend script", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.closeAllTabs();
|
||||
await app.goToNoteInNewTab("Backend script with lint errors");
|
||||
|
22
e2e/note_types/mindmap.ts
Normal file
22
e2e/note_types/mindmap.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { test, expect, Page } from "@playwright/test";
|
||||
import App from "../support/app";
|
||||
|
||||
test("displays simple map", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.goToNoteInNewTab("Sample mindmap");
|
||||
|
||||
await expect(app.currentNoteSplit).toContainText("Hello world");
|
||||
await expect(app.currentNoteSplit).toContainText("1");
|
||||
await expect(app.currentNoteSplit).toContainText("1a");
|
||||
});
|
||||
|
||||
test("displays note settings", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.goToNoteInNewTab("Sample mindmap");
|
||||
|
||||
await app.currentNoteSplit.getByText("Hello world").click({ force: true });
|
||||
const nodeMenu = app.currentNoteSplit.locator(".node-menu");
|
||||
await expect(nodeMenu).toBeVisible();
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
import { test, expect, Page } from "@playwright/test";
|
||||
import App from "../support/app";
|
||||
|
||||
test("Table of contents is displayed", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Table of contents is displayed", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.closeAllTabs();
|
||||
await app.goToNoteInNewTab("Table of contents");
|
||||
@ -36,8 +36,8 @@ test("Table of contents is displayed", async ({ page }) => {
|
||||
await expect(rootList.locator("> ol").nth(1).locator("> ol > ol > ol")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("Highlights list is displayed", async ({ page }) => {
|
||||
const app = new App(page);
|
||||
test("Highlights list is displayed", async ({ page, context }) => {
|
||||
const app = new App(page, context);
|
||||
await app.goto();
|
||||
await app.closeAllTabs();
|
||||
await app.goToNoteInNewTab("Highlights list");
|
||||
|
@ -1,27 +1,46 @@
|
||||
import { Locator, Page, expect } from "@playwright/test";
|
||||
import { expect, Locator, Page } from "@playwright/test";
|
||||
import type { BrowserContext } from "@playwright/test";
|
||||
|
||||
interface GotoOpts {
|
||||
isMobile?: boolean;
|
||||
}
|
||||
|
||||
const BASE_URL = "http://127.0.0.1:8082";
|
||||
|
||||
export default class App {
|
||||
readonly page: Page;
|
||||
readonly context: BrowserContext;
|
||||
|
||||
readonly tabBar: Locator;
|
||||
readonly noteTree: Locator;
|
||||
readonly currentNoteSplit: Locator;
|
||||
readonly sidebar: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
constructor(page: Page, context: BrowserContext) {
|
||||
this.page = page;
|
||||
this.context = context;
|
||||
|
||||
this.tabBar = page.locator(".tab-row-widget-container");
|
||||
this.noteTree = page.locator(".tree-wrapper");
|
||||
this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)")
|
||||
this.sidebar = page.locator("#right-pane");
|
||||
}
|
||||
|
||||
async goto() {
|
||||
async goto(opts: GotoOpts = {}) {
|
||||
await this.context.addCookies([
|
||||
{
|
||||
url: BASE_URL,
|
||||
name: "trilium-device",
|
||||
value: opts.isMobile ? "mobile" : "desktop"
|
||||
}
|
||||
]);
|
||||
|
||||
await this.page.goto("/", { waitUntil: "networkidle" });
|
||||
|
||||
// Wait for the page to load.
|
||||
await expect(this.page.locator(".tree"))
|
||||
.toContainText("Trilium Integration Test");
|
||||
await this.closeAllTabs();
|
||||
}
|
||||
|
||||
async goToNoteInNewTab(noteTitle: string) {
|
||||
@ -31,6 +50,10 @@ export default class App {
|
||||
await autocomplete.press("Enter");
|
||||
}
|
||||
|
||||
async goToSettings() {
|
||||
await this.page.locator(".launcher-button.bx-cog").click();
|
||||
}
|
||||
|
||||
getTab(tabIndex: number) {
|
||||
return this.tabBar.locator(".note-tab-wrapper").nth(tabIndex);
|
||||
}
|
||||
@ -39,18 +62,49 @@ export default class App {
|
||||
return this.tabBar.locator(".note-tab[active]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all the tabs in the client by issuing a command.
|
||||
*/
|
||||
async closeAllTabs() {
|
||||
await this.getTab(0).click({ button: "right" });
|
||||
await this.page.waitForTimeout(500); // TODO: context menu won't dismiss otherwise
|
||||
await this.page.getByText("Close all tabs").click({ force: true });
|
||||
await this.triggerCommand("closeAllTabs");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new tab by cliking on the + button near the tab bar.
|
||||
*/
|
||||
async addNewTab() {
|
||||
await this.page.locator('[data-trigger-command="openNewTab"]').click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a given title in the note tree and clicks on it. Useful for selecting option pages in settings in a similar fashion as the user.
|
||||
* @param title the title of the note to click, as displayed in the note tree.
|
||||
*/
|
||||
async clickNoteOnNoteTreeByTitle(title: string) {
|
||||
this.noteTree.getByText(title).click();
|
||||
await this.noteTree.getByText(title).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes any Trilium command on the client.
|
||||
* @param command the command to send.
|
||||
*/
|
||||
async triggerCommand(command: string) {
|
||||
await this.page.evaluate(async (command: string) => {
|
||||
await (window as any).glob.appContext.triggerCommand(command);
|
||||
}, command);
|
||||
}
|
||||
|
||||
async setOption(key: string, value: string) {
|
||||
const csrfToken = await this.page.evaluate(() => {
|
||||
return (window as any).glob.csrfToken;
|
||||
});
|
||||
|
||||
expect(csrfToken).toBeTruthy();
|
||||
await expect(await this.page.request.put(`${BASE_URL}/api/options/${key}/${value}`, {
|
||||
headers: {
|
||||
"x-csrf-token": csrfToken
|
||||
}
|
||||
})).toBeOK();
|
||||
}
|
||||
|
||||
}
|
||||
|
Binary file not shown.
@ -1,43 +0,0 @@
|
||||
import test, { expect } from "@playwright/test";
|
||||
|
||||
test("User can change language from settings", async ({ page }) => {
|
||||
await page.goto("http://localhost:8082");
|
||||
|
||||
// Clear all tabs
|
||||
await page.locator(".note-tab:first-of-type").locator("div").nth(1).click({ button: "right" });
|
||||
await page.getByText("Close all tabs").click();
|
||||
|
||||
// Go to options -> Appearance
|
||||
await page.locator("#launcher-pane div").filter({ hasText: "Options Open New Window" }).getByRole("button").click();
|
||||
await page.locator("#launcher-pane").getByText("Options").click();
|
||||
await page.locator("#center-pane").getByText("Appearance").click();
|
||||
|
||||
// Check that the default value (English) is set.
|
||||
await expect(page.locator("#center-pane")).toContainText("Theme");
|
||||
const languageCombobox = await page.getByRole("combobox").first();
|
||||
await expect(languageCombobox).toHaveValue("en");
|
||||
|
||||
// Select Chinese and ensure the translation is set.
|
||||
languageCombobox.selectOption("cn");
|
||||
await expect(page.locator("#center-pane")).toContainText("主题");
|
||||
|
||||
// Select English again.
|
||||
languageCombobox.selectOption("en");
|
||||
});
|
||||
|
||||
test("Restores language on start-up on desktop", async ({ page, context }) => {
|
||||
await page.goto("http://localhost:8082");
|
||||
await expect(page.locator("#launcher-pane").first()).toContainText("Open New Window");
|
||||
});
|
||||
|
||||
test("Restores language on start-up on mobile", async ({ page, context }) => {
|
||||
await context.addCookies([
|
||||
{
|
||||
url: "http://localhost:8082",
|
||||
name: "trilium-device",
|
||||
value: "mobile"
|
||||
}
|
||||
]);
|
||||
await page.goto("http://localhost:8082");
|
||||
await expect(page.locator("#launcher-pane div").first()).toContainText("Open New Window");
|
||||
});
|
670
package-lock.json
generated
670
package-lock.json
generated
@ -70,7 +70,7 @@
|
||||
"marked": "15.0.6",
|
||||
"mermaid": "11.4.1",
|
||||
"mime-types": "2.1.35",
|
||||
"mind-elixir": "4.3.5",
|
||||
"mind-elixir": "4.3.6",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"normalize-strings": "1.1.1",
|
||||
"normalize.css": "8.0.1",
|
||||
@ -91,7 +91,7 @@
|
||||
"stream-throttle": "0.1.3",
|
||||
"striptags": "3.2.0",
|
||||
"tmp": "0.2.3",
|
||||
"ts-loader": "9.5.1",
|
||||
"ts-loader": "9.5.2",
|
||||
"turndown": "7.2.0",
|
||||
"unescape": "1.0.1",
|
||||
"vanilla-js-wheel-zoom": "9.0.4",
|
||||
@ -109,6 +109,7 @@
|
||||
"@electron-forge/maker-squirrel": "7.6.0",
|
||||
"@electron-forge/maker-zip": "7.6.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.6.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@playwright/test": "1.49.1",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
@ -131,7 +132,7 @@
|
||||
"@types/jsdom": "21.1.7",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/multer": "1.4.12",
|
||||
"@types/node": "22.10.5",
|
||||
"@types/node": "22.10.6",
|
||||
"@types/safe-compare": "1.1.2",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/sax": "1.2.7",
|
||||
@ -147,8 +148,6 @@
|
||||
"@types/yargs": "17.0.33",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "33.3.1",
|
||||
"electron-packager": "17.1.2",
|
||||
"electron-rebuild": "3.2.9",
|
||||
"esm": "3.2.25",
|
||||
"iconsur": "1.7.0",
|
||||
"jasmine": "5.5.0",
|
||||
@ -4333,9 +4332,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz",
|
||||
"integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==",
|
||||
"version": "22.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz",
|
||||
"integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5098,13 +5097,6 @@
|
||||
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
|
||||
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/archiver": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz",
|
||||
@ -5194,36 +5186,6 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/are-we-there-yet": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
|
||||
"integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
|
||||
"deprecated": "This package is no longer supported.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/are-we-there-yet/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
@ -5807,19 +5769,6 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-fill": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
|
||||
@ -6520,16 +6469,6 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"color-support": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/colorette": {
|
||||
"version": "2.0.20",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||
@ -6687,13 +6626,6 @@
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
@ -7706,13 +7638,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
@ -8344,307 +8269,6 @@
|
||||
"keyboardevents-areequal": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager": {
|
||||
"version": "17.1.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-17.1.2.tgz",
|
||||
"integrity": "sha512-XofXdikjYI7MVBcnXeoOvRR+yFFFHOLs3J7PF5KYQweigtgLshcH4W660PsvHr4lYZ03JBpLyEcUB8DzHZ+BNw==",
|
||||
"deprecated": "Please use @electron/packager moving forward. There is no API change, just a package name change",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/get": "^2.0.0",
|
||||
"@electron/notarize": "^1.2.3",
|
||||
"@electron/osx-sign": "^1.0.5",
|
||||
"@electron/universal": "^1.3.2",
|
||||
"cross-spawn-windows-exe": "^1.2.0",
|
||||
"debug": "^4.0.1",
|
||||
"extract-zip": "^2.0.0",
|
||||
"filenamify": "^4.1.0",
|
||||
"fs-extra": "^11.1.0",
|
||||
"galactus": "^1.0.0",
|
||||
"get-package-info": "^1.0.0",
|
||||
"junk": "^3.1.0",
|
||||
"parse-author": "^2.0.0",
|
||||
"plist": "^3.0.0",
|
||||
"rcedit": "^3.0.1",
|
||||
"resolve": "^1.1.6",
|
||||
"semver": "^7.1.3",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron-packager": "bin/electron-packager.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.17.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/electron/electron-packager?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/get": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
|
||||
"integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^2.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"got": "^11.8.5",
|
||||
"progress": "^2.0.3",
|
||||
"semver": "^6.2.0",
|
||||
"sumchecker": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"global-agent": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/get/node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/get/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/get/node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/notarize": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.4.tgz",
|
||||
"integrity": "sha512-W5GQhJEosFNafewnS28d3bpQ37/s91CDWqxVchHfmv2dQSTWpOzNlUVQwYzC1ay5bChRV/A9BTL68yj0Pa+TSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^9.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/notarize/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/notarize/node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/universal": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz",
|
||||
"integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@malept/cross-spawn-promise": "^1.1.0",
|
||||
"debug": "^4.3.1",
|
||||
"dir-compare": "^3.0.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"minimatch": "^3.0.4",
|
||||
"plist": "^3.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/universal/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@electron/universal/node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/@malept/cross-spawn-promise": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
|
||||
"integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/malept"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/dir-compare": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz",
|
||||
"integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal": "^1.0.0",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-packager/node_modules/rcedit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.1.0.tgz",
|
||||
"integrity": "sha512-WRlRdY1qZbu1L11DklT07KuHfRk42l0NFFJdaExELEu4fEQ982bP5Z6OWGPj/wLLIuKRQDCxZJGAwoFsxhZhNA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn-windows-exe": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-rebuild": {
|
||||
"version": "3.2.9",
|
||||
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz",
|
||||
"integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==",
|
||||
"deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"debug": "^4.1.1",
|
||||
"detect-libc": "^2.0.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"got": "^11.7.0",
|
||||
"lzma-native": "^8.0.5",
|
||||
"node-abi": "^3.0.0",
|
||||
"node-api-version": "^0.1.4",
|
||||
"node-gyp": "^9.0.0",
|
||||
"ora": "^5.1.0",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.0.5",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron-rebuild": "lib/src/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-rebuild/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-rebuild/node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-rebuild/node_modules/node-api-version": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
|
||||
"integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-squirrel-startup": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.1.tgz",
|
||||
@ -10101,82 +9725,6 @@
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
|
||||
"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
|
||||
"deprecated": "This package is no longer supported.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"aproba": "^1.0.3 || ^2.0.0",
|
||||
"color-support": "^1.1.3",
|
||||
"console-control-strings": "^1.1.0",
|
||||
"has-unicode": "^2.0.1",
|
||||
"signal-exit": "^3.0.7",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wide-align": "^1.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/gauge/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/generate-function": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||
@ -10553,13 +10101,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
@ -12397,40 +11938,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lzma-native": {
|
||||
"version": "8.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
|
||||
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^3.1.0",
|
||||
"node-gyp-build": "^4.2.1",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"lzmajs": "bin/lzmajs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lzma-native/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/macos-alias": {
|
||||
"version": "0.2.12",
|
||||
"resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.12.tgz",
|
||||
@ -12817,9 +12324,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mind-elixir": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/mind-elixir/-/mind-elixir-4.3.5.tgz",
|
||||
"integrity": "sha512-I1Mxc/jCwHEDMecDjQVpc+WShmzrEnIv6+MnWPauJ0LAiOXMBQB/wpKqlF4bTp+kCqzOHMYryAvIWm0jvloZ8Q==",
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/mind-elixir/-/mind-elixir-4.3.6.tgz",
|
||||
"integrity": "sha512-6E9DT5vOYJ7DMDFXJlAnKU3Q6ekwBkR48Tjo6PchEcxJjPURJsiIASxtIeZCfvp8V39N4WyIa3Yt7Q/SFQkVfw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/minimalistic-assert": {
|
||||
@ -13086,13 +12593,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
|
||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-api-version": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz",
|
||||
@ -13145,61 +12645,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
|
||||
"integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"env-paths": "^2.2.0",
|
||||
"exponential-backoff": "^3.1.1",
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.2.6",
|
||||
"make-fetch-happen": "^10.0.3",
|
||||
"nopt": "^6.0.0",
|
||||
"npmlog": "^6.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.2",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"node-gyp": "bin/node-gyp.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13 || ^14.13 || >=16"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.8.4",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
|
||||
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||
@ -13406,23 +12851,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/npmlog": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
|
||||
"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
|
||||
"deprecated": "This package is no longer supported.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"are-we-there-yet": "^3.0.0",
|
||||
"console-control-strings": "^1.1.0",
|
||||
"gauge": "^4.0.3",
|
||||
"set-blocking": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
@ -15761,13 +15189,6 @@
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
@ -16995,9 +16416,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.5.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
|
||||
"integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
|
||||
"version": "9.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
|
||||
"integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
@ -17941,71 +17362,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wide-align/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wildcard": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||
|
10
package.json
10
package.json
@ -36,6 +36,7 @@
|
||||
"build-frontend-docs": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js",
|
||||
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
|
||||
"webpack": "cross-env node --import ./loader-register.js node_modules/webpack/bin/webpack.js -c webpack.config.ts",
|
||||
"test-playwright": "playwright test",
|
||||
"test-jasmine": "cross-env TRILIUM_DATA_DIR=./data-test tsx ./node_modules/jasmine/bin/jasmine.js",
|
||||
"test-es6": "tsx -r esm spec-es6/attribute_parser.spec.ts",
|
||||
"test": "npm run test-jasmine && npm run test-es6",
|
||||
@ -115,7 +116,7 @@
|
||||
"marked": "15.0.6",
|
||||
"mermaid": "11.4.1",
|
||||
"mime-types": "2.1.35",
|
||||
"mind-elixir": "4.3.5",
|
||||
"mind-elixir": "4.3.6",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"normalize-strings": "1.1.1",
|
||||
"normalize.css": "8.0.1",
|
||||
@ -136,7 +137,7 @@
|
||||
"stream-throttle": "0.1.3",
|
||||
"striptags": "3.2.0",
|
||||
"tmp": "0.2.3",
|
||||
"ts-loader": "9.5.1",
|
||||
"ts-loader": "9.5.2",
|
||||
"turndown": "7.2.0",
|
||||
"unescape": "1.0.1",
|
||||
"vanilla-js-wheel-zoom": "9.0.4",
|
||||
@ -151,6 +152,7 @@
|
||||
"@electron-forge/maker-squirrel": "7.6.0",
|
||||
"@electron-forge/maker-zip": "7.6.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.6.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@playwright/test": "1.49.1",
|
||||
"@types/archiver": "6.0.3",
|
||||
"@types/better-sqlite3": "7.6.12",
|
||||
@ -173,7 +175,7 @@
|
||||
"@types/jsdom": "21.1.7",
|
||||
"@types/mime-types": "2.1.4",
|
||||
"@types/multer": "1.4.12",
|
||||
"@types/node": "22.10.5",
|
||||
"@types/node": "22.10.6",
|
||||
"@types/safe-compare": "1.1.2",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/sax": "1.2.7",
|
||||
@ -189,8 +191,6 @@
|
||||
"@types/yargs": "17.0.33",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "33.3.1",
|
||||
"electron-packager": "17.1.2",
|
||||
"electron-rebuild": "3.2.9",
|
||||
"esm": "3.2.25",
|
||||
"iconsur": "1.7.0",
|
||||
"jasmine": "5.5.0",
|
||||
|
@ -73,9 +73,9 @@ export default defineConfig({
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
webServer: !process.env.TRILIUM_DOCKER ? {
|
||||
command: 'npm run integration-mem-db-dev',
|
||||
url: SERVER_URL,
|
||||
// reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
reuseExistingServer: !process.env.CI,
|
||||
} : undefined,
|
||||
});
|
||||
|
138
spec-es6/data_dir.spec.ts
Normal file
138
spec-es6/data_dir.spec.ts
Normal file
@ -0,0 +1,138 @@
|
||||
import { describe, it, execute, expect } from "./mini_test.ts";
|
||||
|
||||
import { getPlatformAppDataDir, getDataDirs} from "../src/services/data_dir.ts"
|
||||
|
||||
|
||||
|
||||
describe("data_dir.ts unit tests", () => {
|
||||
|
||||
describe("#getPlatformAppDataDir()", () => {
|
||||
|
||||
type TestCaseGetPlatformAppDataDir = [
|
||||
description: string,
|
||||
fnValue: Parameters<typeof getPlatformAppDataDir>,
|
||||
expectedValueFn: (val: ReturnType<typeof getPlatformAppDataDir>) => boolean
|
||||
]
|
||||
const testCases: TestCaseGetPlatformAppDataDir[] = [
|
||||
|
||||
[
|
||||
"w/ unsupported OS it should return 'null'",
|
||||
["aix", undefined],
|
||||
(val) => val === null
|
||||
],
|
||||
|
||||
[
|
||||
"w/ win32 and no APPDATA set it should return 'null'",
|
||||
["win32", undefined],
|
||||
(val) => val === null
|
||||
],
|
||||
|
||||
[
|
||||
"w/ win32 and set APPDATA it should return set 'APPDATA'",
|
||||
["win32", "AppData"],
|
||||
(val) => val === "AppData"
|
||||
],
|
||||
|
||||
[
|
||||
"w/ linux it should return '/.local/share'",
|
||||
["linux", undefined],
|
||||
(val) => val !== null && val.endsWith("/.local/share")
|
||||
],
|
||||
|
||||
[
|
||||
"w/ linux and wrongly set APPDATA it should ignore APPDATA and return /.local/share",
|
||||
["linux", "FakeAppData"],
|
||||
(val) => val !== null && val.endsWith("/.local/share")
|
||||
],
|
||||
|
||||
[
|
||||
"w/ darwin it should return /Library/Application Support",
|
||||
["darwin", undefined],
|
||||
(val) => val !== null && val.endsWith("/Library/Application Support")
|
||||
],
|
||||
];
|
||||
|
||||
testCases.forEach(testCase => {
|
||||
const [testDescription, value, isExpected] = testCase;
|
||||
return it(testDescription, () => {
|
||||
const actual = getPlatformAppDataDir(...value);
|
||||
const result = isExpected(actual);
|
||||
expect(result).toBeTruthy()
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
describe("#getTriliumDataDir", () => {
|
||||
// TODO
|
||||
})
|
||||
|
||||
describe("#getDataDirs()", () => {
|
||||
|
||||
const envKeys: Omit<keyof ReturnType<typeof getDataDirs>, "TRILIUM_DATA_DIR">[] = [
|
||||
"DOCUMENT_PATH",
|
||||
"BACKUP_DIR",
|
||||
"LOG_DIR",
|
||||
"ANONYMIZED_DB_DIR",
|
||||
"CONFIG_INI_PATH",
|
||||
];
|
||||
|
||||
const setMockedEnv = (prefix: string | null) => {
|
||||
envKeys.forEach(key => {
|
||||
if (prefix) {
|
||||
process.env[`TRILIUM_${key}`] = `${prefix}_${key}`
|
||||
} else {
|
||||
delete process.env[`TRILIUM_${key}`]
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
it("w/ process.env values present, it should return an object using values from process.env", () => {
|
||||
|
||||
// set mocked values
|
||||
const mockValuePrefix = "MOCK";
|
||||
setMockedEnv(mockValuePrefix);
|
||||
|
||||
// get result
|
||||
const result = getDataDirs(`${mockValuePrefix}_TRILIUM_DATA_DIR`);
|
||||
|
||||
for (const key in result) {
|
||||
expect(result[key]).toEqual(`${mockValuePrefix}_${key}`)
|
||||
}
|
||||
})
|
||||
|
||||
it("w/ NO process.env values present, it should return an object using supplied TRILIUM_DATA_DIR as base", () => {
|
||||
|
||||
// make sure values are undefined
|
||||
setMockedEnv(null);
|
||||
|
||||
const mockDataDir = "/home/test/MOCK_TRILIUM_DATA_DIR"
|
||||
const result = getDataDirs(mockDataDir);
|
||||
|
||||
for (const key in result) {
|
||||
expect(result[key].startsWith(mockDataDir)).toBeTruthy()
|
||||
}
|
||||
})
|
||||
|
||||
it("should ignore attempts to change a property on the returned object", () => {
|
||||
|
||||
// make sure values are undefined
|
||||
setMockedEnv(null);
|
||||
|
||||
const mockDataDir = "/home/test/MOCK_TRILIUM_DATA_DIR"
|
||||
const result = getDataDirs(mockDataDir);
|
||||
|
||||
//@ts-expect-error - attempt to change value of readonly property
|
||||
result.BACKUP_DIR = "attempt to change";
|
||||
|
||||
for (const key in result) {
|
||||
expect(result[key].startsWith(mockDataDir)).toBeTruthy()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
execute()
|
@ -3,7 +3,7 @@ import BBranch from "../../src/becca/entities/bbranch.js";
|
||||
import BAttribute from "../../src/becca/entities/battribute.js";
|
||||
import becca from "../../src/becca/becca.js";
|
||||
import randtoken from "rand-token";
|
||||
import SearchResult from "../../src/services/search/search_result.js";
|
||||
import type SearchResult from "../../src/services/search/search_result.js";
|
||||
import type { NoteType } from "../../src/becca/entities/rows.js";
|
||||
randtoken.generator({ source: "crypto" });
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import AndExp from "../../src/services/search/expressions/and.js";
|
||||
import AttributeExistsExp from "../../src/services/search/expressions/attribute_exists.js";
|
||||
import Expression from "../../src/services/search/expressions/expression.js";
|
||||
import type Expression from "../../src/services/search/expressions/expression.js";
|
||||
import LabelComparisonExp from "../../src/services/search/expressions/label_comparison.js";
|
||||
import NotExp from "../../src/services/search/expressions/not.js";
|
||||
import NoteContentFulltextExp from "../../src/services/search/expressions/note_content_fulltext.js";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import child_process from "child_process";
|
||||
import type child_process from "child_process";
|
||||
|
||||
let etapiAuthToken: string | undefined;
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
import sql from "../services/sql.js";
|
||||
import NoteSet from "../services/search/note_set.js";
|
||||
import NotFoundError from "../errors/not_found_error.js";
|
||||
import BOption from "./entities/boption.js";
|
||||
import BNote from "./entities/bnote.js";
|
||||
import BEtapiToken from "./entities/betapi_token.js";
|
||||
import BAttribute from "./entities/battribute.js";
|
||||
import BBranch from "./entities/bbranch.js";
|
||||
import type BOption from "./entities/boption.js";
|
||||
import type BNote from "./entities/bnote.js";
|
||||
import type BEtapiToken from "./entities/betapi_token.js";
|
||||
import type BAttribute from "./entities/battribute.js";
|
||||
import type BBranch from "./entities/bbranch.js";
|
||||
import BRevision from "./entities/brevision.js";
|
||||
import BAttachment from "./entities/battachment.js";
|
||||
import type { AttachmentRow, BlobRow, RevisionRow } from "./entities/rows.js";
|
||||
import BBlob from "./entities/bblob.js";
|
||||
import BRecentNote from "./entities/brecent_note.js";
|
||||
import AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
|
||||
interface AttachmentOpts {
|
||||
includeContentLength?: boolean;
|
||||
|
@ -12,7 +12,7 @@ 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 } from "./entities/rows.js";
|
||||
import AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import ws from "../services/ws.js";
|
||||
|
||||
const beccaLoaded = new Promise<void>(async (res, rej) => {
|
||||
|
@ -9,7 +9,7 @@ import cls from "../../services/cls.js";
|
||||
import log from "../../services/log.js";
|
||||
import protectedSessionService from "../../services/protected_session.js";
|
||||
import blobService from "../../services/blob.js";
|
||||
import Becca, { type ConstructorData } from "../becca-interface.js";
|
||||
import type { default as Becca, ConstructorData } from "../becca-interface.js";
|
||||
import becca from "../becca.js";
|
||||
|
||||
interface ContentOpts {
|
||||
|
@ -7,8 +7,8 @@ import sql from "../../services/sql.js";
|
||||
import protectedSessionService from "../../services/protected_session.js";
|
||||
import log from "../../services/log.js";
|
||||
import type { AttachmentRow } from "./rows.js";
|
||||
import BNote from "./bnote.js";
|
||||
import BBranch from "./bbranch.js";
|
||||
import type BNote from "./bnote.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
import noteService from "../../services/notes.js";
|
||||
|
||||
const attachmentRoleToNoteTypeMapping = {
|
||||
|
@ -15,7 +15,7 @@ import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
import eventService from "../../services/events.js";
|
||||
import type { AttachmentRow, AttributeType, NoteRow, NoteType, RevisionRow } from "./rows.js";
|
||||
import BBranch from "./bbranch.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
import BAttribute from "./battribute.js";
|
||||
import type { NotePojo } from "../becca-interface.js";
|
||||
import searchService from "../../services/search/services/search.js";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { ConstructorData } from "./becca-interface.js";
|
||||
import AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import type AbstractBeccaEntity from "./entities/abstract_becca_entity.js";
|
||||
import BAttachment from "./entities/battachment.js";
|
||||
import BAttribute from "./entities/battribute.js";
|
||||
import BBlob from "./entities/bblob.js";
|
||||
|
@ -3,7 +3,7 @@ import log from "../services/log.js";
|
||||
import beccaService from "./becca_service.js";
|
||||
import dateUtils from "../services/date_utils.js";
|
||||
import { JSDOM } from "jsdom";
|
||||
import BNote from "./entities/bnote.js";
|
||||
import type BNote from "./entities/bnote.js";
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
import appInfo from "../services/app_info.js";
|
||||
import eu from "./etapi_utils.js";
|
||||
|
||||
|
@ -3,7 +3,7 @@ import eu from "./etapi_utils.js";
|
||||
import mappers from "./mappers.js";
|
||||
import v from "./validators.js";
|
||||
import utils from "../services/utils.js";
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
import type { AttachmentRow } from "../becca/entities/rows.js";
|
||||
import type { ValidatorMap } from "./etapi-interface.js";
|
||||
|
||||
|
@ -3,7 +3,7 @@ import eu from "./etapi_utils.js";
|
||||
import mappers from "./mappers.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import v from "./validators.js";
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
import type { AttributeRow } from "../becca/entities/rows.js";
|
||||
import type { ValidatorMap } from "./etapi-interface.js";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
|
||||
import eu from "./etapi_utils.js";
|
||||
import backupService from "../services/backup.js";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
|
||||
import becca from "../becca/becca.js";
|
||||
import eu from "./etapi_utils.js";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BAttachment from "../becca/entities/battachment.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import BBranch from "../becca/entities/bbranch.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type BAttachment from "../becca/entities/battachment.js";
|
||||
import type BAttribute from "../becca/entities/battribute.js";
|
||||
import type BBranch from "../becca/entities/bbranch.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
|
||||
function mapNoteToPojo(note: BNote) {
|
||||
return {
|
||||
|
@ -9,7 +9,7 @@ import searchService from "../services/search/services/search.js";
|
||||
import SearchContext from "../services/search/search_context.js";
|
||||
import zipExportService from "../services/export/zip.js";
|
||||
import zipImportService from "../services/import/zip.js";
|
||||
import { type Request, Router } from "express";
|
||||
import type { Request, Router } from "express";
|
||||
import type { ParsedQs } from "qs";
|
||||
import type { NoteParams } from "../services/note-interface.js";
|
||||
import type { SearchParams } from "../services/search/services/types.js";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
@ -2,7 +2,7 @@ import specialNotesService from "../services/special_notes.js";
|
||||
import dateNotesService from "../services/date_notes.js";
|
||||
import eu from "./etapi_utils.js";
|
||||
import mappers from "./mappers.js";
|
||||
import { Router } from "express";
|
||||
import type { Router } from "express";
|
||||
|
||||
const getDateInvalidError = (date: string) => new eu.EtapiError(400, "DATE_INVALID", `Date "${date}" is not valid.`);
|
||||
const getMonthInvalidError = (month: string) => new eu.EtapiError(400, "MONTH_INVALID", `Month "${month}" is not valid.`);
|
||||
|
@ -14,15 +14,15 @@ import MainTreeExecutors from "./main_tree_executors.js";
|
||||
import toast from "../services/toast.js";
|
||||
import ShortcutComponent from "./shortcut_component.js";
|
||||
import { t, initLocale } from "../services/i18n.js";
|
||||
import NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import type NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
|
||||
import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js";
|
||||
import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js";
|
||||
import type { Node } from "../services/tree.js";
|
||||
import LoadResults from "../services/load_results.js";
|
||||
import type LoadResults from "../services/load_results.js";
|
||||
import type { Attribute } from "../services/attribute_parser.js";
|
||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import NoteContext, { type GetTextEditorCallback } from "./note_context.js";
|
||||
import type NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js";
|
||||
|
||||
interface Layout {
|
||||
getRootWidget: (appContext: AppContext) => RootWidget;
|
||||
@ -92,7 +92,7 @@ export type CommandMappings = {
|
||||
filePath: string;
|
||||
};
|
||||
focusAndSelectTitle: CommandData & {
|
||||
isNewNote: boolean;
|
||||
isNewNote?: boolean;
|
||||
};
|
||||
showPromptDialog: PromptDialogOptions;
|
||||
showInfoDialog: ConfirmWithMessageOptions;
|
||||
@ -262,6 +262,9 @@ type EventMappings = {
|
||||
};
|
||||
noteContextRemovedEvent: {
|
||||
ntxIds: string[];
|
||||
};
|
||||
exportSvg: {
|
||||
ntxId: string;
|
||||
}
|
||||
};
|
||||
|
||||
@ -274,15 +277,16 @@ export type CommandListener<T extends CommandNames> = {
|
||||
};
|
||||
|
||||
export type CommandListenerData<T extends CommandNames> = CommandMappings[T];
|
||||
export type EventData<T extends EventNames> = EventMappings[T];
|
||||
|
||||
type CommandAndEventMappings = CommandMappings & EventMappings;
|
||||
type EventOnlyNames = keyof EventMappings;
|
||||
export type EventNames = CommandNames | EventOnlyNames;
|
||||
export type EventData<T extends EventNames> = CommandAndEventMappings[T];
|
||||
|
||||
/**
|
||||
* This type is a discriminated union which contains all the possible commands that can be triggered via {@link AppContext.triggerCommand}.
|
||||
*/
|
||||
export type CommandNames = keyof CommandMappings;
|
||||
type EventNames = keyof EventMappings;
|
||||
|
||||
type FilterByValueType<T, ValueType> = { [K in keyof T]: T[K] extends ValueType ? K : never }[keyof T];
|
||||
|
||||
@ -375,12 +379,10 @@ class AppContext extends Component {
|
||||
|
||||
this.child(rootWidget);
|
||||
|
||||
this.triggerEvent("initialRenderComplete");
|
||||
this.triggerEvent("initialRenderComplete", {});
|
||||
}
|
||||
|
||||
// TODO: Remove ignore once all commands are mapped out.
|
||||
//@ts-ignore
|
||||
triggerEvent<K extends EventNames | CommandNames>(name: K, data: CommandAndEventMappings[K] = {}) {
|
||||
triggerEvent<K extends EventNames>(name: K, data: EventData<K>) {
|
||||
return this.handleEvent(name, data);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import utils from "../services/utils.js";
|
||||
import type { CommandMappings, CommandNames } from "./app_context.js";
|
||||
import type { CommandMappings, CommandNames, EventData, EventNames } from "./app_context.js";
|
||||
|
||||
/**
|
||||
* Abstract class for all components in the Trilium's frontend.
|
||||
@ -46,7 +46,7 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
|
||||
return this;
|
||||
}
|
||||
|
||||
handleEvent(name: string, data: unknown): Promise<unknown> | null {
|
||||
handleEvent<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null {
|
||||
try {
|
||||
const callMethodPromise = this.initialized ? this.initialized.then(() => this.callMethod((this as any)[`${name}Event`], data)) : this.callMethod((this as any)[`${name}Event`], data);
|
||||
|
||||
@ -65,11 +65,11 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
|
||||
return this.parent?.triggerEvent(name, data);
|
||||
}
|
||||
|
||||
handleEventInChildren(name: string, data: unknown = {}) {
|
||||
const promises = [];
|
||||
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null {
|
||||
const promises: Promise<unknown>[] = [];
|
||||
|
||||
for (const child of this.children) {
|
||||
const ret = child.handleEvent(name, data);
|
||||
const ret = child.handleEvent(name, data) as Promise<void>;
|
||||
|
||||
if (ret) {
|
||||
promises.push(ret);
|
||||
|
@ -10,7 +10,7 @@ import bundleService from "../services/bundle.js";
|
||||
import froca from "../services/froca.js";
|
||||
import linkService from "../services/link.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
// TODO: Move somewhere else nicer.
|
||||
export type SqlExecuteResults = unknown[];
|
||||
|
@ -8,7 +8,7 @@ import froca from "../services/froca.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import options from "../services/options.js";
|
||||
import type { ViewScope } from "../services/link.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
interface SetNoteOpts {
|
||||
triggerSwitchEvent?: unknown;
|
||||
|
@ -5,8 +5,8 @@ import froca from "../services/froca.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import cssClassManager from "../services/css_class_manager.js";
|
||||
import type { Froca } from "../services/froca-interface.js";
|
||||
import FAttachment from "./fattachment.js";
|
||||
import FAttribute, { type AttributeType } from "./fattribute.js";
|
||||
import type FAttachment from "./fattachment.js";
|
||||
import type { default as FAttribute, AttributeType } from "./fattribute.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
const LABEL = "label";
|
||||
@ -35,7 +35,7 @@ const NOTE_TYPE_ICONS = {
|
||||
* end user. Those types should be used only for checking against, they are
|
||||
* not for direct use.
|
||||
*/
|
||||
type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code";
|
||||
type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap";
|
||||
|
||||
interface NotePathRecord {
|
||||
isArchived: boolean;
|
||||
|
@ -27,7 +27,7 @@ import ClassicEditorToolbar from "../widgets/ribbon_widgets/classic_editor_toolb
|
||||
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
|
||||
import AboutDialog from "../widgets/dialogs/about.js";
|
||||
import HelpDialog from "../widgets/dialogs/help.js";
|
||||
import AppContext from "../components/app_context.js";
|
||||
import type AppContext from "../components/app_context.js";
|
||||
import TabRowWidget from "../widgets/tab_row.js";
|
||||
import JumpToNoteDialog from "../widgets/dialogs/jump_to_note.js";
|
||||
|
||||
|
@ -5,7 +5,7 @@ import dialogService from "../services/dialog.js";
|
||||
import server from "../services/server.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import type { SelectMenuItemEventListener } from "../components/events.js";
|
||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import type NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import type { FilteredCommandNames, ContextMenuCommandData } from "../components/app_context.js";
|
||||
|
||||
type LauncherCommandNames = FilteredCommandNames<ContextMenuCommandData>;
|
||||
@ -58,7 +58,7 @@ export default class LauncherContextMenu implements SelectMenuItemEventListener<
|
||||
|
||||
{ title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-reset destructive-action-icon", enabled: canBeReset }
|
||||
];
|
||||
return items.filter((row) => row !== null);
|
||||
return items.filter((row) => row !== null) as MenuItem<LauncherCommandNames>[];
|
||||
}
|
||||
|
||||
async selectMenuItemHandler({ command }: MenuCommandItem<LauncherCommandNames>) {
|
||||
|
@ -9,8 +9,8 @@ import server from "../services/server.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import FAttachment from "../entities/fattachment.js";
|
||||
import type NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import type FAttachment from "../entities/fattachment.js";
|
||||
import type { SelectMenuItemEventListener } from "../components/events.js";
|
||||
|
||||
// TODO: Deduplicate once client/server is well split.
|
||||
@ -196,7 +196,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
|
||||
enabled: notSearch && noSelectedNotes
|
||||
}
|
||||
];
|
||||
return items.filter((row) => row !== null);
|
||||
return items.filter((row) => row !== null) as MenuItem<TreeCommandNames>[];
|
||||
}
|
||||
|
||||
async selectMenuItemHandler({ command, type, templateNoteId }: MenuCommandItem<TreeCommandNames>) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import ws from "./ws.js";
|
||||
import froca from "./froca.js";
|
||||
import FAttribute from "../entities/fattribute.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FAttribute from "../entities/fattribute.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
async function renderAttribute(attribute: FAttribute, renderIsInheritable: boolean) {
|
||||
const isInheritable = renderIsInheritable && attribute.isInheritable ? `(inheritable)` : "";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "./server.js";
|
||||
import froca from "./froca.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { AttributeRow } from "./load_results.js";
|
||||
|
||||
async function addLabel(noteId: string, name: string, value: string = "") {
|
||||
|
@ -14,7 +14,7 @@ import AddLabelBulkAction from "../widgets/bulk_actions/label/add_label.js";
|
||||
import AddRelationBulkAction from "../widgets/bulk_actions/relation/add_relation.js";
|
||||
import RenameNoteBulkAction from "../widgets/bulk_actions/note/rename_note.js";
|
||||
import { t } from "./i18n.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
const ACTION_GROUPS = [
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
import FAttachment from "../entities/fattachment.js";
|
||||
import FAttribute from "../entities/fattribute.js";
|
||||
import FBlob from "../entities/fblob.js";
|
||||
import FBranch from "../entities/fbranch.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FAttachment from "../entities/fattachment.js";
|
||||
import type FAttribute from "../entities/fattribute.js";
|
||||
import type FBlob from "../entities/fblob.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
export interface Froca {
|
||||
notes: Record<string, FNote>;
|
||||
|
@ -6,7 +6,7 @@ import noteAttributeCache from "./note_attribute_cache.js";
|
||||
import FBranch, { type FBranchRow } from "../entities/fbranch.js";
|
||||
import FAttribute, { type FAttributeRow } from "../entities/fattribute.js";
|
||||
import FAttachment, { type FAttachmentRow } from "../entities/fattachment.js";
|
||||
import FNote, { type FNoteRow } from "../entities/fnote.js";
|
||||
import type { default as FNote, FNoteRow } from "../entities/fnote.js";
|
||||
import type { EntityChange } from "../server_types.js";
|
||||
|
||||
async function processEntityChanges(entityChanges: EntityChange[]) {
|
||||
|
@ -15,11 +15,11 @@ import BasicWidget from "../widgets/basic_widget.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
import dialogService from "./dialog.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import { t } from "./i18n.js";
|
||||
import NoteContext from "../components/note_context.js";
|
||||
import NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import Component from "../components/component.js";
|
||||
import type NoteContext from "../components/note_context.js";
|
||||
import type NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import type Component from "../components/component.js";
|
||||
|
||||
/**
|
||||
* A whole number
|
||||
@ -463,7 +463,7 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig
|
||||
await ws.waitForMaxKnownEntityChangeId();
|
||||
|
||||
await appContext.tabManager.getActiveContext().setNote(notePath);
|
||||
await appContext.triggerEvent("focusAndSelectTitle");
|
||||
await appContext.triggerEvent("focusAndSelectTitle", {});
|
||||
};
|
||||
|
||||
this.openTabWithNote = async (notePath, activate) => {
|
||||
@ -472,7 +472,7 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig
|
||||
await appContext.tabManager.openTabWithNoteWithHoisting(notePath, { activate });
|
||||
|
||||
if (activate) {
|
||||
await appContext.triggerEvent("focusAndSelectTitle");
|
||||
await appContext.triggerEvent("focusAndSelectTitle", {});
|
||||
}
|
||||
};
|
||||
|
||||
@ -485,7 +485,7 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig
|
||||
await appContext.triggerCommand("openNewNoteSplit", { ntxId, notePath });
|
||||
|
||||
if (activate) {
|
||||
await appContext.triggerEvent("focusAndSelectTitle");
|
||||
await appContext.triggerEvent("focusAndSelectTitle", {});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,7 @@ import appContext from "../components/app_context.js";
|
||||
import treeService, { type Node } from "./tree.js";
|
||||
import dialogService from "./dialog.js";
|
||||
import froca from "./froca.js";
|
||||
import NoteContext from "../components/note_context.js";
|
||||
import type NoteContext from "../components/note_context.js";
|
||||
import { t } from "./i18n.js";
|
||||
|
||||
function getHoistedNoteId() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import server from "./server.js";
|
||||
import appContext, { type CommandNames } from "../components/app_context.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
import Component from "../components/component.js";
|
||||
import type Component from "../components/component.js";
|
||||
|
||||
const keyboardActionRepo: Record<string, Action> = {};
|
||||
|
||||
|
@ -96,10 +96,6 @@ const I18NEXT: Library = {
|
||||
js: ["node_modules/i18next/i18next.min.js", "node_modules/i18next-http-backend/i18nextHttpBackend.min.js"]
|
||||
};
|
||||
|
||||
const MIND_ELIXIR: Library = {
|
||||
js: ["node_modules/mind-elixir/dist/MindElixir.iife.js", "node_modules/@mind-elixir/node-menu/dist/node-menu.umd.cjs"]
|
||||
};
|
||||
|
||||
const HIGHLIGHT_JS: Library = {
|
||||
js: () => {
|
||||
const mimeTypes = mimeTypesService.getMimeTypes();
|
||||
@ -219,6 +215,5 @@ export default {
|
||||
EXCALIDRAW,
|
||||
MARKJS,
|
||||
I18NEXT,
|
||||
MIND_ELIXIR,
|
||||
HIGHLIGHT_JS
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import FAttribute from "../entities/fattribute.js";
|
||||
import type FAttribute from "../entities/fattribute.js";
|
||||
|
||||
/**
|
||||
* The purpose of this class is to cache the list of attributes for notes.
|
||||
|
@ -6,8 +6,8 @@ import froca from "./froca.js";
|
||||
import treeService from "./tree.js";
|
||||
import toastService from "./toast.js";
|
||||
import { t } from "./i18n.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import FBranch from "../entities/fbranch.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type { ChooseNoteTypeResponse } from "../widgets/dialogs/note_type_chooser.js";
|
||||
|
||||
interface CreateNoteOpts {
|
||||
|
@ -5,7 +5,7 @@ import attributeRenderer from "./attribute_renderer.js";
|
||||
import libraryLoader from "./library_loader.js";
|
||||
import treeService from "./tree.js";
|
||||
import utils from "./utils.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-list">
|
||||
|
@ -5,7 +5,7 @@ import utils from "./utils.js";
|
||||
import attributeRenderer from "./attribute_renderer.js";
|
||||
import contentRenderer from "./content_renderer.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import { t } from "./i18n.js";
|
||||
|
||||
function setupGlobalTooltip() {
|
||||
|
@ -74,9 +74,9 @@ ws.subscribeToMessages(async (message) => {
|
||||
if (message.type === "protectedSessionLogin") {
|
||||
await reloadData();
|
||||
|
||||
await appContext.triggerEvent("frocaReloaded");
|
||||
await appContext.triggerEvent("frocaReloaded", {});
|
||||
|
||||
appContext.triggerEvent("protectedSessionStarted");
|
||||
appContext.triggerEvent("protectedSessionStarted", {});
|
||||
|
||||
appContext.triggerCommand("closeProtectedSessionPasswordDialog");
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import server from "./server.js";
|
||||
|
||||
function enableProtectedSession() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "./server.js";
|
||||
import bundleService, { type Bundle } from "./bundle.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
async function render(note: FNote, $el: JQuery<HTMLElement>) {
|
||||
const relations = note.getRelations("renderNote");
|
||||
|
4
src/public/app/types-lib.d.ts
vendored
4
src/public/app/types-lib.d.ts
vendored
@ -20,3 +20,7 @@ declare module "draggabilly" {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@mind-elixir/node-menu' {
|
||||
export default mindmap;
|
||||
}
|
||||
|
@ -3,17 +3,17 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
||||
import server from "../../services/server.js";
|
||||
import contextMenuService from "../../menus/context_menu.js";
|
||||
import attributeParser from "../../services/attribute_parser.js";
|
||||
import attributeParser, { type Attribute } from "../../services/attribute_parser.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import attributeRenderer from "../../services/attribute_renderer.js";
|
||||
import noteCreateService from "../../services/note_create.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import AttributeDetailWidget from "./attribute_detail.js";
|
||||
import type AttributeDetailWidget from "./attribute_detail.js";
|
||||
import type { CommandData, EventData, EventListener, FilteredCommandNames } from "../../components/app_context.js";
|
||||
import FAttribute, { type AttributeType } from "../../entities/fattribute.js";
|
||||
import FNote from "../../entities/fnote.js";
|
||||
import type { default as FAttribute, AttributeType } from "../../entities/fattribute.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
|
||||
const HELP_TEXT = `
|
||||
<p>${t("attribute_editor.help_text_body1")}</p>
|
||||
@ -417,7 +417,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem
|
||||
return null;
|
||||
}
|
||||
|
||||
let matchedAttr = null;
|
||||
let matchedAttr: Attribute | null = null;
|
||||
|
||||
for (const attr of parsedAttrs) {
|
||||
if (attr.startIndex && clickIndex > attr.startIndex && attr.endIndex && clickIndex <= attr.endIndex) {
|
||||
|
@ -2,7 +2,7 @@ import { t } from "../../services/i18n.js";
|
||||
import server from "../../services/server.js";
|
||||
import ws from "../../services/ws.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import FAttribute from "../../entities/fattribute.js";
|
||||
import type FAttribute from "../../entities/fattribute.js";
|
||||
|
||||
interface ActionDefinition {
|
||||
script: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Component, { TypedComponent } from "../../components/component.js";
|
||||
import type { default as Component, TypedComponent } from "../../components/component.js";
|
||||
import BasicWidget, { TypedBasicWidget } from "../basic_widget.js";
|
||||
|
||||
export default class Container<T extends TypedComponent<any>> extends TypedBasicWidget<T> {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { TypedComponent } from "../../components/component.js";
|
||||
import type { TypedComponent } from "../../components/component.js";
|
||||
import Container from "./container.js";
|
||||
|
||||
export type FlexDirection = "row" | "column";
|
||||
|
@ -11,7 +11,7 @@ import utils from "../../services/utils.js";
|
||||
import TodayLauncher from "../buttons/launcher/today_launcher.js";
|
||||
import HistoryNavigationButton from "../buttons/history_navigation.js";
|
||||
import QuickSearchLauncherWidget from "../quick_search_launcher.js";
|
||||
import FNote from "../../entities/fnote.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { CommandNames } from "../../components/app_context.js";
|
||||
|
||||
interface InnerWidget extends BasicWidget {
|
||||
|
@ -51,7 +51,7 @@ export default class LauncherContainer extends FlexContainer<LauncherWidget> {
|
||||
this.$widget.empty();
|
||||
this.renderChildren();
|
||||
|
||||
await this.handleEventInChildren("initialRenderComplete");
|
||||
await this.handleEventInChildren("initialRenderComplete", {});
|
||||
|
||||
const activeContext = appContext.tabManager.getActiveContext();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import FlexContainer from "./flex_container.js";
|
||||
import splitService from "../../services/resizer.js";
|
||||
import RightPanelWidget from "../right_panel_widget.js";
|
||||
import type RightPanelWidget from "../right_panel_widget.js";
|
||||
import type { EventData, EventNames } from "../../components/app_context.js";
|
||||
|
||||
export default class RightPaneContainer extends FlexContainer<RightPanelWidget> {
|
||||
private rightPaneHidden: boolean;
|
||||
@ -19,7 +20,7 @@ export default class RightPaneContainer extends FlexContainer<RightPanelWidget>
|
||||
return super.isEnabled() && !this.rightPaneHidden && this.children.length > 0 && !!this.children.find((ch) => ch.isEnabled() && ch.canBeShown());
|
||||
}
|
||||
|
||||
handleEventInChildren(name: string, data: unknown) {
|
||||
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>): Promise<unknown[] | unknown> | null {
|
||||
const promise = super.handleEventInChildren(name, data);
|
||||
|
||||
if (["activeContextChanged", "noteSwitchedAndActivated", "noteSwitched"].includes(name)) {
|
||||
|
@ -12,7 +12,7 @@ import options from "../services/options.js";
|
||||
import OnClickButtonWidget from "./buttons/onclick_button.js";
|
||||
import appContext, { type EventData } from "../components/app_context.js";
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
const TPL = `<div class="highlights-list-widget">
|
||||
<style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
import type { Screen } from "../../components/mobile_screen_switcher.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import type BasicWidget from "../basic_widget.js";
|
||||
import FlexContainer, { type FlexDirection } from "../containers/flex_container.js";
|
||||
|
||||
const DRAG_STATE_NONE = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BasicWidget from "./basic_widget.js";
|
||||
import appContext, { type EventData } from "../components/app_context.js";
|
||||
import FNote from "../entities/fnote.js";
|
||||
import NoteContext from "../components/note_context.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type NoteContext from "../components/note_context.js";
|
||||
|
||||
/**
|
||||
* This widget allows for changing and updating depending on the active note.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BasicWidget from "./basic_widget.js";
|
||||
import AbstractButtonWidget from "./buttons/abstract_button.js";
|
||||
import type BasicWidget from "./basic_widget.js";
|
||||
import type AbstractButtonWidget from "./buttons/abstract_button.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
|
||||
const WIDGET_TPL = `
|
||||
|
@ -165,13 +165,13 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
|
||||
this.watchdog.on("stateChange", () => {
|
||||
const currentState = this.watchdog.state;
|
||||
logInfo(`CKEditor state changed to ${currentState}`);
|
||||
|
||||
if (!["crashed", "crashedPermanently"].includes(currentState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`CKEditor changed to ${currentState}`);
|
||||
|
||||
logInfo(`CKEditor crash logs: ${JSON.stringify(this.watchdog.crashes)}`);
|
||||
this.watchdog.crashes.forEach((crashInfo) => console.log(crashInfo));
|
||||
|
||||
if (currentState === "crashedPermanently") {
|
||||
@ -182,6 +182,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
});
|
||||
|
||||
this.watchdog.setCreator(async (elementOrData, editorConfig) => {
|
||||
logInfo("Creating new CKEditor");
|
||||
const extraOpts = {};
|
||||
if (isClassicEditor) {
|
||||
extraOpts.toolbar = {
|
||||
|
@ -1,6 +1,11 @@
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import MindElixir, { type MindElixirCtor } from "mind-elixir";
|
||||
import nodeMenu from "@mind-elixir/node-menu";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
|
||||
const NEW_TOPIC_NAME = "";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail-mind-map note-detail-printable">
|
||||
@ -137,6 +142,11 @@ const TPL = `
|
||||
`;
|
||||
|
||||
export default class MindMapWidget extends TypeWidget {
|
||||
|
||||
private $content!: JQuery<HTMLElement>;
|
||||
private triggeredByUserOperation?: boolean;
|
||||
private mind?: ReturnType<MindElixirCtor["new"]>;
|
||||
|
||||
static getType() {
|
||||
return "mindMap";
|
||||
}
|
||||
@ -163,16 +173,12 @@ export default class MindMapWidget extends TypeWidget {
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note) {
|
||||
async doRefresh(note: FNote) {
|
||||
if (this.triggeredByUserOperation) {
|
||||
this.triggeredByUserOperation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!window.MindElixir) {
|
||||
await libraryLoader.requireLibrary(libraryLoader.MIND_ELIXIR);
|
||||
}
|
||||
|
||||
this.#initLibrary();
|
||||
await this.#loadData(note);
|
||||
}
|
||||
@ -181,12 +187,14 @@ export default class MindMapWidget extends TypeWidget {
|
||||
this.triggeredByUserOperation = false;
|
||||
}
|
||||
|
||||
async #loadData(note) {
|
||||
async #loadData(note: FNote) {
|
||||
const blob = await note.getBlob();
|
||||
const content = blob.getJsonContent() || MindElixir.new();
|
||||
const content = blob?.getJsonContent() || MindElixir.new(NEW_TOPIC_NAME);
|
||||
|
||||
this.mind.refresh(content);
|
||||
this.mind.toCenter();
|
||||
if (this.mind) {
|
||||
this.mind.refresh(content);
|
||||
this.mind.toCenter();
|
||||
}
|
||||
}
|
||||
|
||||
#initLibrary() {
|
||||
@ -194,11 +202,12 @@ export default class MindMapWidget extends TypeWidget {
|
||||
el: this.$content[0],
|
||||
direction: MindElixir.LEFT
|
||||
});
|
||||
mind.install(window["@mind-elixir/node-menu"]);
|
||||
mind.install(nodeMenu);
|
||||
|
||||
this.mind = mind;
|
||||
mind.init(MindElixir.new());
|
||||
mind.bus.addListener("operation", (operation) => {
|
||||
mind.init(MindElixir.new(NEW_TOPIC_NAME));
|
||||
// TODO: See why the typeof mindmap is not correct.
|
||||
mind.bus.addListener("operation", (operation: { name: string }) => {
|
||||
this.triggeredByUserOperation = true;
|
||||
if (operation.name !== "beginEdit") {
|
||||
this.spacedUpdate.scheduleUpdate();
|
||||
@ -237,14 +246,14 @@ export default class MindMapWidget extends TypeWidget {
|
||||
return await this.mind.exportSvg().text();
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({ loadResults }) {
|
||||
if (loadResults.isNoteReloaded(this.noteId)) {
|
||||
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded"> ) {
|
||||
if (this.noteId && loadResults.isNoteReloaded(this.noteId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async exportSvgEvent({ ntxId }) {
|
||||
if (!this.isNoteContext(ntxId) || this.note.type !== "mindMap") {
|
||||
async exportSvgEvent({ ntxId }: EventData<"exportSvg">) {
|
||||
if (!this.isNoteContext(ntxId) || this.note?.type !== "mindMap") {
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { FilterOptionsByType, OptionDefinitions, OptionMap, OptionNames } from "../../../../../services/options_interface.js";
|
||||
import type { EventData, EventListener } from "../../../components/app_context.js";
|
||||
import FNote from "../../../entities/fnote.js";
|
||||
import type FNote from "../../../entities/fnote.js";
|
||||
import { t } from "../../../services/i18n.js";
|
||||
import server from "../../../services/server.js";
|
||||
import toastService from "../../../services/toast.js";
|
||||
|
@ -1,7 +1,13 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import appContext, { type EventData, type EventNames } from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type NoteDetailWidget from "../note_detail.js";
|
||||
import type SpacedUpdate from "../../services/spaced_update.js";
|
||||
|
||||
export default abstract class TypeWidget extends NoteContextAwareWidget {
|
||||
|
||||
protected spacedUpdate!: SpacedUpdate;
|
||||
|
||||
export default class TypeWidget extends NoteContextAwareWidget {
|
||||
// for overriding
|
||||
static getType() {}
|
||||
|
||||
@ -11,12 +17,11 @@ export default class TypeWidget extends NoteContextAwareWidget {
|
||||
return super.doRender();
|
||||
}
|
||||
|
||||
/** @param {FNote} note */
|
||||
async doRefresh(note) {}
|
||||
abstract doRefresh(note: FNote | null | undefined): Promise<void>;
|
||||
|
||||
async refresh() {
|
||||
const thisWidgetType = this.constructor.getType();
|
||||
const noteWidgetType = await this.parent.getWidgetType();
|
||||
const thisWidgetType = (this.constructor as any).getType();
|
||||
const noteWidgetType = await (this.parent as NoteDetailWidget).getWidgetType();
|
||||
|
||||
if (thisWidgetType !== noteWidgetType) {
|
||||
this.toggleInt(false);
|
||||
@ -27,7 +32,7 @@ export default class TypeWidget extends NoteContextAwareWidget {
|
||||
|
||||
await this.doRefresh(this.note);
|
||||
|
||||
this.triggerEvent("noteDetailRefreshed", { ntxId: this.noteContext.ntxId });
|
||||
this.triggerEvent("noteDetailRefreshed", { ntxId: this.noteContext?.ntxId });
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +45,7 @@ export default class TypeWidget extends NoteContextAwareWidget {
|
||||
|
||||
focus() {}
|
||||
|
||||
async readOnlyTemporarilyDisabledEvent({ noteContext }) {
|
||||
async readOnlyTemporarilyDisabledEvent({ noteContext }: EventData<"readOnlyTemporarilyDisabled">) {
|
||||
if (this.isNoteContext(noteContext.ntxId)) {
|
||||
await this.refresh();
|
||||
|
||||
@ -49,10 +54,10 @@ export default class TypeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
// events should be propagated manually to the children widgets
|
||||
handleEventInChildren(name, data) {
|
||||
handleEventInChildren<T extends EventNames>(name: T, data: EventData<T>) {
|
||||
if (["activeContextChanged", "setNoteContext"].includes(name)) {
|
||||
// won't trigger .refresh();
|
||||
return super.handleEventInChildren("setNoteContext", data);
|
||||
return super.handleEventInChildren("setNoteContext", data as EventData<"activeContextChanged">);
|
||||
} else if (name === "entitiesReloaded") {
|
||||
return super.handleEventInChildren(name, data);
|
||||
} else {
|
@ -16,7 +16,7 @@ import path from "path";
|
||||
import htmlSanitizer from "../../services/html_sanitizer.js";
|
||||
import attributeFormatter from "../../services/attribute_formatter.js";
|
||||
import jsdom from "jsdom";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
const { JSDOM } = jsdom;
|
||||
|
||||
|
@ -12,8 +12,8 @@ import ws from "../../services/ws.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import type { Request, Response } from "express";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import BAttachment from "../../becca/entities/battachment.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type BAttachment from "../../becca/entities/battachment.js";
|
||||
|
||||
function updateFile(req: Request) {
|
||||
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||
|
@ -4,8 +4,8 @@ import imageService from "../../services/image.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import fs from "fs";
|
||||
import type { Request, Response } from "express";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import BRevision from "../../becca/entities/brevision.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type BRevision from "../../becca/entities/brevision.js";
|
||||
import { RESOURCE_DIR } from "../../services/resource_dir.js";
|
||||
|
||||
function returnImageFromNote(req: Request, res: Response) {
|
||||
|
@ -12,7 +12,7 @@ import log from "../../services/log.js";
|
||||
import TaskContext from "../../services/task_context.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import type { Request } from "express";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
|
||||
async function importNotesToBranch(req: Request) {
|
||||
const { parentNoteId } = req.params;
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
import becca from "../../becca/becca.js";
|
||||
import { JSDOM } from "jsdom";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import BAttribute from "../../becca/entities/battribute.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type BAttribute from "../../becca/entities/battribute.js";
|
||||
import type { Request } from "express";
|
||||
|
||||
function buildDescendantCountMap(noteIdsToCount: string[]) {
|
||||
|
@ -11,7 +11,7 @@ import becca from "../../becca/becca.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import blobService from "../../services/blob.js";
|
||||
import type { Request } from "express";
|
||||
import BBranch from "../../becca/entities/bbranch.js";
|
||||
import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { AttributeRow } from "../../becca/entities/rows.js";
|
||||
|
||||
function getNote(req: Request) {
|
||||
|
@ -10,9 +10,9 @@ import becca from "../../becca/becca.js";
|
||||
import blobService from "../../services/blob.js";
|
||||
import eraseService from "../../services/erase.js";
|
||||
import type { Request, Response } from "express";
|
||||
import BRevision from "../../becca/entities/brevision.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import { type NotePojo } from "../../becca/becca-interface.js";
|
||||
import type BRevision from "../../becca/entities/brevision.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type { NotePojo } from "../../becca/becca-interface.js";
|
||||
|
||||
interface NotePath {
|
||||
noteId: string;
|
||||
|
@ -9,7 +9,7 @@ import bulkActionService from "../../services/bulk_actions.js";
|
||||
import cls from "../../services/cls.js";
|
||||
import attributeFormatter from "../../services/attribute_formatter.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import SearchResult from "../../services/search/search_result.js";
|
||||
import type SearchResult from "../../services/search/search_result.js";
|
||||
|
||||
function searchFromNote(req: Request): SearchNoteResult {
|
||||
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||
|
@ -4,7 +4,7 @@ import becca from "../../becca/becca.js";
|
||||
import log from "../../services/log.js";
|
||||
import NotFoundError from "../../errors/not_found_error.js";
|
||||
import type { Request } from "express";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
|
||||
function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) {
|
||||
const noteIds = new Set(_noteIds);
|
||||
|
@ -3,7 +3,7 @@ import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import express from "express";
|
||||
import env from "../services/env.js";
|
||||
import serveStatic from "serve-static";
|
||||
import type serveStatic from "serve-static";
|
||||
|
||||
const persistentCacheStatic = (root: string, options?: serveStatic.ServeStaticOptions<express.Response<any, Record<string, any>>>) => {
|
||||
if (!env.isDev()) {
|
||||
|
@ -12,7 +12,7 @@ import packageJson from "../../package.json" with { type: "json" };
|
||||
import assetPath from "../services/asset_path.js";
|
||||
import appPath from "../services/app_path.js";
|
||||
import type { Request, Response } from "express";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
|
||||
function index(req: Request, res: Response) {
|
||||
const options = optionService.getOptionMap();
|
||||
|
@ -6,7 +6,7 @@ import becca from "../becca/becca.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import attributeFormatter from "./attribute_formatter.js";
|
||||
import BUILTIN_ATTRIBUTES from "./builtin_attributes.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import type { AttributeRow } from "../becca/entities/rows.js";
|
||||
|
||||
const ATTRIBUTE_TYPES = new Set(["label", "relation"]);
|
||||
|
@ -23,16 +23,16 @@ import exportService from "./export/zip.js";
|
||||
import syncMutex from "./sync_mutex.js";
|
||||
import backupService from "./backup.js";
|
||||
import optionsService from "./options.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import BBranch from "../becca/entities/bbranch.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import BAttachment from "../becca/entities/battachment.js";
|
||||
import BRevision from "../becca/entities/brevision.js";
|
||||
import BEtapiToken from "../becca/entities/betapi_token.js";
|
||||
import BOption from "../becca/entities/boption.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import type AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import type BBranch from "../becca/entities/bbranch.js";
|
||||
import type BAttribute from "../becca/entities/battribute.js";
|
||||
import type BAttachment from "../becca/entities/battachment.js";
|
||||
import type BRevision from "../becca/entities/brevision.js";
|
||||
import type BEtapiToken from "../becca/entities/betapi_token.js";
|
||||
import type BOption from "../becca/entities/boption.js";
|
||||
import type { AttributeRow } from "../becca/entities/rows.js";
|
||||
import Becca from "../becca/becca-interface.js";
|
||||
import type Becca from "../becca/becca-interface.js";
|
||||
import type { NoteParams } from "./note-interface.js";
|
||||
import type { ApiParams } from "./backend_script_api_interface.js";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Request, Response } from "express";
|
||||
import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
|
||||
export interface ApiParams {
|
||||
startNote?: BNote | null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import treeService from "./tree.js";
|
||||
import sql from "./sql.js";
|
||||
import BBranch from "../becca/entities/bbranch.js";
|
||||
import type BBranch from "../becca/entities/bbranch.js";
|
||||
|
||||
function moveBranchToNote(branchToMove: BBranch, targetParentNoteId: string) {
|
||||
if (branchToMove.parentNoteId === targetParentNoteId) {
|
||||
|
@ -4,7 +4,7 @@ import cloningService from "./cloning.js";
|
||||
import branchService from "./branches.js";
|
||||
import { randomString } from "./utils.js";
|
||||
import eraseService from "./erase.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
|
||||
interface Action {
|
||||
labelName: string;
|
||||
|
@ -2,75 +2,83 @@
|
||||
|
||||
/*
|
||||
* This file resolves trilium data path in this order of priority:
|
||||
* - if TRILIUM_DATA_DIR environment variable exists, then its value is used as the path
|
||||
* - if "trilium-data" dir exists directly in the home dir, then it is used
|
||||
* - based on OS convention, if the "app data directory" exists, we'll use or create "trilium-data" directory there
|
||||
* - as a fallback if the previous step fails, we'll use home dir
|
||||
* - case A) if TRILIUM_DATA_DIR environment variable exists, then its value is used as the path
|
||||
* - case B) if "trilium-data" dir exists directly in the home dir, then it is used
|
||||
* - case C) based on OS convention, if the "app data directory" exists, we'll use or create "trilium-data" directory there
|
||||
* - case D) as a fallback if the previous step fails, we'll use home dir
|
||||
*/
|
||||
|
||||
import os from "os";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
function getAppDataDir() {
|
||||
let appDataDir = os.homedir(); // fallback if OS is not recognized
|
||||
|
||||
if (os.platform() === "win32" && process.env.APPDATA) {
|
||||
appDataDir = process.env.APPDATA;
|
||||
} else if (os.platform() === "linux") {
|
||||
appDataDir = `${os.homedir()}/.local/share`;
|
||||
} else if (os.platform() === "darwin") {
|
||||
appDataDir = `${os.homedir()}/Library/Application Support`;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(appDataDir)) {
|
||||
// expected app data path doesn't exist, let's use fallback
|
||||
appDataDir = os.homedir();
|
||||
}
|
||||
|
||||
return appDataDir;
|
||||
}
|
||||
import { join as pathJoin } from "path";
|
||||
|
||||
const DIR_NAME = "trilium-data";
|
||||
const FOLDER_PERMISSIONS = 0o700;
|
||||
|
||||
function getTriliumDataDir() {
|
||||
export function getTriliumDataDir(dataDirName: string) {
|
||||
// case A
|
||||
if (process.env.TRILIUM_DATA_DIR) {
|
||||
if (!fs.existsSync(process.env.TRILIUM_DATA_DIR)) {
|
||||
fs.mkdirSync(process.env.TRILIUM_DATA_DIR, 0o700);
|
||||
}
|
||||
|
||||
createDirIfNotExisting(process.env.TRILIUM_DATA_DIR);
|
||||
return process.env.TRILIUM_DATA_DIR;
|
||||
}
|
||||
|
||||
const homePath = os.homedir() + path.sep + DIR_NAME;
|
||||
|
||||
// case B
|
||||
const homePath = pathJoin(os.homedir(), dataDirName);
|
||||
if (fs.existsSync(homePath)) {
|
||||
return homePath;
|
||||
}
|
||||
|
||||
const appDataPath = getAppDataDir() + path.sep + DIR_NAME;
|
||||
|
||||
if (!fs.existsSync(appDataPath)) {
|
||||
fs.mkdirSync(appDataPath, 0o700);
|
||||
// case C
|
||||
const platformAppDataDir = getPlatformAppDataDir(os.platform(), process.env.APPDATA);
|
||||
if (platformAppDataDir && fs.existsSync(platformAppDataDir)) {
|
||||
const appDataDirPath = pathJoin(platformAppDataDir, dataDirName);
|
||||
createDirIfNotExisting(appDataDirPath);
|
||||
return appDataDirPath;
|
||||
}
|
||||
|
||||
return appDataPath;
|
||||
// case D
|
||||
createDirIfNotExisting(homePath);
|
||||
return homePath;
|
||||
}
|
||||
|
||||
const TRILIUM_DATA_DIR = getTriliumDataDir();
|
||||
const DIR_SEP = TRILIUM_DATA_DIR + path.sep;
|
||||
export function getDataDirs(TRILIUM_DATA_DIR: string) {
|
||||
const dataDirs = {
|
||||
TRILIUM_DATA_DIR: TRILIUM_DATA_DIR,
|
||||
DOCUMENT_PATH: process.env.TRILIUM_DOCUMENT_PATH || pathJoin(TRILIUM_DATA_DIR, "document.db"),
|
||||
BACKUP_DIR: process.env.TRILIUM_BACKUP_DIR || pathJoin(TRILIUM_DATA_DIR, "backup"),
|
||||
LOG_DIR: process.env.TRILIUM_LOG_DIR || pathJoin(TRILIUM_DATA_DIR, "log"),
|
||||
ANONYMIZED_DB_DIR: process.env.TRILIUM_ANONYMIZED_DB_DIR || pathJoin(TRILIUM_DATA_DIR, "anonymized-db"),
|
||||
CONFIG_INI_PATH: process.env.TRILIUM_CONFIG_INI_PATH || pathJoin(TRILIUM_DATA_DIR, "config.ini")
|
||||
} as const;
|
||||
|
||||
const DOCUMENT_PATH = process.env.TRILIUM_DOCUMENT_PATH || `${DIR_SEP}document.db`;
|
||||
const BACKUP_DIR = process.env.TRILIUM_BACKUP_DIR || `${DIR_SEP}backup`;
|
||||
const LOG_DIR = process.env.TRILIUM_LOG_DIR || `${DIR_SEP}log`;
|
||||
const ANONYMIZED_DB_DIR = process.env.TRILIUM_ANONYMIZED_DB_DIR || `${DIR_SEP}anonymized-db`;
|
||||
const CONFIG_INI_PATH = process.env.TRILIUM_CONFIG_INI_PATH || `${DIR_SEP}config.ini`;
|
||||
Object.freeze(dataDirs);
|
||||
return dataDirs;
|
||||
}
|
||||
|
||||
export default {
|
||||
TRILIUM_DATA_DIR,
|
||||
DOCUMENT_PATH,
|
||||
BACKUP_DIR,
|
||||
LOG_DIR,
|
||||
ANONYMIZED_DB_DIR,
|
||||
CONFIG_INI_PATH
|
||||
};
|
||||
export function getPlatformAppDataDir(platform: ReturnType<typeof os.platform>, ENV_APPDATA_DIR: string | undefined = process.env.APPDATA) {
|
||||
switch (true) {
|
||||
case platform === "win32" && !!ENV_APPDATA_DIR:
|
||||
return ENV_APPDATA_DIR;
|
||||
|
||||
case platform === "linux":
|
||||
return `${os.homedir()}/.local/share`;
|
||||
|
||||
case platform === "darwin":
|
||||
return `${os.homedir()}/Library/Application Support`;
|
||||
|
||||
default:
|
||||
// if OS is not recognized
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function createDirIfNotExisting(path: fs.PathLike, permissionMode: fs.Mode = FOLDER_PERMISSIONS) {
|
||||
if (!fs.existsSync(path)) {
|
||||
fs.mkdirSync(path, permissionMode);
|
||||
}
|
||||
}
|
||||
|
||||
const TRILIUM_DATA_DIR = getTriliumDataDir(DIR_NAME);
|
||||
const dataDirs = getDataDirs(TRILIUM_DATA_DIR);
|
||||
|
||||
export default dataDirs;
|
||||
|
@ -8,7 +8,7 @@ import protectedSessionService from "./protected_session.js";
|
||||
import searchService from "../services/search/services/search.js";
|
||||
import SearchContext from "../services/search/search_context.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import { t } from "i18next";
|
||||
|
||||
const CALENDAR_ROOT_LABEL = "calendarRoot";
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
import { getContentDisposition, stripTags } from "../utils.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import BBranch from "../../becca/entities/bbranch.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { Response } from "express";
|
||||
|
||||
function exportToOpml(taskContext: TaskContext, branch: BBranch, version: string, res: Response) {
|
||||
|
@ -5,8 +5,8 @@ import html from "html";
|
||||
import { getContentDisposition, escapeHtml } from "../utils.js";
|
||||
import mdService from "./md.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import BBranch from "../../becca/entities/bbranch.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { Response } from "express";
|
||||
|
||||
function exportSingleNote(taskContext: TaskContext, branch: BBranch, format: "html" | "markdown", res: Response) {
|
||||
|
@ -18,7 +18,7 @@ import ValidationError from "../../errors/validation_error.js";
|
||||
import type NoteMeta from "../meta/note_meta.js";
|
||||
import type AttachmentMeta from "../meta/attachment_meta.js";
|
||||
import type AttributeMeta from "../meta/attribute_meta.js";
|
||||
import BBranch from "../../becca/entities/bbranch.js";
|
||||
import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { Response } from "express";
|
||||
import { RESOURCE_DIR } from "../resource_dir.js";
|
||||
|
||||
|
@ -6,8 +6,8 @@ import becca from "../becca/becca.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import hiddenSubtreeService from "./hidden_subtree.js";
|
||||
import oneTimeTimer from "./one_time_timer.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import type AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
|
||||
import type { DefinitionObject } from "./promoted_attribute_definition_interface.js";
|
||||
|
||||
type Handler = (definition: DefinitionObject, note: BNote, targetNote: BNote) => void;
|
||||
|
@ -9,8 +9,8 @@ import imageService from "../image.js";
|
||||
import protectedSessionService from "../protected_session.js";
|
||||
import htmlSanitizer from "../html_sanitizer.js";
|
||||
import sanitizeAttributeName from "../sanitize_attribute_name.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type { File } from "./common.js";
|
||||
import type { AttributeType } from "../../becca/entities/rows.js";
|
||||
|
||||
|
@ -4,8 +4,8 @@ import noteService from "../../services/notes.js";
|
||||
import xml2js from "xml2js";
|
||||
import protectedSessionService from "../protected_session.js";
|
||||
import htmlSanitizer from "../html_sanitizer.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
const parseString = xml2js.parseString;
|
||||
|
||||
interface OpmlXml {
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
|
||||
import noteService from "../../services/notes.js";
|
||||
import imageService from "../../services/image.js";
|
||||
|
@ -15,11 +15,11 @@ import htmlSanitizer from "../html_sanitizer.js";
|
||||
import becca from "../../becca/becca.js";
|
||||
import BAttachment from "../../becca/entities/battachment.js";
|
||||
import markdownService from "./markdown.js";
|
||||
import TaskContext from "../task_context.js";
|
||||
import BNote from "../../becca/entities/bnote.js";
|
||||
import type TaskContext from "../task_context.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type NoteMeta from "../meta/note_meta.js";
|
||||
import type AttributeMeta from "../meta/attribute_meta.js";
|
||||
import { Stream } from "stream";
|
||||
import type { Stream } from "stream";
|
||||
import { ALLOWED_NOTE_TYPES, type NoteType } from "../../becca/entities/rows.js";
|
||||
|
||||
interface MetaFile {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user