Merge branch 'develop' into renovate/mind-elixir-4.x

This commit is contained in:
Elian Doran 2025-01-14 12:38:34 +02:00 committed by GitHub
commit 62fbf3ffd0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
121 changed files with 352 additions and 248 deletions

View File

@ -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
View 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 });
});

View File

@ -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);
});

View File

@ -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");

View 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();
});

View File

@ -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");

View File

@ -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.

View File

@ -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");
});

View File

@ -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",

View File

@ -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,
});

View File

@ -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" });

View File

@ -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";

View File

@ -1,4 +1,4 @@
import child_process from "child_process";
import type child_process from "child_process";
let etapiAuthToken: string | undefined;

View File

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

View File

@ -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) => {

View File

@ -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 {

View File

@ -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 = {

View File

@ -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";

View File

@ -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";

View File

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

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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 {

View File

@ -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";

View File

@ -1,4 +1,4 @@
import { Router } from "express";
import type { Router } from "express";
import fs from "fs";
import path from "path";

View File

@ -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.`);

View File

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

View File

@ -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[];

View File

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

View File

@ -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";

View File

@ -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";

View File

@ -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>) {

View File

@ -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>) {

View File

@ -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)` : "";

View File

@ -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 = "") {

View File

@ -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 = [
{

View File

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

View File

@ -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[]) {

View File

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

View File

@ -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() {

View File

@ -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> = {};

View File

@ -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.

View File

@ -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 {

View File

@ -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">

View File

@ -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() {

View File

@ -1,4 +1,4 @@
import FNote from "../entities/fnote.js";
import type FNote from "../entities/fnote.js";
import server from "./server.js";
function enableProtectedSession() {

View File

@ -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");

View File

@ -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) {

View File

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

View File

@ -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> {

View File

@ -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";

View File

@ -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 {

View File

@ -1,6 +1,6 @@
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";
export default class RightPaneContainer extends FlexContainer<RightPanelWidget> {
private rightPaneHidden: boolean;

View File

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

View File

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

View File

@ -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.

View File

@ -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 = `

View File

@ -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";

View File

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

View File

@ -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);

View File

@ -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) {

View File

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

View File

@ -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[]) {

View File

@ -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) {

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -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()) {

View File

@ -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();

View File

@ -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"]);

View File

@ -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";

View File

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

View File

@ -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) {

View File

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

View File

@ -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";

View File

@ -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) {

View File

@ -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) {

View File

@ -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";

View File

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

View File

@ -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";

View File

@ -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 {

View File

@ -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";

View File

@ -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 {

View File

@ -24,7 +24,7 @@ import fs from "fs";
import ws from "./ws.js";
import html2plaintext from "html2plaintext";
import type { AttachmentRow, AttributeRow, BranchRow, NoteRow } from "../becca/entities/rows.js";
import TaskContext from "./task_context.js";
import type TaskContext from "./task_context.js";
import type { NoteParams } from "./note-interface.js";
import imageService from "./image.js";
import { t } from "i18next";

View File

@ -4,7 +4,7 @@ import log from "./log.js";
import sql from "./sql.js";
import protectedSessionService from "./protected_session.js";
import dateUtils from "./date_utils.js";
import BNote from "../becca/entities/bnote.js";
import type BNote from "../becca/entities/bnote.js";
function protectRevisions(note: BNote) {
if (!protectedSessionService.isProtectedSessionAvailable()) {

View File

@ -6,7 +6,7 @@ import log from "./log.js";
import attributeService from "../services/attributes.js";
import protectedSessionService from "../services/protected_session.js";
import hiddenSubtreeService from "./hidden_subtree.js";
import BNote from "../becca/entities/bnote.js";
import type BNote from "../becca/entities/bnote.js";
function getRunAtHours(note: BNote): number[] {
try {

View File

@ -2,7 +2,7 @@ import ScriptContext from "./script_context.js";
import cls from "./cls.js";
import log from "./log.js";
import becca from "../becca/becca.js";
import BNote from "../becca/entities/bnote.js";
import type BNote from "../becca/entities/bnote.js";
import type { ApiParams } from "./backend_script_api_interface.js";
interface Bundle {

View File

@ -1,6 +1,6 @@
import { toObject } from "./utils.js";
import BackendScriptApi from "./backend_script_api.js";
import BNote from "../becca/entities/bnote.js";
import type BNote from "../becca/entities/bnote.js";
import type { ApiParams } from "./backend_script_api_interface.js";
type Module = {

View File

@ -4,7 +4,7 @@ import Expression from "./expression.js";
import NoteSet from "../note_set.js";
import log from "../../log.js";
import becca from "../../../becca/becca.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
class AncestorExp extends Expression {
private ancestorNoteId: string;

View File

@ -1,7 +1,7 @@
"use strict";
import NoteSet from "../note_set.js";
import SearchContext from "../search_context.js";
import type NoteSet from "../note_set.js";
import type SearchContext from "../search_context.js";
import Expression from "./expression.js";
import TrueExp from "./true.js";

View File

@ -1,7 +1,7 @@
"use strict";
import NoteSet from "../note_set.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
import becca from "../../../becca/becca.js";
import Expression from "./expression.js";

View File

@ -2,7 +2,7 @@
import Expression from "./expression.js";
import NoteSet from "../note_set.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
class ChildOfExp extends Expression {
private subExpression: Expression;

View File

@ -3,7 +3,7 @@
import Expression from "./expression.js";
import NoteSet from "../note_set.js";
import becca from "../../../becca/becca.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
class DescendantOfExp extends Expression {
private subExpression: Expression;

View File

@ -2,7 +2,7 @@
import Expression from "./expression.js";
import NoteSet from "../note_set.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
/**
* Note is hidden when all its note paths start in hidden subtree (i.e., the note is not cloned into visible tree)

View File

@ -3,7 +3,7 @@
import Expression from "./expression.js";
import NoteSet from "../note_set.js";
import becca from "../../../becca/becca.js";
import SearchContext from "../search_context.js";
import type SearchContext from "../search_context.js";
type Comparator = (value: string) => boolean;

View File

@ -1,7 +1,7 @@
"use strict";
import NoteSet from "../note_set.js";
import SearchContext from "../search_context.js";
import type NoteSet from "../note_set.js";
import type SearchContext from "../search_context.js";
import Expression from "./expression.js";
class NotExp extends Expression {

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