mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	many small fixes from Intellij analysis
This commit is contained in:
		| @@ -92,6 +92,7 @@ module.exports = { | ||||
|         renderMathInElement: true, | ||||
|         // \src\public\app\widgets\type_widgets\editable_text.js | ||||
|         BalloonEditor: true, | ||||
|         FancytreeNode: true, | ||||
|         CKEditorInspector: true, | ||||
|         // \src\public\app\widgets\type_widgets\editable_code.js | ||||
|         CodeMirror: true, | ||||
|   | ||||
| @@ -189,7 +189,7 @@ class AbstractBeccaEntity { | ||||
|              * We're using the unencrypted blob for the hash calculation, because otherwise the random IV would | ||||
|              * cause every content blob to be unique which would balloon the database size (esp. with revisioning). | ||||
|              * This has minor security implications (it's easy to infer that given content is shared between different | ||||
|              * notes/attachments, but the trade-off comes out clearly positive. | ||||
|              * notes/attachments, but the trade-off comes out clearly positive). | ||||
|              */ | ||||
|             newBlobId = utils.hashedBlobId(unencryptedContentForHashCalculation); | ||||
|             blobNeedsInsert = !sql.getValue('SELECT 1 FROM blobs WHERE blobId = ?', [newBlobId]); | ||||
| @@ -228,7 +228,10 @@ class AbstractBeccaEntity { | ||||
|         return newBlobId; | ||||
|     } | ||||
|  | ||||
|     /** @protected */ | ||||
|     /** | ||||
|      * @protected | ||||
|      * @returns {string|Buffer} | ||||
|      */ | ||||
|     _getContent() { | ||||
|         const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]); | ||||
|  | ||||
|   | ||||
| @@ -86,7 +86,7 @@ class BAttachment extends AbstractBeccaEntity { | ||||
|             || protectedSessionService.isProtectedSessionAvailable() | ||||
|     } | ||||
|  | ||||
|     /** @returns {*} */ | ||||
|     /** @returns {string|Buffer}  */ | ||||
|     getContent() { | ||||
|         return this._getContent(); | ||||
|     } | ||||
|   | ||||
| @@ -207,7 +207,7 @@ class BNote extends AbstractBeccaEntity { | ||||
|      * - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity) | ||||
|      */ | ||||
|  | ||||
|     /** @returns {*} */ | ||||
|     /** @returns {string|Buffer}  */ | ||||
|     getContent() { | ||||
|         return this._getContent(); | ||||
|     } | ||||
| @@ -965,7 +965,7 @@ class BNote extends AbstractBeccaEntity { | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** @returns {String[]} - includes the subtree root note as well */ | ||||
|     /** @returns {string[]} - includes the subtree root note as well */ | ||||
|     getSubtreeNoteIds({includeArchived = true, includeHidden = false, resolveSearch = false} = {}) { | ||||
|         return this.getSubtree({includeArchived, includeHidden, resolveSearch}) | ||||
|             .notes | ||||
| @@ -1157,13 +1157,10 @@ class BNote extends AbstractBeccaEntity { | ||||
|         } | ||||
|  | ||||
|         const parentNotes = this.getParentNotes(); | ||||
|         let notePaths = []; | ||||
|  | ||||
|         if (parentNotes.length === 1) { // optimization for most common case | ||||
|             notePaths = parentNotes[0].getAllNotePaths(); | ||||
|         } else { | ||||
|             notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths()); | ||||
|         } | ||||
|         const notePaths = parentNotes.length === 1 | ||||
|             ? parentNotes[0].getAllNotePaths() // optimization for most common case | ||||
|             : parentNotes.flatMap(parentNote => parentNote.getAllNotePaths()); | ||||
|  | ||||
|         for (const notePath of notePaths) { | ||||
|             notePath.push(this.noteId); | ||||
| @@ -1514,10 +1511,10 @@ class BNote extends AbstractBeccaEntity { | ||||
|     /** | ||||
|      * (Soft) delete a note and all its descendants. | ||||
|      * | ||||
|      * @param {string} [deleteId] - optional delete identified | ||||
|      * @param {string} [deleteId=null] - optional delete identified | ||||
|      * @param {TaskContext} [taskContext] | ||||
|      */ | ||||
|     deleteNote(deleteId, taskContext) { | ||||
|     deleteNote(deleteId = null, taskContext = null) { | ||||
|         if (this.isDeleted) { | ||||
|             return; | ||||
|         } | ||||
|   | ||||
| @@ -80,7 +80,7 @@ class BNoteRevision extends AbstractBeccaEntity { | ||||
|      * This is the same approach as is used for Note's content. | ||||
|      */ | ||||
|  | ||||
|     /** @returns {*} */ | ||||
|     /** @returns {string|Buffer} */ | ||||
|     getContent() { | ||||
|         return this._getContent(); | ||||
|     } | ||||
|   | ||||
| @@ -47,7 +47,7 @@ export default class MainTreeExecutors extends Component { | ||||
|         } | ||||
|  | ||||
|         const parentNotePath = treeService.getNotePath(node.getParent()); | ||||
|         const isProtected = await treeService.getParentProtectedStatus(node); | ||||
|         const isProtected = treeService.getParentProtectedStatus(node); | ||||
|  | ||||
|         if (node.data.noteId === 'root' || node.data.noteId === hoistedNoteService.getHoistedNoteId()) { | ||||
|             return; | ||||
|   | ||||
| @@ -152,7 +152,7 @@ class NoteContext extends Component { | ||||
|         return resolvedNotePath; | ||||
|     } | ||||
|  | ||||
|     /** @property {FNote} */ | ||||
|     /** @returns {FNote} */ | ||||
|     get note() { | ||||
|         if (!this.noteId || !(this.noteId in froca.notes)) { | ||||
|             return null; | ||||
| @@ -161,7 +161,7 @@ class NoteContext extends Component { | ||||
|         return froca.notes[this.noteId]; | ||||
|     } | ||||
|  | ||||
|     /** @property {string[]} */ | ||||
|     /** @returns {string[]} */ | ||||
|     get notePathArray() { | ||||
|         return this.notePath ? this.notePath.split('/') : []; | ||||
|     } | ||||
|   | ||||
| @@ -14,6 +14,8 @@ export default class TabManager extends Component { | ||||
|     constructor() { | ||||
|         super(); | ||||
|  | ||||
|         /** @property {NoteContext[]} */ | ||||
|         this.children = []; | ||||
|         this.mutex = new Mutex(); | ||||
|  | ||||
|         this.activeNtxId = null; | ||||
| @@ -38,7 +40,7 @@ export default class TabManager extends Component { | ||||
|         appContext.addBeforeUnloadListener(this); | ||||
|     } | ||||
|  | ||||
|     /** @type {NoteContext[]} */ | ||||
|     /** @returns {NoteContext[]} */ | ||||
|     get noteContexts() { | ||||
|         return this.children; | ||||
|     } | ||||
|   | ||||
| @@ -358,13 +358,10 @@ class FNote { | ||||
|         } | ||||
|  | ||||
|         const parentNotes = this.getParentNotes(); | ||||
|         let notePaths = []; | ||||
|  | ||||
|         if (parentNotes.length === 1) { // optimization for most common case | ||||
|             notePaths = parentNotes[0].getAllNotePaths(); | ||||
|         } else { | ||||
|             notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths()); | ||||
|         } | ||||
|         const notePaths = parentNotes.length === 1 | ||||
|             ? parentNotes[0].getAllNotePaths() // optimization for most common case | ||||
|             : parentNotes.flatMap(parentNote => parentNote.getAllNotePaths()); | ||||
|  | ||||
|         for (const notePath of notePaths) { | ||||
|             notePath.push(this.noteId); | ||||
|   | ||||
| @@ -108,7 +108,7 @@ export default class TreeContextMenu { | ||||
|         } | ||||
|         else if (command === "insertNoteAfter") { | ||||
|             const parentNotePath = treeService.getNotePath(this.node.getParent()); | ||||
|             const isProtected = await treeService.getParentProtectedStatus(this.node); | ||||
|             const isProtected = treeService.getParentProtectedStatus(this.node); | ||||
|  | ||||
|             noteCreateService.createNote(parentNotePath, { | ||||
|                 target: 'after', | ||||
|   | ||||
| @@ -41,7 +41,7 @@ class WidgetsByParent { | ||||
|  | ||||
|     add(widget) { | ||||
|         if (!widget.parentWidget) { | ||||
|             console.log(`Custom widget does not have mandatory 'getParent()' method defined`); | ||||
|             console.log(`Custom widget does not have mandatory 'parentWidget' property defined`); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -9,15 +9,15 @@ | ||||
|  * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ | ||||
|  * @param {Function} func to wrap | ||||
|  * @param {Number} waitMs in ms (`100`) | ||||
|  * @param {Boolean} immediate whether to execute at the beginning (`false`) | ||||
|  * @param {Boolean} [immediate=false] whether to execute at the beginning (`false`) | ||||
|  * @api public | ||||
|  */ | ||||
| function debounce(func, waitMs, immediate) { | ||||
|     var timeout, args, context, timestamp, result; | ||||
| function debounce(func, waitMs, immediate = false) { | ||||
|     let timeout, args, context, timestamp, result; | ||||
|     if (null == waitMs) waitMs = 100; | ||||
|  | ||||
|     function later() { | ||||
|         var last = Date.now() - timestamp; | ||||
|         const last = Date.now() - timestamp; | ||||
|  | ||||
|         if (last < waitMs && last >= 0) { | ||||
|             timeout = setTimeout(later, waitMs - last); | ||||
| @@ -30,11 +30,11 @@ function debounce(func, waitMs, immediate) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     var debounced = function(){ | ||||
|     const debounced = function () { | ||||
|         context = this; | ||||
|         args = arguments; | ||||
|         timestamp = Date.now(); | ||||
|         var callNow = immediate && !timeout; | ||||
|         const callNow = immediate && !timeout; | ||||
|         if (!timeout) timeout = setTimeout(later, waitMs); | ||||
|         if (callNow) { | ||||
|             result = func.apply(context, args); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import options from "./options.js"; | ||||
| import noteAttributeCache from "./note_attribute_cache.js"; | ||||
| import FBranch from "../entities/fbranch.js"; | ||||
| import FAttribute from "../entities/fattribute.js"; | ||||
| import FAttachment from "../entities/fattachment.js"; | ||||
|  | ||||
| async function processEntityChanges(entityChanges) { | ||||
|     const loadResults = new LoadResults(entityChanges); | ||||
|   | ||||
| @@ -322,7 +322,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | ||||
|      * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. | ||||
|      * | ||||
|      * @method | ||||
|      * @returns {Promise<CKEditor>} instance of CKEditor | ||||
|      * @returns {Promise<BalloonEditor>} instance of CKEditor | ||||
|      */ | ||||
|     this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContext()?.getTextEditor(); | ||||
|  | ||||
|   | ||||
| @@ -79,7 +79,7 @@ async function openExternally(type, entityId, mime) { | ||||
|  | ||||
|         if (res) { | ||||
|             // fallback in case there's no default application for this file | ||||
|             window.open(getFileUrl(type, entityId), { url: true }); | ||||
|             window.open(getFileUrl(type, entityId)); | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|   | ||||
| @@ -18,7 +18,7 @@ async function resolveNotePath(notePath, hoistedNoteId = 'root') { | ||||
|  * notePath as possible. Part of the path might not be valid because of note moving (which causes | ||||
|  * path change) or other corruption, in that case this will try to get some other valid path to the correct note. | ||||
|  * | ||||
|  * @returns {string[]} | ||||
|  * @returns {Promise<string[]>} | ||||
|  */ | ||||
| async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) { | ||||
|     utils.assertArguments(notePath); | ||||
| @@ -129,7 +129,7 @@ ws.subscribeToMessages(message => { | ||||
| }); | ||||
|  | ||||
| function getParentProtectedStatus(node) { | ||||
|     return hoistedNoteService.isHoistedNode(node) ? 0 : node.getParent().data.isProtected; | ||||
|     return hoistedNoteService.isHoistedNode(node) ? false : node.getParent().data.isProtected; | ||||
| } | ||||
|  | ||||
| function getNoteIdFromNotePath(notePath) { | ||||
|   | ||||
| @@ -399,10 +399,10 @@ function escapeRegExp(str) { | ||||
| } | ||||
|  | ||||
| function areObjectsEqual () { | ||||
|     var i, l, leftChain, rightChain; | ||||
|     let i, l, leftChain, rightChain; | ||||
|  | ||||
|     function compare2Objects (x, y) { | ||||
|         var p; | ||||
|         let p; | ||||
|  | ||||
|         // remember that NaN === NaN returns false | ||||
|         // and isNaN(undefined) returns true | ||||
|   | ||||
| @@ -321,9 +321,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget { | ||||
|  | ||||
|     parseAttributes() { | ||||
|         try { | ||||
|             const attrs = attributesParser.lexAndParse(this.getPreprocessedData()); | ||||
|  | ||||
|             return attrs; | ||||
|             return attributesParser.lexAndParse(this.getPreprocessedData()); | ||||
|         } | ||||
|         catch (e) { | ||||
|             this.$errors.text(e.message).slideDown(); | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export default class BookmarkSwitchWidget extends SwitchWidget { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     refreshWithNote(note) { | ||||
|     async refreshWithNote(note) { | ||||
|         const isBookmarked = !!note.getParentBranches().find(b => b.parentNoteId === '_lbBookmarks'); | ||||
|  | ||||
|         this.$switchOn.toggle(!isBookmarked); | ||||
|   | ||||
| @@ -90,7 +90,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     refreshWithNote(note) { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$convertNoteIntoAttachmentButton.toggle(note.isEligibleForConversionToAttachment()); | ||||
|  | ||||
|         this.toggleDisabled(this.$findInTextButton, ['text', 'code', 'book', 'search'].includes(note.type)); | ||||
|   | ||||
| @@ -34,7 +34,7 @@ export default class ConfirmDialog extends BasicWidget { | ||||
|         super(); | ||||
|  | ||||
|         this.resolve = null; | ||||
|         this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterwards | ||||
|         this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterward | ||||
|     } | ||||
|  | ||||
|     doRender() { | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export default class InfoDialog extends BasicWidget { | ||||
|         super(); | ||||
|  | ||||
|         this.resolve = null; | ||||
|         this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterwards | ||||
|         this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterward | ||||
|     } | ||||
|  | ||||
|     doRender() { | ||||
|   | ||||
| @@ -46,7 +46,7 @@ export default class NoteTypeChooserDialog extends BasicWidget { | ||||
|         super(props); | ||||
|  | ||||
|         this.resolve = null; | ||||
|         this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterwards | ||||
|         this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterward | ||||
|         this.$originalDialog = null; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,7 @@ export default class CodeButtonsWidget extends NoteContextAwareWidget { | ||||
|         super.doRender(); | ||||
|     } | ||||
|  | ||||
|     refreshWithNote(note) { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$executeButton.toggle( | ||||
|             note.mime.startsWith('application/javascript') | ||||
|             || note.mime === 'text/x-sqlite;schema=trilium' | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| import libraryLoader from "../services/library_loader.js"; | ||||
| import NoteContextAwareWidget from "./note_context_aware_widget.js"; | ||||
| import froca from "../services/froca.js"; | ||||
|  | ||||
| const TPL = `<div class="mermaid-widget"> | ||||
|     <style> | ||||
|   | ||||
| @@ -78,7 +78,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget { | ||||
|             .width($parent.width()); | ||||
|     } | ||||
|  | ||||
|     async refreshWithNote() { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$widget.show(); | ||||
|  | ||||
|         this.css = { | ||||
|   | ||||
| @@ -1424,11 +1424,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { | ||||
|  | ||||
|         const parentNote = froca.getNoteFromCache(node.getParent().data.noteId); | ||||
|  | ||||
|         if (parentNote && parentNote.hasLabel('sorted')) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|         return !parentNote?.hasLabel('sorted'); | ||||
|     } | ||||
|  | ||||
|     moveNoteUpCommand({node}) { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ export default class ProtectedNoteSwitchWidget extends SwitchWidget { | ||||
|         protectedSessionService.protectNote(this.noteId, false, false) | ||||
|     } | ||||
|  | ||||
|     refreshWithNote(note) { | ||||
|     async refreshWithNote(note) { | ||||
|         this.$switchOn.toggle(!note.isProtected); | ||||
|         this.$switchOff.toggle(!!note.isProtected); | ||||
|     } | ||||
|   | ||||
| @@ -75,14 +75,6 @@ export default class OwnedAttributeListWidget extends NoteContextAwareWidget { | ||||
|         await this.attributeEditorWidget.updateAttributeList(attributes); | ||||
|     } | ||||
|  | ||||
|     entitiesReloadedEvent({loadResults}) { | ||||
|         if (loadResults.getAttributes(this.componentId).find(attr => attributeService.isAffecting(attr, this.note))) { | ||||
|             this.refreshWithNote(this.note, true); | ||||
|  | ||||
|             this.getTitle(this.note); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     focus() { | ||||
|         this.attributeEditorWidget.focus(); | ||||
|     } | ||||
|   | ||||
| @@ -60,7 +60,7 @@ export default class SimilarNotesWidget extends NoteContextAwareWidget { | ||||
|         this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper"); | ||||
|     } | ||||
|  | ||||
|     async refreshWithNote() { | ||||
|     async refreshWithNote(note) { | ||||
|         // remember which title was when we found the similar notes | ||||
|         this.title = this.note.title; | ||||
|  | ||||
|   | ||||
| @@ -517,7 +517,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|  | ||||
|             draggabilly.on('dragEnd', _ => { | ||||
|                 this.isDragging = false; | ||||
|                 const finalTranslateX = parseFloat(tabEl.style.left, 10); | ||||
|                 const finalTranslateX = parseFloat(tabEl.style.left); | ||||
|                 tabEl.style.transform = `translate3d(0, 0, 0)`; | ||||
|  | ||||
|                 // Animate dragged tab back into its place | ||||
| @@ -617,7 +617,10 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         this.updateTab($tab, noteContext); | ||||
|     } | ||||
|  | ||||
|     /** @param {NoteContext} noteContext */ | ||||
|     /** | ||||
|      * @param {jQuery} $tab | ||||
|      * @param {NoteContext} noteContext | ||||
|      */ | ||||
|     async updateTab($tab, noteContext) { | ||||
|         if (!$tab.length) { | ||||
|             return; | ||||
|   | ||||
| @@ -106,7 +106,7 @@ export default class TocWidget extends RightPanelWidget { | ||||
|     /** | ||||
|      * Builds a jquery table of contents. | ||||
|      * | ||||
|      * @param {String} html Note's html content | ||||
|      * @param {string} html Note's html content | ||||
|      * @returns {$toc: jQuery, headingCount: integer} ordered list table of headings, nested by heading level | ||||
|      *         with an onclick event that will cause the document to scroll to | ||||
|      *         the desired position. | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| import libraryLoader from "../../services/library_loader.js"; | ||||
| import TypeWidget from "./type_widget.js"; | ||||
| import utils from '../../services/utils.js'; | ||||
| import froca from "../../services/froca.js"; | ||||
| import debounce from "../../services/debounce.js"; | ||||
|  | ||||
| const {sleep} = utils; | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import froca from "../../services/froca.js"; | ||||
| import AbstractTextTypeWidget from "./abstract_text_type_widget.js"; | ||||
| import treeService from "../../services/tree.js"; | ||||
| import libraryLoader from "../../services/library_loader.js"; | ||||
|   | ||||
| @@ -24,8 +24,6 @@ export default class WatchedFileUpdateStatusWidget extends NoteContextAwareWidge | ||||
|     isEnabled() { | ||||
|         const { entityType, entityId } = this.getEntity(); | ||||
|  | ||||
|         console.log(entityType, entityId); | ||||
|  | ||||
|         return super.isEnabled() && !!fileWatcher.getFileModificationStatus(entityType, entityId); | ||||
|     } | ||||
|  | ||||
| @@ -56,7 +54,7 @@ export default class WatchedFileUpdateStatusWidget extends NoteContextAwareWidge | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     refreshWithNote(note) { | ||||
|     async refreshWithNote(note) { | ||||
|         const { entityType, entityId } = this.getEntity(); | ||||
|         const status = fileWatcher.getFileModificationStatus(entityType, entityId); | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,6 @@ function getNoteRevisions(req) { | ||||
| } | ||||
|  | ||||
| function getNoteRevision(req) { | ||||
|     // FIXME | ||||
|     const noteRevision = becca.getNoteRevision(req.params.noteRevisionId); | ||||
|  | ||||
|     if (noteRevision.type === 'file') { | ||||
|   | ||||
| @@ -51,13 +51,16 @@ function encrypt(key, plainText) { | ||||
|     return encryptedDataWithIv.toString('base64'); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @returns {Buffer|false|null} | ||||
|  */ | ||||
| function decrypt(key, cipherText) { | ||||
|     if (cipherText === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     if (!key) { | ||||
|         return "[protected]"; | ||||
|         return Buffer.from("[protected]"); | ||||
|     } | ||||
|  | ||||
|     try { | ||||
| @@ -103,17 +106,13 @@ function decryptString(dataKey, cipherText) { | ||||
|  | ||||
|     if (buffer === null) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     const str = buffer.toString('utf-8'); | ||||
|  | ||||
|     if (str === 'false') { | ||||
|     } else if (buffer === false) { | ||||
|         log.error(`Could not decrypt string. Buffer: ${buffer}`); | ||||
|  | ||||
|         throw new Error("Could not decrypt string."); | ||||
|     } | ||||
|  | ||||
|     return str; | ||||
|     return buffer.toString('UTF-8'); | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
| @@ -369,6 +369,10 @@ async function importZip(taskContext, fileBuffer, importRootNote) { | ||||
|         return content; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {string} filePath | ||||
|      * @param {Buffer} content | ||||
|      */ | ||||
|     function saveNote(filePath, content) { | ||||
|         const {parentNoteMeta, noteMeta, attachmentMeta} = getMeta(filePath); | ||||
|  | ||||
| @@ -566,6 +570,7 @@ function streamToBuffer(stream) { | ||||
|     return new Promise((res, rej) => stream.on('end', () => res(Buffer.concat(chunks)))); | ||||
| } | ||||
|  | ||||
| /** @returns {Buffer} */ | ||||
| function readContent(zipfile, entry) { | ||||
|     return new Promise((res, rej) => { | ||||
|         zipfile.openReadStream(entry, function(err, readStream) { | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| const becca = require('../becca/becca'); | ||||
| const sql = require("./sql"); | ||||
|  | ||||
| /** @returns {string|null} */ | ||||
| function getOptionOrNull(name) { | ||||
|     let option; | ||||
|  | ||||
| @@ -14,11 +15,12 @@ function getOptionOrNull(name) { | ||||
|     return option ? option.value : null; | ||||
| } | ||||
|  | ||||
| /** @returns {string} */ | ||||
| function getOption(name) { | ||||
|     const val = getOptionOrNull(name); | ||||
|  | ||||
|     if (val === null) { | ||||
|         throw new Error(`Option "${name}" doesn't exist`); | ||||
|         throw new Error(`Option '${name}' doesn't exist`); | ||||
|     } | ||||
|  | ||||
|     return val; | ||||
|   | ||||
| @@ -177,7 +177,7 @@ function register(router) { | ||||
|         res.send(note.getContent()); | ||||
|     }); | ||||
|  | ||||
|     // :filename is not used by trilium, but instead used for "save as" to assign a human readable filename | ||||
|     // :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename | ||||
|     router.get('/share/api/images/:noteId/:filename', (req, res, next) => { | ||||
|         shacaLoader.ensureLoad(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user