From 0d4fb42731ed31cc86e1222a1d5e187d6d85570b Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 18 Feb 2024 11:47:32 +0200 Subject: [PATCH] server-ts: Port services/tree --- src/becca/entities/bbranch.ts | 8 +++-- src/becca/entities/rows.ts | 2 +- src/routes/api/branches.js | 2 +- src/routes/api/notes.js | 2 +- src/services/backend_script_api.js | 2 +- src/services/branches.js | 2 +- src/services/cloning.js | 2 +- src/services/handlers.js | 2 +- src/services/import/zip.js | 2 +- src/services/{tree.js => tree.ts} | 54 +++++++++++++++++------------- 10 files changed, 43 insertions(+), 35 deletions(-) rename src/services/{tree.js => tree.ts} (79%) diff --git a/src/becca/entities/bbranch.ts b/src/becca/entities/bbranch.ts index 6b45a7e7a..677bc75ef 100644 --- a/src/becca/entities/bbranch.ts +++ b/src/becca/entities/bbranch.ts @@ -267,17 +267,19 @@ class BBranch extends AbstractBeccaEntity { }; } - createClone(parentNoteId: string, notePosition: number) { + createClone(parentNoteId: string, notePosition?: number) { const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId); if (existingBranch) { - existingBranch.notePosition = notePosition; + if (notePosition) { + existingBranch.notePosition = notePosition; + } return existingBranch; } else { return new BBranch({ noteId: this.noteId, parentNoteId: parentNoteId, - notePosition: notePosition, + notePosition: notePosition || null, prefix: this.prefix, isExpanded: this.isExpanded }); diff --git a/src/becca/entities/rows.ts b/src/becca/entities/rows.ts index 097e9042e..82bd95a7f 100644 --- a/src/becca/entities/rows.ts +++ b/src/becca/entities/rows.ts @@ -80,7 +80,7 @@ export interface BranchRow { noteId: string; parentNoteId: string; prefix?: string | null; - notePosition: number | null; + notePosition?: number | null; isExpanded?: boolean; isDeleted?: boolean; utcDateModified?: string; diff --git a/src/routes/api/branches.js b/src/routes/api/branches.js index ae06efdda..c313f5aa3 100644 --- a/src/routes/api/branches.js +++ b/src/routes/api/branches.js @@ -3,7 +3,7 @@ const sql = require('../../services/sql'); const utils = require('../../services/utils'); const entityChangesService = require('../../services/entity_changes'); -const treeService = require('../../services/tree.js'); +const treeService = require('../../services/tree'); const eraseService = require('../../services/erase'); const becca = require('../../becca/becca'); const TaskContext = require('../../services/task_context'); diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index 4f3f89176..8787acbf8 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -2,7 +2,7 @@ const noteService = require('../../services/notes'); const eraseService = require('../../services/erase'); -const treeService = require('../../services/tree.js'); +const treeService = require('../../services/tree'); const sql = require('../../services/sql'); const utils = require('../../services/utils'); const log = require('../../services/log'); diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index 470bfe7ba..f7fcac10a 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -4,7 +4,7 @@ const sql = require('./sql'); const utils = require('./utils'); const attributeService = require('./attributes'); const dateNoteService = require('./date_notes.js'); -const treeService = require('./tree.js'); +const treeService = require('./tree'); const config = require('./config'); const axios = require('axios'); const dayjs = require('dayjs'); diff --git a/src/services/branches.js b/src/services/branches.js index ec0632745..7fab98cd1 100644 --- a/src/services/branches.js +++ b/src/services/branches.js @@ -1,4 +1,4 @@ -const treeService = require('./tree.js'); +const treeService = require('./tree'); const sql = require('./sql'); function moveBranchToNote(branchToMove, targetParentNoteId) { diff --git a/src/services/cloning.js b/src/services/cloning.js index a42df4ba8..2fc15756b 100644 --- a/src/services/cloning.js +++ b/src/services/cloning.js @@ -2,7 +2,7 @@ const sql = require('./sql'); const eventChangesService = require('./entity_changes'); -const treeService = require('./tree.js'); +const treeService = require('./tree'); const BBranch = require('../becca/entities/bbranch'); const becca = require('../becca/becca'); const log = require('./log'); diff --git a/src/services/handlers.js b/src/services/handlers.js index a24e28dd6..16cdd7733 100644 --- a/src/services/handlers.js +++ b/src/services/handlers.js @@ -1,6 +1,6 @@ const eventService = require('./events'); const scriptService = require('./script.js'); -const treeService = require('./tree.js'); +const treeService = require('./tree'); const noteService = require('./notes'); const becca = require('../becca/becca'); const BAttribute = require('../becca/entities/battribute'); diff --git a/src/services/import/zip.js b/src/services/import/zip.js index 08c663786..01bc8b50c 100644 --- a/src/services/import/zip.js +++ b/src/services/import/zip.js @@ -9,7 +9,7 @@ const BBranch = require('../../becca/entities/bbranch'); const path = require('path'); const protectedSessionService = require('../protected_session'); const mimeService = require('./mime.js'); -const treeService = require('../tree.js'); +const treeService = require('../tree'); const yauzl = require("yauzl"); const htmlSanitizer = require('../html_sanitizer'); const becca = require('../../becca/becca'); diff --git a/src/services/tree.js b/src/services/tree.ts similarity index 79% rename from src/services/tree.js rename to src/services/tree.ts index 66276ab2f..56291b620 100644 --- a/src/services/tree.js +++ b/src/services/tree.ts @@ -1,12 +1,13 @@ "use strict"; -const sql = require('./sql'); -const log = require('./log'); -const BBranch = require('../becca/entities/bbranch'); -const entityChangesService = require('./entity_changes'); -const becca = require('../becca/becca'); +import sql = require('./sql'); +import log = require('./log'); +import BBranch = require('../becca/entities/bbranch'); +import entityChangesService = require('./entity_changes'); +import becca = require('../becca/becca'); +import BNote = require('../becca/entities/bnote'); -function validateParentChild(parentNoteId, childNoteId, branchId = null) { +function validateParentChild(parentNoteId: string, childNoteId: string, branchId: string | null = null) { if (['root', '_hidden', '_share', '_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(childNoteId)) { return { branch: null, success: false, message: `Cannot change this note's location.` }; } @@ -25,7 +26,7 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) { return { branch: existingBranch, success: false, - message: `Note "${childNote.title}" note already exists in the "${parentNote.title}".` + message: `Note "${childNote?.title}" note already exists in the "${parentNote?.title}".` }; } @@ -37,7 +38,7 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) { }; } - if (parentNoteId !== '_lbBookmarks' && becca.getNote(parentNoteId).type === 'launcher') { + if (parentNoteId !== '_lbBookmarks' && becca.getNote(parentNoteId)?.type === 'launcher') { return { branch: null, success: false, @@ -51,7 +52,7 @@ function validateParentChild(parentNoteId, childNoteId, branchId = null) { /** * Tree cycle can be created when cloning or when moving existing clone. This method should detect both cases. */ -function wouldAddingBranchCreateCycle(parentNoteId, childNoteId) { +function wouldAddingBranchCreateCycle(parentNoteId: string, childNoteId: string) { if (parentNoteId === childNoteId) { return true; } @@ -70,20 +71,22 @@ function wouldAddingBranchCreateCycle(parentNoteId, childNoteId) { return parentAncestorNoteIds.some(parentAncestorNoteId => childSubtreeNoteIds.has(parentAncestorNoteId)); } -function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, foldersFirst = false, sortNatural = false, sortLocale) { +function sortNotes(parentNoteId: string, customSortBy: string = 'title', reverse = false, foldersFirst = false, sortNatural = false, _sortLocale?: string | null) { if (!customSortBy) { customSortBy = 'title'; } - if (!sortLocale) { - // sortLocale can not be empty string or null value, default value must be set to undefined. - sortLocale = undefined; - } + // sortLocale can not be empty string or null value, default value must be set to undefined. + const sortLocale = (_sortLocale || undefined); sql.transactional(() => { - const notes = becca.getNote(parentNoteId).getChildNotes(); + const note = becca.getNote(parentNoteId); + if (!note) { + throw new Error("Unable to find note"); + } - const normalize = obj => (obj && typeof obj === 'string') ? obj.toLowerCase() : obj; + const notes = note.getChildNotes(); + const normalize = (obj: any) => (obj && typeof obj === 'string') ? obj.toLowerCase() : obj; notes.sort((a, b) => { if (foldersFirst) { @@ -96,7 +99,7 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder } } - function fetchValue(note, key) { + function fetchValue(note: BNote, key: string) { let rawValue; if (key === 'title') { @@ -105,14 +108,14 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder rawValue = prefix ? `${prefix} - ${note.title}` : note.title; } else { rawValue = ['dateCreated', 'dateModified'].includes(key) - ? note[key] + ? (note as any)[key] : note.getLabelValue(key); } return normalize(rawValue); } - function compare(a, b) { + function compare(a: string, b: string) { if (!sortNatural) { // alphabetical sort return b === null || b === undefined || a < b ? -1 : 1; @@ -160,6 +163,7 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder for (const note of notes) { const branch = note.getParentBranches().find(b => b.parentNoteId === parentNoteId); + if (!branch) { continue; } if (branch.noteId === '_hidden') { position = 999_999_999; @@ -182,9 +186,8 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder }); } -function sortNotesIfNeeded(parentNoteId) { +function sortNotesIfNeeded(parentNoteId: string) { const parentNote = becca.getNote(parentNoteId); - if (!parentNote) { return; } @@ -206,7 +209,7 @@ function sortNotesIfNeeded(parentNoteId) { /** * @deprecated this will be removed in the future */ -function setNoteToParent(noteId, prefix, parentNoteId) { +function setNoteToParent(noteId: string, prefix: string, parentNoteId: string) { const parentNote = becca.getNote(parentNoteId); if (parentNoteId && !parentNote) { @@ -215,7 +218,7 @@ function setNoteToParent(noteId, prefix, parentNoteId) { } // case where there might be more such branches is ignored. It's expected there should be just one - const branchId = sql.getValue("SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ? AND prefix = ?", [noteId, prefix]); + const branchId = sql.getValue("SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ? AND prefix = ?", [noteId, prefix]); const branch = becca.getBranch(branchId); if (branch) { @@ -233,12 +236,15 @@ function setNoteToParent(noteId, prefix, parentNoteId) { } else if (parentNoteId) { const note = becca.getNote(noteId); + if (!note) { + throw new Error(`Cannot find note '${noteId}.`); + } if (note.isDeleted) { throw new Error(`Cannot create a branch for '${noteId}' which is deleted.`); } - const branchId = sql.getValue('SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ? AND parentNoteId = ?', [noteId, parentNoteId]); + const branchId = sql.getValue('SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ? AND parentNoteId = ?', [noteId, parentNoteId]); const branch = becca.getBranch(branchId); if (branch) {