diff --git a/src/etapi/special_notes.js b/src/etapi/special_notes.js index ac605ec67..68ef75fae 100644 --- a/src/etapi/special_notes.js +++ b/src/etapi/special_notes.js @@ -1,4 +1,4 @@ -const specialNotesService = require('../services/special_notes.js'); +const specialNotesService = require('../services/special_notes'); const dateNotesService = require('../services/date_notes'); const eu = require('./etapi_utils'); const mappers = require('./mappers.js'); @@ -17,7 +17,7 @@ function isValidDate(date) { function register(router) { eu.route(router, 'get', '/etapi/inbox/:date', (req, res, next) => { - const {date} = req.params; + const { date } = req.params; if (!isValidDate(date)) { throw getDateInvalidError(date); @@ -28,7 +28,7 @@ function register(router) { }); eu.route(router, 'get', '/etapi/calendar/days/:date', (req, res, next) => { - const {date} = req.params; + const { date } = req.params; if (!isValidDate(date)) { throw getDateInvalidError(date); @@ -39,7 +39,7 @@ function register(router) { }); eu.route(router, 'get', '/etapi/calendar/weeks/:date', (req, res, next) => { - const {date} = req.params; + const { date } = req.params; if (!isValidDate(date)) { throw getDateInvalidError(date); @@ -50,7 +50,7 @@ function register(router) { }); eu.route(router, 'get', '/etapi/calendar/months/:month', (req, res, next) => { - const {month} = req.params; + const { month } = req.params; if (!/[0-9]{4}-[0-9]{2}/.test(month)) { throw getMonthInvalidError(month); @@ -61,7 +61,7 @@ function register(router) { }); eu.route(router, 'get', '/etapi/calendar/years/:year', (req, res, next) => { - const {year} = req.params; + const { year } = req.params; if (!/[0-9]{4}/.test(year)) { throw getYearInvalidError(year); diff --git a/src/routes/api/sender.js b/src/routes/api/sender.js index 7ceeba74d..b2309d3c7 100644 --- a/src/routes/api/sender.js +++ b/src/routes/api/sender.js @@ -3,8 +3,8 @@ const imageType = require('image-type'); const imageService = require('../../services/image'); const noteService = require('../../services/notes'); -const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name'); -const specialNotesService = require('../../services/special_notes.js'); +const { sanitizeAttributeName } = require('../../services/sanitize_attribute_name'); +const specialNotesService = require('../../services/special_notes'); function uploadImage(req) { const file = req.file; @@ -17,14 +17,14 @@ function uploadImage(req) { const parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']); - const {note, noteId} = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true); + const { note, noteId } = imageService.saveImage(parentNote.noteId, file.buffer, originalName, true); const labelsStr = req.headers['x-labels']; if (labelsStr?.trim()) { const labels = JSON.parse(labelsStr); - for (const {name, value} of labels) { + for (const { name, value } of labels) { note.setLabel(sanitizeAttributeName(name), value); } } @@ -39,7 +39,7 @@ function uploadImage(req) { function saveNote(req) { const parentNote = specialNotesService.getInboxNote(req.headers['x-local-date']); - const {note, branch} = noteService.createNewNote({ + const { note, branch } = noteService.createNewNote({ parentNoteId: parentNote.noteId, title: req.body.title, content: req.body.content, @@ -49,7 +49,7 @@ function saveNote(req) { }); if (req.body.labels) { - for (const {name, value} of req.body.labels) { + for (const { name, value } of req.body.labels) { note.setLabel(sanitizeAttributeName(name), value); } } diff --git a/src/routes/api/special_notes.js b/src/routes/api/special_notes.js index 76f41a01f..5ed6e0656 100644 --- a/src/routes/api/special_notes.js +++ b/src/routes/api/special_notes.js @@ -3,7 +3,7 @@ const dateNoteService = require('../../services/date_notes'); const sql = require('../../services/sql'); const cls = require('../../services/cls'); -const specialNotesService = require('../../services/special_notes.js'); +const specialNotesService = require('../../services/special_notes'); const becca = require('../../becca/becca'); function getInboxNote(req) { diff --git a/src/routes/routes.js b/src/routes/routes.js index 3c920264c..c782f5e9c 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -48,7 +48,7 @@ const senderRoute = require('./api/sender.js'); const filesRoute = require('./api/files.js'); const searchRoute = require('./api/search'); const bulkActionRoute = require('./api/bulk_action.js'); -const specialNotesRoute = require('./api/special_notes.js'); +const specialNotesRoute = require('./api/special_notes'); const noteMapRoute = require('./api/note_map.js'); const clipperRoute = require('./api/clipper.js'); const similarNotesRoute = require('./api/similar_notes.js'); @@ -67,7 +67,7 @@ const etapiAttachmentRoutes = require('../etapi/attachments.js'); const etapiAttributeRoutes = require('../etapi/attributes'); const etapiBranchRoutes = require('../etapi/branches.js'); const etapiNoteRoutes = require('../etapi/notes.js'); -const etapiSpecialNoteRoutes = require('../etapi/special_notes.js'); +const etapiSpecialNoteRoutes = require('../etapi/special_notes'); const etapiSpecRoute = require('../etapi/spec.js'); const etapiBackupRoute = require('../etapi/backup'); @@ -230,7 +230,7 @@ function register(app) { apiRoute(GET, '/api/app-info', appInfoRoute.getAppInfo); // docker health check - route(GET, '/api/health-check', [], () => ({"status": "ok"}), apiResultHandler); + route(GET, '/api/health-check', [], () => ({ "status": "ok" }), apiResultHandler); // group of the services below are meant to be executed from the outside route(GET, '/api/setup/status', [], setupApiRoute.getStatus, apiResultHandler); diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index 7aba409b1..5ee8082df 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -16,7 +16,7 @@ const SearchContext = require('./search/search_context'); const becca = require('../becca/becca'); const ws = require('./ws'); const SpacedUpdate = require('./spaced_update'); -const specialNotesService = require('./special_notes.js'); +const specialNotesService = require('./special_notes'); const branchService = require('./branches'); const exportService = require('./export/zip'); const syncMutex = require('./sync_mutex'); diff --git a/src/services/notes.ts b/src/services/notes.ts index 26c96ceb8..d75e90e59 100644 --- a/src/services/notes.ts +++ b/src/services/notes.ts @@ -155,6 +155,7 @@ function getAndValidateParent(params: GetValidateParams) { interface NoteParams { /** optionally can force specific noteId */ noteId?: string; + branchId?: string; parentNoteId: string; templateNoteId?: string; title: string; diff --git a/src/services/special_notes.js b/src/services/special_notes.ts similarity index 79% rename from src/services/special_notes.js rename to src/services/special_notes.ts index cb4108cc4..8a75873ec 100644 --- a/src/services/special_notes.js +++ b/src/services/special_notes.ts @@ -1,16 +1,20 @@ -const attributeService = require('./attributes'); -const dateNoteService = require('./date_notes'); -const becca = require('../becca/becca'); -const noteService = require('./notes'); -const dateUtils = require('./date_utils'); -const log = require('./log'); -const hoistedNoteService = require('./hoisted_note'); -const searchService = require('./search/services/search'); -const SearchContext = require('./search/search_context'); -const {LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT} = require('./hidden_subtree'); +import attributeService = require('./attributes'); +import dateNoteService = require('./date_notes'); +import becca = require('../becca/becca'); +import noteService = require('./notes'); +import dateUtils = require('./date_utils'); +import log = require('./log'); +import hoistedNoteService = require('./hoisted_note'); +import searchService = require('./search/services/search'); +import SearchContext = require('./search/search_context'); +import hiddenSubtree = require('./hidden_subtree'); +const { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } = hiddenSubtree; -function getInboxNote(date) { +function getInboxNote(date: string) { const workspaceNote = hoistedNoteService.getWorkspaceNote(); + if (!workspaceNote) { + throw new Error("Unable to find workspace note"); + } let inbox; @@ -48,8 +52,9 @@ function createSqlConsole() { return note; } -function saveSqlConsole(sqlConsoleNoteId) { +function saveSqlConsole(sqlConsoleNoteId: string) { const sqlConsoleNote = becca.getNote(sqlConsoleNoteId); + if (!sqlConsoleNote) throw new Error(`Unable to find SQL console note ID: ${sqlConsoleNoteId}`); const today = dateUtils.localNowDate(); const sqlConsoleHome = @@ -59,7 +64,7 @@ function saveSqlConsole(sqlConsoleNoteId) { const result = sqlConsoleNote.cloneTo(sqlConsoleHome.noteId); for (const parentBranch of sqlConsoleNote.getParentBranches()) { - if (parentBranch.parentNote.hasAncestor('_hidden')) { + if (parentBranch.parentNote?.hasAncestor('_hidden')) { parentBranch.markAsDeleted(); } } @@ -67,7 +72,7 @@ function saveSqlConsole(sqlConsoleNoteId) { return result; } -function createSearchNote(searchString, ancestorNoteId) { +function createSearchNote(searchString: string, ancestorNoteId: string) { const {note} = noteService.createNewNote({ parentNoteId: getMonthlyParentNoteId('_search', 'search'), title: `Search: ${searchString}`, @@ -88,6 +93,9 @@ function createSearchNote(searchString, ancestorNoteId) { function getSearchHome() { const workspaceNote = hoistedNoteService.getWorkspaceNote(); + if (!workspaceNote) { + throw new Error("Unable to find workspace note"); + } if (!workspaceNote.isRoot()) { return workspaceNote.searchNoteInSubtree('#workspaceSearchHome') @@ -101,14 +109,18 @@ function getSearchHome() { } } -function saveSearchNote(searchNoteId) { +function saveSearchNote(searchNoteId: string) { const searchNote = becca.getNote(searchNoteId); + if (!searchNote) { + throw new Error("Unable to find search note"); + } + const searchHome = getSearchHome(); const result = searchNote.cloneTo(searchHome.noteId); for (const parentBranch of searchNote.getParentBranches()) { - if (parentBranch.parentNote.hasAncestor('_hidden')) { + if (parentBranch.parentNote?.hasAncestor('_hidden')) { parentBranch.markAsDeleted(); } } @@ -116,7 +128,7 @@ function saveSearchNote(searchNoteId) { return result; } -function getMonthlyParentNoteId(rootNoteId, prefix) { +function getMonthlyParentNoteId(rootNoteId: string, prefix: string) { const month = dateUtils.localNowDate().substring(0, 7); const labelName = `${prefix}MonthNote`; @@ -138,7 +150,7 @@ function getMonthlyParentNoteId(rootNoteId, prefix) { return monthNote.noteId; } -function createScriptLauncher(parentNoteId, forceNoteId = null) { +function createScriptLauncher(parentNoteId: string, forceNoteId?: string) { const note = noteService.createNewNote({ noteId: forceNoteId, title: "Script Launcher", @@ -151,7 +163,13 @@ function createScriptLauncher(parentNoteId, forceNoteId = null) { return note; } -function createLauncher({parentNoteId, launcherType, noteId}) { +interface LauncherConfig { + parentNoteId: string; + launcherType: string; + noteId: string; +} + +function createLauncher({ parentNoteId, launcherType, noteId }: LauncherConfig) { let note; if (launcherType === 'note') { @@ -197,10 +215,10 @@ function createLauncher({parentNoteId, launcherType, noteId}) { }; } -function resetLauncher(noteId) { +function resetLauncher(noteId: string) { const note = becca.getNote(noteId); - if (note.isLaunchBarConfig()) { + if (note?.isLaunchBarConfig()) { if (note) { if (noteId === '_lbRoot') { // deleting hoisted notes are not allowed, so we just reset the children @@ -228,7 +246,13 @@ function resetLauncher(noteId) { * Another use case was for script-packages (e.g. demo Task manager) which could this way register automatically/easily * into the launchbar - for this it's recommended to use backend API's createOrUpdateLauncher() */ -function createOrUpdateScriptLauncherFromApi(opts) { +function createOrUpdateScriptLauncherFromApi(opts: { + id: string; + title: string; + action: string; + icon?: string; + shortcut?: string; +}) { if (opts.id && !/^[a-z0-9]+$/i.test(opts.id)) { throw new Error(`Launcher ID can be alphanumeric only, '${opts.id}' given`); } @@ -263,7 +287,7 @@ function createOrUpdateScriptLauncherFromApi(opts) { return launcherNote; } -module.exports = { +export = { getInboxNote, createSqlConsole, saveSqlConsole,