mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +01:00 
			
		
		
		
	Merge pull request #42 from TriliumNext/feature/typescript_backend_6
Convert backend to TypeScript (67% -> 71%)
This commit is contained in:
		
						commit
						a072016fc5
					
				
							
								
								
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -101,6 +101,7 @@ | ||||
|         "@types/sanitize-html": "^2.11.0", | ||||
|         "@types/sax": "^1.2.7", | ||||
|         "@types/stream-throttle": "^0.1.4", | ||||
|         "@types/tmp": "^0.2.6", | ||||
|         "@types/turndown": "^5.0.4", | ||||
|         "@types/ws": "^8.5.10", | ||||
|         "@types/xml2js": "^0.4.14", | ||||
| @ -1628,6 +1629,12 @@ | ||||
|         "@types/node": "*" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@types/tmp": { | ||||
|       "version": "0.2.6", | ||||
|       "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz", | ||||
|       "integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@types/tough-cookie": { | ||||
|       "version": "4.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", | ||||
| @ -14570,6 +14577,12 @@ | ||||
|         "@types/node": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/tmp": { | ||||
|       "version": "0.2.6", | ||||
|       "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz", | ||||
|       "integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/tough-cookie": { | ||||
|       "version": "4.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", | ||||
|  | ||||
| @ -122,6 +122,7 @@ | ||||
|     "@types/sanitize-html": "^2.11.0", | ||||
|     "@types/sax": "^1.2.7", | ||||
|     "@types/stream-throttle": "^0.1.4", | ||||
|     "@types/tmp": "^0.2.6", | ||||
|     "@types/turndown": "^5.0.4", | ||||
|     "@types/ws": "^8.5.10", | ||||
|     "@types/xml2js": "^0.4.14", | ||||
|  | ||||
| @ -129,7 +129,7 @@ export default class Becca { | ||||
|         return this.branches[branchId]; | ||||
|     } | ||||
| 
 | ||||
|     getBranchOrThrow(branchId: string): BBranch | null { | ||||
|     getBranchOrThrow(branchId: string): BBranch { | ||||
|         const branch = this.getBranch(branchId); | ||||
|         if (!branch) { | ||||
|             throw new NotFoundError(`Branch '${branchId}' was not found in becca.`); | ||||
| @ -239,7 +239,7 @@ export default class Becca { | ||||
|         return (this as any)[camelCaseEntityName][entityId]; | ||||
|     } | ||||
| 
 | ||||
|     getRecentNotesFromQuery(query: string, params = []): BRecentNote[] { | ||||
|     getRecentNotesFromQuery(query: string, params: string[] = []): BRecentNote[] { | ||||
|         const rows = sql.getRows(query, params); | ||||
| 
 | ||||
|         const BRecentNote = require('./entities/brecent_note'); // avoiding circular dependency problems
 | ||||
|  | ||||
| @ -134,7 +134,7 @@ class BAttachment extends AbstractBeccaEntity<BAttachment> { | ||||
|         return this._getContent() as Buffer; | ||||
|     } | ||||
| 
 | ||||
|     setContent(content: string | Buffer, opts: ContentOpts) { | ||||
|     setContent(content: string | Buffer, opts?: ContentOpts) { | ||||
|         this._setContent(content, opts); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -203,9 +203,9 @@ class BNote extends AbstractBeccaEntity<BNote> { | ||||
|         return this.children && this.children.length > 0; | ||||
|     } | ||||
| 
 | ||||
|     getChildBranches(): (BBranch | null)[] { | ||||
|     getChildBranches(): BBranch[] { | ||||
|         return this.children | ||||
|             .map(childNote => this.becca.getBranchFromChildAndParent(childNote.noteId, this.noteId)); | ||||
|             .map(childNote => this.becca.getBranchFromChildAndParent(childNote.noteId, this.noteId)) as BBranch[]; | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
| @ -1434,7 +1434,7 @@ class BNote extends AbstractBeccaEntity<BNote> { | ||||
|     searchNotesInSubtree(searchString: string) { | ||||
|         const searchService = require('../../services/search/services/search'); | ||||
| 
 | ||||
|         return searchService.searchNotes(searchString); | ||||
|         return searchService.searchNotes(searchString) as BNote[]; | ||||
|     } | ||||
| 
 | ||||
|     searchNoteInSubtree(searchString: string) { | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const appInfo = require('../../services/app_info'); | ||||
| import appInfo = require('../../services/app_info'); | ||||
| 
 | ||||
| function getAppInfo() { | ||||
|     return appInfo; | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getAppInfo | ||||
| }; | ||||
| @ -1,27 +1,28 @@ | ||||
| const becca = require('../../becca/becca'); | ||||
| const blobService = require('../../services/blob'); | ||||
| const ValidationError = require('../../errors/validation_error'); | ||||
| const imageService = require("../../services/image"); | ||||
| import becca = require('../../becca/becca'); | ||||
| import blobService = require('../../services/blob'); | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| import imageService = require("../../services/image"); | ||||
| import { Request } from 'express'; | ||||
| 
 | ||||
| function getAttachmentBlob(req) { | ||||
| function getAttachmentBlob(req: Request) { | ||||
|     const preview = req.query.preview === 'true'; | ||||
| 
 | ||||
|     return blobService.getBlobPojo('attachments', req.params.attachmentId, { preview }); | ||||
| } | ||||
| 
 | ||||
| function getAttachments(req) { | ||||
| function getAttachments(req: Request) { | ||||
|     const note = becca.getNoteOrThrow(req.params.noteId); | ||||
| 
 | ||||
|     return note.getAttachments({includeContentLength: true}); | ||||
| } | ||||
| 
 | ||||
| function getAttachment(req) { | ||||
| function getAttachment(req: Request) { | ||||
|     const {attachmentId} = req.params; | ||||
| 
 | ||||
|     return becca.getAttachmentOrThrow(attachmentId, {includeContentLength: true}); | ||||
| } | ||||
| 
 | ||||
| function getAllAttachments(req) { | ||||
| function getAllAttachments(req: Request) { | ||||
|     const {attachmentId} = req.params; | ||||
|     // one particular attachment is requested, but return all note's attachments
 | ||||
| 
 | ||||
| @ -29,18 +30,18 @@ function getAllAttachments(req) { | ||||
|     return attachment.getNote()?.getAttachments({includeContentLength: true}) || []; | ||||
| } | ||||
| 
 | ||||
| function saveAttachment(req) { | ||||
| function saveAttachment(req: Request) { | ||||
|     const {noteId} = req.params; | ||||
|     const {attachmentId, role, mime, title, content} = req.body; | ||||
|     const {matchBy} = req.query; | ||||
|     const {matchBy} = req.query as any; | ||||
| 
 | ||||
|     const note = becca.getNoteOrThrow(noteId); | ||||
|     note.saveAttachment({attachmentId, role, mime, title, content}, matchBy); | ||||
| } | ||||
| 
 | ||||
| function uploadAttachment(req) { | ||||
| function uploadAttachment(req: Request) { | ||||
|     const {noteId} = req.params; | ||||
|     const {file} = req; | ||||
|     const {file} = req as any; | ||||
| 
 | ||||
|     const note = becca.getNoteOrThrow(noteId); | ||||
|     let url; | ||||
| @ -65,7 +66,7 @@ function uploadAttachment(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function renameAttachment(req) { | ||||
| function renameAttachment(req: Request) { | ||||
|     const {title} = req.body; | ||||
|     const {attachmentId} = req.params; | ||||
| 
 | ||||
| @ -79,7 +80,7 @@ function renameAttachment(req) { | ||||
|     attachment.save(); | ||||
| } | ||||
| 
 | ||||
| function deleteAttachment(req) { | ||||
| function deleteAttachment(req: Request) { | ||||
|     const {attachmentId} = req.params; | ||||
| 
 | ||||
|     const attachment = becca.getAttachment(attachmentId); | ||||
| @ -89,14 +90,14 @@ function deleteAttachment(req) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function convertAttachmentToNote(req) { | ||||
| function convertAttachmentToNote(req: Request) { | ||||
|     const {attachmentId} = req.params; | ||||
| 
 | ||||
|     const attachment = becca.getAttachmentOrThrow(attachmentId); | ||||
|     return attachment.convertToNote(); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getAttachmentBlob, | ||||
|     getAttachments, | ||||
|     getAttachment, | ||||
| @ -1,19 +1,20 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const sql = require('../../services/sql'); | ||||
| const log = require('../../services/log'); | ||||
| const attributeService = require('../../services/attributes'); | ||||
| const BAttribute = require('../../becca/entities/battribute'); | ||||
| const becca = require('../../becca/becca'); | ||||
| const ValidationError = require('../../errors/validation_error'); | ||||
| import sql = require('../../services/sql'); | ||||
| import log = require('../../services/log'); | ||||
| import attributeService = require('../../services/attributes'); | ||||
| import BAttribute = require('../../becca/entities/battribute'); | ||||
| import becca = require('../../becca/becca'); | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| import { Request } from 'express'; | ||||
| 
 | ||||
| function getEffectiveNoteAttributes(req) { | ||||
| function getEffectiveNoteAttributes(req: Request) { | ||||
|     const note = becca.getNote(req.params.noteId); | ||||
| 
 | ||||
|     return note.getAttributes(); | ||||
|     return note?.getAttributes(); | ||||
| } | ||||
| 
 | ||||
| function updateNoteAttribute(req) { | ||||
| function updateNoteAttribute(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const body = req.body; | ||||
| 
 | ||||
| @ -70,14 +71,17 @@ function updateNoteAttribute(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function setNoteAttribute(req) { | ||||
| function setNoteAttribute(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const body = req.body; | ||||
| 
 | ||||
|     const attributeId = sql.getValue(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = ? AND name = ?`, [noteId, body.type, body.name]); | ||||
|     const attributeId = sql.getValue<string | null>(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = ? AND name = ?`, [noteId, body.type, body.name]); | ||||
| 
 | ||||
|     if (attributeId) { | ||||
|         const attr = becca.getAttribute(attributeId); | ||||
|         if (!attr) { | ||||
|             throw new ValidationError(`Missing attribute with ID ${attributeId}.`); | ||||
|         } | ||||
|         attr.value = body.value; | ||||
|         attr.save(); | ||||
|     } else { | ||||
| @ -88,14 +92,14 @@ function setNoteAttribute(req) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function addNoteAttribute(req) { | ||||
| function addNoteAttribute(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const body = req.body; | ||||
| 
 | ||||
|     new BAttribute({...body, noteId}).save(); | ||||
| } | ||||
| 
 | ||||
| function deleteNoteAttribute(req) { | ||||
| function deleteNoteAttribute(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const attributeId = req.params.attributeId; | ||||
| 
 | ||||
| @ -110,11 +114,14 @@ function deleteNoteAttribute(req) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function updateNoteAttributes(req) { | ||||
| function updateNoteAttributes(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const incomingAttributes = req.body; | ||||
| 
 | ||||
|     const note = becca.getNote(noteId); | ||||
|     if (!note) { | ||||
|         throw new ValidationError(`Cannot find note with ID ${noteId}.`); | ||||
|     } | ||||
| 
 | ||||
|     let existingAttrs = note.getOwnedAttributes().slice(); | ||||
| 
 | ||||
| @ -179,25 +186,29 @@ function updateNoteAttributes(req) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function getAttributeNames(req) { | ||||
| function getAttributeNames(req: Request) { | ||||
|     const type = req.query.type; | ||||
|     const query = req.query.query; | ||||
| 
 | ||||
|     if (typeof type !== "string" || typeof query !== "string") { | ||||
|         throw new ValidationError("Invalid data type."); | ||||
|     } | ||||
| 
 | ||||
|     return attributeService.getAttributeNames(type, query); | ||||
| } | ||||
| 
 | ||||
| function getValuesForAttribute(req) { | ||||
| function getValuesForAttribute(req: Request) { | ||||
|     const attributeName = req.params.attributeName; | ||||
| 
 | ||||
|     return sql.getColumn("SELECT DISTINCT value FROM attributes WHERE isDeleted = 0 AND name = ? AND type = 'label' AND value != '' ORDER BY value", [attributeName]); | ||||
| } | ||||
| 
 | ||||
| function createRelation(req) { | ||||
| function createRelation(req: Request) { | ||||
|     const sourceNoteId = req.params.noteId; | ||||
|     const targetNoteId = req.params.targetNoteId; | ||||
|     const name = req.params.name; | ||||
| 
 | ||||
|     const attributeId = sql.getValue(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = 'relation' AND name = ? AND value = ?`, [sourceNoteId, name, targetNoteId]); | ||||
|     const attributeId = sql.getValue<string>(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = 'relation' AND name = ? AND value = ?`, [sourceNoteId, name, targetNoteId]); | ||||
|     let attribute = becca.getAttribute(attributeId); | ||||
| 
 | ||||
|     if (!attribute) { | ||||
| @ -212,20 +223,22 @@ function createRelation(req) { | ||||
|     return attribute; | ||||
| } | ||||
| 
 | ||||
| function deleteRelation(req) { | ||||
| function deleteRelation(req: Request) { | ||||
|     const sourceNoteId = req.params.noteId; | ||||
|     const targetNoteId = req.params.targetNoteId; | ||||
|     const name = req.params.name; | ||||
| 
 | ||||
|     const attributeId = sql.getValue(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = 'relation' AND name = ? AND value = ?`, [sourceNoteId, name, targetNoteId]); | ||||
|     const attributeId = sql.getValue<string | null>(`SELECT attributeId FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = 'relation' AND name = ? AND value = ?`, [sourceNoteId, name, targetNoteId]); | ||||
| 
 | ||||
|     if (attributeId) { | ||||
|         const attribute = becca.getAttribute(attributeId); | ||||
|         attribute.markAsDeleted(); | ||||
|         if (attribute) { | ||||
|             attribute.markAsDeleted(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     updateNoteAttributes, | ||||
|     updateNoteAttribute, | ||||
|     setNoteAttribute, | ||||
| @ -1,21 +1,26 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const beccaService = require('../../becca/becca_service'); | ||||
| const searchService = require('../../services/search/services/search'); | ||||
| const log = require('../../services/log'); | ||||
| const utils = require('../../services/utils'); | ||||
| const cls = require('../../services/cls'); | ||||
| const becca = require('../../becca/becca'); | ||||
| import beccaService = require('../../becca/becca_service'); | ||||
| import searchService = require('../../services/search/services/search'); | ||||
| import log = require('../../services/log'); | ||||
| import utils = require('../../services/utils'); | ||||
| import cls = require('../../services/cls'); | ||||
| import becca = require('../../becca/becca'); | ||||
| import { Request } from 'express'; | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| 
 | ||||
| function getAutocomplete(req) { | ||||
|     const query = req.query.query.trim(); | ||||
| function getAutocomplete(req: Request) { | ||||
|     if (typeof req.query.query !== "string") { | ||||
|         throw new ValidationError("Invalid query data type."); | ||||
|     } | ||||
|     const query = (req.query.query || "").trim(); | ||||
|     const activeNoteId = req.query.activeNoteId || 'none'; | ||||
| 
 | ||||
|     let results; | ||||
| 
 | ||||
|     const timestampStarted = Date.now(); | ||||
| 
 | ||||
|     if (query.length === 0) { | ||||
|     if (query.length === 0 && typeof activeNoteId === "string") { | ||||
|         results = getRecentNotes(activeNoteId); | ||||
|     } | ||||
|     else { | ||||
| @ -31,7 +36,7 @@ function getAutocomplete(req) { | ||||
|     return results; | ||||
| } | ||||
| 
 | ||||
| function getRecentNotes(activeNoteId) { | ||||
| function getRecentNotes(activeNoteId: string) { | ||||
|     let extraCondition = ''; | ||||
|     const params = [activeNoteId]; | ||||
| 
 | ||||
| @ -70,6 +75,6 @@ function getRecentNotes(activeNoteId) { | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getAutocomplete | ||||
| }; | ||||
| @ -1,8 +1,9 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const fs = require('fs'); | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const {LOG_DIR} = require('../../services/data_dir'); | ||||
| import fs = require('fs'); | ||||
| import dateUtils = require('../../services/date_utils'); | ||||
| import dataDir = require('../../services/data_dir'); | ||||
| const { LOG_DIR } = dataDir; | ||||
| 
 | ||||
| function getBackendLog() { | ||||
|     const file = `${LOG_DIR}/trilium-${dateUtils.localNowDate()}.log`; | ||||
| @ -16,6 +17,6 @@ function getBackendLog() { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getBackendLog | ||||
| }; | ||||
| @ -1,23 +1,24 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const sql = require('../../services/sql'); | ||||
| const utils = require('../../services/utils'); | ||||
| const entityChangesService = require('../../services/entity_changes'); | ||||
| const treeService = require('../../services/tree'); | ||||
| const eraseService = require('../../services/erase'); | ||||
| const becca = require('../../becca/becca'); | ||||
| const TaskContext = require('../../services/task_context'); | ||||
| const branchService = require('../../services/branches'); | ||||
| const log = require('../../services/log'); | ||||
| const ValidationError = require('../../errors/validation_error'); | ||||
| const eventService = require("../../services/events"); | ||||
| import sql = require('../../services/sql'); | ||||
| import utils = require('../../services/utils'); | ||||
| import entityChangesService = require('../../services/entity_changes'); | ||||
| import treeService = require('../../services/tree'); | ||||
| import eraseService = require('../../services/erase'); | ||||
| import becca = require('../../becca/becca'); | ||||
| import TaskContext = require('../../services/task_context'); | ||||
| import branchService = require('../../services/branches'); | ||||
| import log = require('../../services/log'); | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| import eventService = require("../../services/events"); | ||||
| import { Request } from 'express'; | ||||
| 
 | ||||
| /** | ||||
|  * Code in this file deals with moving and cloning branches. The relationship between note and parent note is unique | ||||
|  * for not deleted branches. There may be multiple deleted note-parent note relationships. | ||||
|  */ | ||||
| 
 | ||||
| function moveBranchToParent(req) { | ||||
| function moveBranchToParent(req: Request) { | ||||
|     const {branchId, parentBranchId} = req.params; | ||||
| 
 | ||||
|     const branchToMove = becca.getBranch(branchId); | ||||
| @ -30,7 +31,7 @@ function moveBranchToParent(req) { | ||||
|     return branchService.moveBranchToBranch(branchToMove, targetParentBranch, branchId); | ||||
| } | ||||
| 
 | ||||
| function moveBranchBeforeNote(req) { | ||||
| function moveBranchBeforeNote(req: Request) { | ||||
|     const {branchId, beforeBranchId} = req.params; | ||||
| 
 | ||||
|     const branchToMove = becca.getBranchOrThrow(branchId); | ||||
| @ -51,7 +52,7 @@ function moveBranchBeforeNote(req) { | ||||
|         [beforeBranch.parentNoteId, originalBeforeNotePosition]); | ||||
| 
 | ||||
|     // also need to update becca positions
 | ||||
|     const parentNote = becca.getNote(beforeBranch.parentNoteId); | ||||
|     const parentNote = becca.getNoteOrThrow(beforeBranch.parentNoteId); | ||||
| 
 | ||||
|     for (const childBranch of parentNote.getChildBranches()) { | ||||
|         if (childBranch.notePosition >= originalBeforeNotePosition) { | ||||
| @ -80,11 +81,11 @@ function moveBranchBeforeNote(req) { | ||||
|     return { success: true }; | ||||
| } | ||||
| 
 | ||||
| function moveBranchAfterNote(req) { | ||||
| function moveBranchAfterNote(req: Request) { | ||||
|     const {branchId, afterBranchId} = req.params; | ||||
| 
 | ||||
|     const branchToMove = becca.getBranch(branchId); | ||||
|     const afterNote = becca.getBranch(afterBranchId); | ||||
|     const branchToMove = becca.getBranchOrThrow(branchId); | ||||
|     const afterNote = becca.getBranchOrThrow(afterBranchId); | ||||
| 
 | ||||
|     const validationResult = treeService.validateParentChild(afterNote.parentNoteId, branchToMove.noteId, branchId); | ||||
| 
 | ||||
| @ -100,7 +101,7 @@ function moveBranchAfterNote(req) { | ||||
|         [afterNote.parentNoteId, originalAfterNotePosition]); | ||||
| 
 | ||||
|     // also need to update becca positions
 | ||||
|     const parentNote = becca.getNote(afterNote.parentNoteId); | ||||
|     const parentNote = becca.getNoteOrThrow(afterNote.parentNoteId); | ||||
| 
 | ||||
|     for (const childBranch of parentNote.getChildBranches()) { | ||||
|         if (childBranch.notePosition > originalAfterNotePosition) { | ||||
| @ -131,7 +132,7 @@ function moveBranchAfterNote(req) { | ||||
|     return { success: true }; | ||||
| } | ||||
| 
 | ||||
| function setExpanded(req) { | ||||
| function setExpanded(req: Request) { | ||||
|     const {branchId} = req.params; | ||||
|     const expanded = parseInt(req.params.expanded); | ||||
| 
 | ||||
| @ -153,11 +154,11 @@ function setExpanded(req) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function setExpandedForSubtree(req) { | ||||
| function setExpandedForSubtree(req: Request) { | ||||
|     const {branchId} = req.params; | ||||
|     const expanded = parseInt(req.params.expanded); | ||||
| 
 | ||||
|     let branchIds = sql.getColumn(` | ||||
|     let branchIds = sql.getColumn<string>(` | ||||
|         WITH RECURSIVE | ||||
|         tree(branchId, noteId) AS ( | ||||
|             SELECT branchId, noteId FROM branches WHERE branchId = ? | ||||
| @ -186,12 +187,12 @@ function setExpandedForSubtree(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function deleteBranch(req) { | ||||
| function deleteBranch(req: Request) { | ||||
|     const last = req.query.last === 'true'; | ||||
|     const eraseNotes = req.query.eraseNotes === 'true'; | ||||
|     const branch = becca.getBranchOrThrow(req.params.branchId); | ||||
| 
 | ||||
|     const taskContext = TaskContext.getInstance(req.query.taskId, 'deleteNotes'); | ||||
|     const taskContext = TaskContext.getInstance(req.query.taskId as string, 'deleteNotes'); | ||||
| 
 | ||||
|     const deleteId = utils.randomString(10); | ||||
|     let noteDeleted; | ||||
| @ -214,16 +215,16 @@ function deleteBranch(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function setPrefix(req) { | ||||
| function setPrefix(req: Request) { | ||||
|     const branchId = req.params.branchId; | ||||
|     const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; | ||||
| 
 | ||||
|     const branch = becca.getBranch(branchId); | ||||
|     const branch = becca.getBranchOrThrow(branchId); | ||||
|     branch.prefix = prefix; | ||||
|     branch.save(); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     moveBranchToParent, | ||||
|     moveBranchBeforeNote, | ||||
|     moveBranchAfterNote, | ||||
| @ -1,17 +1,18 @@ | ||||
| const becca = require('../../becca/becca'); | ||||
| const bulkActionService = require('../../services/bulk_actions'); | ||||
| import { Request } from 'express'; | ||||
| import becca = require('../../becca/becca'); | ||||
| import bulkActionService = require('../../services/bulk_actions'); | ||||
| 
 | ||||
| function execute(req) { | ||||
| function execute(req: Request) { | ||||
|     const {noteIds, includeDescendants} = req.body; | ||||
| 
 | ||||
|     const affectedNoteIds = getAffectedNoteIds(noteIds, includeDescendants); | ||||
| 
 | ||||
|     const bulkActionNote = becca.getNote('_bulkAction'); | ||||
|     const bulkActionNote = becca.getNoteOrThrow('_bulkAction'); | ||||
| 
 | ||||
|     bulkActionService.executeActions(bulkActionNote, affectedNoteIds); | ||||
| } | ||||
| 
 | ||||
| function getAffectedNoteCount(req) { | ||||
| function getAffectedNoteCount(req: Request) { | ||||
|     const {noteIds, includeDescendants} = req.body; | ||||
| 
 | ||||
|     const affectedNoteIds = getAffectedNoteIds(noteIds, includeDescendants); | ||||
| @ -21,8 +22,8 @@ function getAffectedNoteCount(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function getAffectedNoteIds(noteIds, includeDescendants) { | ||||
|     const affectedNoteIds = new Set(); | ||||
| function getAffectedNoteIds(noteIds: string[], includeDescendants: boolean) { | ||||
|     const affectedNoteIds = new Set<string>(); | ||||
| 
 | ||||
|     for (const noteId of noteIds) { | ||||
|         const note = becca.getNote(noteId); | ||||
| @ -42,7 +43,7 @@ function getAffectedNoteIds(noteIds, includeDescendants) { | ||||
|     return affectedNoteIds; | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     execute, | ||||
|     getAffectedNoteCount | ||||
| }; | ||||
| @ -1,22 +1,32 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const attributeService = require('../../services/attributes'); | ||||
| const cloneService = require('../../services/cloning'); | ||||
| const noteService = require('../../services/notes'); | ||||
| const dateNoteService = require('../../services/date_notes'); | ||||
| const dateUtils = require('../../services/date_utils'); | ||||
| const imageService = require('../../services/image'); | ||||
| const appInfo = require('../../services/app_info'); | ||||
| const ws = require('../../services/ws'); | ||||
| const log = require('../../services/log'); | ||||
| const utils = require('../../services/utils'); | ||||
| const path = require('path'); | ||||
| const htmlSanitizer = require('../../services/html_sanitizer'); | ||||
| const {formatAttrForSearch} = require('../../services/attribute_formatter'); | ||||
| const jsdom = require("jsdom"); | ||||
| import { Request } from "express"; | ||||
| 
 | ||||
| import attributeService = require('../../services/attributes'); | ||||
| import cloneService = require('../../services/cloning'); | ||||
| import noteService = require('../../services/notes'); | ||||
| import dateNoteService = require('../../services/date_notes'); | ||||
| import dateUtils = require('../../services/date_utils'); | ||||
| import imageService = require('../../services/image'); | ||||
| import appInfo = require('../../services/app_info'); | ||||
| import ws = require('../../services/ws'); | ||||
| import log = require('../../services/log'); | ||||
| import utils = require('../../services/utils'); | ||||
| import path = require('path'); | ||||
| import htmlSanitizer = require('../../services/html_sanitizer'); | ||||
| import attributeFormatter = require('../../services/attribute_formatter'); | ||||
| import jsdom = require("jsdom"); | ||||
| import BNote = require("../../becca/entities/bnote"); | ||||
| import ValidationError = require("../../errors/validation_error"); | ||||
| const { JSDOM } = jsdom; | ||||
| 
 | ||||
| function addClipping(req) { | ||||
| interface Image { | ||||
|     src: string; | ||||
|     dataUrl: string; | ||||
|     imageId: string; | ||||
| } | ||||
| 
 | ||||
| function addClipping(req: Request) { | ||||
|     // if a note under the clipperInbox has the same 'pageUrl' attribute,
 | ||||
|     // add the content to that note and clone it under today's inbox
 | ||||
|     // otherwise just create a new note under today's inbox
 | ||||
| @ -44,10 +54,14 @@ function addClipping(req) { | ||||
|     const rewrittenContent = processContent(images, clippingNote, content); | ||||
| 
 | ||||
|     const existingContent = clippingNote.getContent(); | ||||
|     if (typeof existingContent !== "string") { | ||||
|         throw new ValidationError("Invalid note content type."); | ||||
|     } | ||||
| 
 | ||||
|     clippingNote.setContent(`${existingContent}${existingContent.trim() ? "<br>" : ""}${rewrittenContent}`); | ||||
| 
 | ||||
|     if (clippingNote.parentNoteId !== clipperInbox.noteId) { | ||||
|     // TODO: Is parentNoteId ever defined?
 | ||||
|     if ((clippingNote as any).parentNoteId !== clipperInbox.noteId) { | ||||
|         cloneService.cloneNoteToParentNote(clippingNote.noteId, clipperInbox.noteId); | ||||
|     } | ||||
| 
 | ||||
| @ -56,13 +70,13 @@ function addClipping(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function findClippingNote(clipperInboxNote, pageUrl, clipType) { | ||||
| function findClippingNote(clipperInboxNote: BNote, pageUrl: string, clipType: string | null) { | ||||
|     if (!pageUrl) { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     const notes = clipperInboxNote.searchNotesInSubtree( | ||||
|         formatAttrForSearch({ | ||||
|         attributeFormatter.formatAttrForSearch({ | ||||
|             type: 'label', | ||||
|             name: "pageUrl", | ||||
|             value: pageUrl | ||||
| @ -84,7 +98,7 @@ function getClipperInboxNote() { | ||||
|     return clipperInbox; | ||||
| } | ||||
| 
 | ||||
| function createNote(req) { | ||||
| function createNote(req: Request) { | ||||
|     let {title, content, pageUrl, images, clipType, labels} = req.body; | ||||
| 
 | ||||
|     if (!title || !title.trim()) { | ||||
| @ -123,6 +137,9 @@ function createNote(req) { | ||||
|     } | ||||
| 
 | ||||
|     const existingContent = note.getContent(); | ||||
|     if (typeof existingContent !== "string") { | ||||
|         throw new ValidationError("Invalid note content tpye."); | ||||
|     } | ||||
|     const rewrittenContent = processContent(images, note, content); | ||||
|     const newContent = `${existingContent}${existingContent.trim() ? "<br/>" : ""}${rewrittenContent}`; | ||||
|     note.setContent(newContent); | ||||
| @ -134,7 +151,7 @@ function createNote(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function processContent(images, note, content) { | ||||
| function processContent(images: Image[], note: BNote, content: string) { | ||||
|     let rewrittenContent = htmlSanitizer.sanitize(content); | ||||
| 
 | ||||
|     if (images) { | ||||
| @ -178,7 +195,7 @@ function processContent(images, note, content) { | ||||
|     return rewrittenContent; | ||||
| } | ||||
| 
 | ||||
| function openNote(req) { | ||||
| function openNote(req: Request) { | ||||
|     if (utils.isElectron()) { | ||||
|         ws.sendMessageToAllClients({ | ||||
|             type: 'openNote', | ||||
| @ -203,7 +220,7 @@ function handshake() { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function findNotesByUrl(req){ | ||||
| function findNotesByUrl(req: Request){ | ||||
|     let pageUrl = req.params.noteUrl; | ||||
|     const clipperInbox = getClipperInboxNote(); | ||||
|     let foundPage = findClippingNote(clipperInbox, pageUrl, null); | ||||
| @ -1,34 +1,35 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const cloningService = require('../../services/cloning'); | ||||
| import { Request } from 'express'; | ||||
| import cloningService = require('../../services/cloning'); | ||||
| 
 | ||||
| function cloneNoteToBranch(req) { | ||||
| function cloneNoteToBranch(req: Request) { | ||||
|     const {noteId, parentBranchId} = req.params; | ||||
|     const {prefix} = req.body; | ||||
| 
 | ||||
|     return cloningService.cloneNoteToBranch(noteId, parentBranchId, prefix); | ||||
| } | ||||
| 
 | ||||
| function cloneNoteToParentNote(req) { | ||||
| function cloneNoteToParentNote(req: Request) { | ||||
|     const {noteId, parentNoteId} = req.params; | ||||
|     const {prefix} = req.body; | ||||
| 
 | ||||
|     return cloningService.cloneNoteToParentNote(noteId, parentNoteId, prefix); | ||||
| } | ||||
| 
 | ||||
| function cloneNoteAfter(req) { | ||||
| function cloneNoteAfter(req: Request) { | ||||
|     const {noteId, afterBranchId} = req.params; | ||||
| 
 | ||||
|     return cloningService.cloneNoteAfter(noteId, afterBranchId); | ||||
| } | ||||
| 
 | ||||
| function toggleNoteInParent(req) { | ||||
| function toggleNoteInParent(req: Request) { | ||||
|     const {noteId, parentNoteId, present} = req.params; | ||||
| 
 | ||||
|     return cloningService.toggleNoteInParent(present === 'true', noteId, parentNoteId); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     cloneNoteToBranch, | ||||
|     cloneNoteToParentNote, | ||||
|     cloneNoteAfter, | ||||
| @ -1,10 +1,12 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const sql = require('../../services/sql'); | ||||
| const log = require('../../services/log'); | ||||
| const backupService = require('../../services/backup'); | ||||
| const anonymizationService = require('../../services/anonymization'); | ||||
| const consistencyChecksService = require('../../services/consistency_checks'); | ||||
| import sql = require('../../services/sql'); | ||||
| import log = require('../../services/log'); | ||||
| import backupService = require('../../services/backup'); | ||||
| import anonymizationService = require('../../services/anonymization'); | ||||
| import consistencyChecksService = require('../../services/consistency_checks'); | ||||
| import { Request } from 'express'; | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| 
 | ||||
| function getExistingBackups() { | ||||
|     return backupService.getExistingBackups(); | ||||
| @ -30,7 +32,10 @@ function getExistingAnonymizedDatabases() { | ||||
|     return anonymizationService.getExistingAnonymizedDatabases(); | ||||
| } | ||||
| 
 | ||||
| async function anonymize(req) { | ||||
| async function anonymize(req: Request) { | ||||
|     if (req.params.type !== "full" && req.params.type !== "light") { | ||||
|         throw new ValidationError("Invalid type provided."); | ||||
|     } | ||||
|     return await anonymizationService.createAnonymizedCopy(req.params.type); | ||||
| } | ||||
| 
 | ||||
| @ -44,7 +49,7 @@ function checkIntegrity() { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getExistingBackups, | ||||
|     backupDatabase, | ||||
|     vacuumDatabase, | ||||
| @ -1,4 +1,5 @@ | ||||
| const etapiTokenService = require('../../services/etapi_tokens'); | ||||
| import { Request } from 'express'; | ||||
| import etapiTokenService = require('../../services/etapi_tokens'); | ||||
| 
 | ||||
| function getTokens() { | ||||
|     const tokens = etapiTokenService.getTokens(); | ||||
| @ -8,19 +9,19 @@ function getTokens() { | ||||
|     return tokens; | ||||
| } | ||||
| 
 | ||||
| function createToken(req) { | ||||
| function createToken(req: Request) { | ||||
|     return etapiTokenService.createToken(req.body.tokenName); | ||||
| } | ||||
| 
 | ||||
| function patchToken(req) { | ||||
| function patchToken(req: Request) { | ||||
|     etapiTokenService.renameToken(req.params.etapiTokenId, req.body.name); | ||||
| } | ||||
| 
 | ||||
| function deleteToken(req) { | ||||
| function deleteToken(req: Request) { | ||||
|     etapiTokenService.deleteToken(req.params.etapiTokenId); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getTokens, | ||||
|     createToken, | ||||
|     patchToken, | ||||
| @ -1,14 +1,16 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const zipExportService = require('../../services/export/zip'); | ||||
| const singleExportService = require('../../services/export/single'); | ||||
| const opmlExportService = require('../../services/export/opml'); | ||||
| const becca = require('../../becca/becca'); | ||||
| const TaskContext = require('../../services/task_context'); | ||||
| const log = require('../../services/log'); | ||||
| const NotFoundError = require('../../errors/not_found_error'); | ||||
| import zipExportService = require('../../services/export/zip'); | ||||
| import singleExportService = require('../../services/export/single'); | ||||
| import opmlExportService = require('../../services/export/opml'); | ||||
| import becca = require('../../becca/becca'); | ||||
| import TaskContext = require('../../services/task_context'); | ||||
| import log = require('../../services/log'); | ||||
| import NotFoundError = require('../../errors/not_found_error'); | ||||
| import { Request, Response } from 'express'; | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| 
 | ||||
| function exportBranch(req, res) { | ||||
| function exportBranch(req: Request, res: Response) { | ||||
|     const {branchId, type, format, version, taskId} = req.params; | ||||
|     const branch = becca.getBranch(branchId); | ||||
| 
 | ||||
| @ -29,6 +31,9 @@ function exportBranch(req, res) { | ||||
|             zipExportService.exportToZip(taskContext, branch, format, res); | ||||
|         } | ||||
|         else if (type === 'single') { | ||||
|             if (format !== "html" && format !== "markdown") { | ||||
|                 throw new ValidationError("Invalid export type."); | ||||
|             } | ||||
|             singleExportService.exportSingleNote(taskContext, branch, format, res); | ||||
|         } | ||||
|         else if (format === 'opml') { | ||||
| @ -38,7 +43,7 @@ function exportBranch(req, res) { | ||||
|             throw new NotFoundError(`Unrecognized export format '${format}'`); | ||||
|         } | ||||
|     } | ||||
|     catch (e) { | ||||
|     catch (e: any) { | ||||
|         const message = `Export failed with following error: '${e.message}'. More details might be in the logs.`; | ||||
|         taskContext.reportError(message); | ||||
| 
 | ||||
| @ -1,21 +1,24 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const protectedSessionService = require('../../services/protected_session'); | ||||
| const utils = require('../../services/utils'); | ||||
| const log = require('../../services/log'); | ||||
| const noteService = require('../../services/notes'); | ||||
| const tmp = require('tmp'); | ||||
| const fs = require('fs'); | ||||
| const { Readable } = require('stream'); | ||||
| const chokidar = require('chokidar'); | ||||
| const ws = require('../../services/ws'); | ||||
| const becca = require('../../becca/becca'); | ||||
| const ValidationError = require('../../errors/validation_error'); | ||||
| import protectedSessionService = require('../../services/protected_session'); | ||||
| import utils = require('../../services/utils'); | ||||
| import log = require('../../services/log'); | ||||
| import noteService = require('../../services/notes'); | ||||
| import tmp = require('tmp'); | ||||
| import fs = require('fs'); | ||||
| import { Readable } from 'stream'; | ||||
| import chokidar = require('chokidar'); | ||||
| import ws = require('../../services/ws'); | ||||
| import becca = require('../../becca/becca'); | ||||
| import ValidationError = require('../../errors/validation_error'); | ||||
| import { Request, Response } from 'express'; | ||||
| import BNote = require('../../becca/entities/bnote'); | ||||
| import BAttachment = require('../../becca/entities/battachment'); | ||||
| 
 | ||||
| function updateFile(req) { | ||||
| function updateFile(req: Request) { | ||||
|     const note = becca.getNoteOrThrow(req.params.noteId); | ||||
| 
 | ||||
|     const file = req.file; | ||||
|     const file = (req as any).file; | ||||
|     note.saveRevision(); | ||||
| 
 | ||||
|     note.mime = file.mimetype.toLowerCase(); | ||||
| @ -32,9 +35,9 @@ function updateFile(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function updateAttachment(req) { | ||||
| function updateAttachment(req: Request) { | ||||
|     const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); | ||||
|     const file = req.file; | ||||
|     const file = (req as any).file; | ||||
| 
 | ||||
|     attachment.getNote().saveRevision(); | ||||
| 
 | ||||
| @ -46,12 +49,7 @@ function updateAttachment(req) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {BNote|BAttachment} noteOrAttachment | ||||
|  * @param res | ||||
|  * @param {boolean} contentDisposition | ||||
|  */ | ||||
| function downloadData(noteOrAttachment, res, contentDisposition) { | ||||
| function downloadData(noteOrAttachment: BNote | BAttachment, res: Response, contentDisposition: boolean) { | ||||
|     if (noteOrAttachment.isProtected && !protectedSessionService.isProtectedSessionAvailable()) { | ||||
|         return res.status(401).send("Protected session not available"); | ||||
|     } | ||||
| @ -68,7 +66,7 @@ function downloadData(noteOrAttachment, res, contentDisposition) { | ||||
|     res.send(noteOrAttachment.getContent()); | ||||
| } | ||||
| 
 | ||||
| function downloadNoteInt(noteId, res, contentDisposition = true) { | ||||
| function downloadNoteInt(noteId: string, res: Response, contentDisposition = true) { | ||||
|     const note = becca.getNote(noteId); | ||||
| 
 | ||||
|     if (!note) { | ||||
| @ -80,7 +78,7 @@ function downloadNoteInt(noteId, res, contentDisposition = true) { | ||||
|     return downloadData(note, res, contentDisposition); | ||||
| } | ||||
| 
 | ||||
| function downloadAttachmentInt(attachmentId, res, contentDisposition = true) { | ||||
| function downloadAttachmentInt(attachmentId: string, res: Response, contentDisposition = true) { | ||||
|     const attachment = becca.getAttachment(attachmentId); | ||||
| 
 | ||||
|     if (!attachment) { | ||||
| @ -92,34 +90,34 @@ function downloadAttachmentInt(attachmentId, res, contentDisposition = true) { | ||||
|     return downloadData(attachment, res, contentDisposition); | ||||
| } | ||||
| 
 | ||||
| const downloadFile = (req, res) => downloadNoteInt(req.params.noteId, res, true); | ||||
| const openFile = (req, res) => downloadNoteInt(req.params.noteId, res, false); | ||||
| const downloadFile = (req: Request, res: Response) => downloadNoteInt(req.params.noteId, res, true); | ||||
| const openFile = (req: Request, res: Response) => downloadNoteInt(req.params.noteId, res, false); | ||||
| 
 | ||||
| const downloadAttachment = (req, res) => downloadAttachmentInt(req.params.attachmentId, res, true); | ||||
| const openAttachment = (req, res) => downloadAttachmentInt(req.params.attachmentId, res, false); | ||||
| const downloadAttachment = (req: Request, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, true); | ||||
| const openAttachment = (req: Request, res: Response) => downloadAttachmentInt(req.params.attachmentId, res, false); | ||||
| 
 | ||||
| function fileContentProvider(req) { | ||||
| function fileContentProvider(req: Request) { | ||||
|     // Read the file name from route params.
 | ||||
|     const note = becca.getNoteOrThrow(req.params.noteId); | ||||
| 
 | ||||
|     return streamContent(note.getContent(), note.getFileName(), note.mime); | ||||
| } | ||||
| 
 | ||||
| function attachmentContentProvider(req) { | ||||
| function attachmentContentProvider(req: Request) { | ||||
|     // Read the file name from route params.
 | ||||
|     const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); | ||||
| 
 | ||||
|     return streamContent(attachment.getContent(), attachment.getFileName(), attachment.mime); | ||||
| } | ||||
| 
 | ||||
| function streamContent(content, fileName, mimeType) { | ||||
| function streamContent(content: string | Buffer, fileName: string, mimeType: string) { | ||||
|     if (typeof content === "string") { | ||||
|         content = Buffer.from(content, 'utf8'); | ||||
|     } | ||||
| 
 | ||||
|     const totalSize = content.byteLength; | ||||
| 
 | ||||
|     const getStream = range => { | ||||
|     const getStream = (range: { start: number, end: number }) => { | ||||
|         if (!range) { | ||||
|             // Request if for complete content.
 | ||||
|             return Readable.from(content); | ||||
| @ -138,7 +136,7 @@ function streamContent(content, fileName, mimeType) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function saveNoteToTmpDir(req) { | ||||
| function saveNoteToTmpDir(req: Request) { | ||||
|     const note = becca.getNoteOrThrow(req.params.noteId); | ||||
|     const fileName = note.getFileName(); | ||||
|     const content = note.getContent(); | ||||
| @ -146,18 +144,26 @@ function saveNoteToTmpDir(req) { | ||||
|     return saveToTmpDir(fileName, content, 'notes', note.noteId); | ||||
| } | ||||
| 
 | ||||
| function saveAttachmentToTmpDir(req) { | ||||
| function saveAttachmentToTmpDir(req: Request) { | ||||
|     const attachment = becca.getAttachmentOrThrow(req.params.attachmentId); | ||||
|     const fileName = attachment.getFileName(); | ||||
|     const content = attachment.getContent(); | ||||
| 
 | ||||
|     if (!attachment.attachmentId) { | ||||
|         throw new ValidationError("Missing attachment ID."); | ||||
|     } | ||||
|     return saveToTmpDir(fileName, content, 'attachments', attachment.attachmentId); | ||||
| } | ||||
| 
 | ||||
| function saveToTmpDir(fileName, content, entityType, entityId) { | ||||
| function saveToTmpDir(fileName: string, content: string | Buffer, entityType: string, entityId: string) { | ||||
|     const tmpObj = tmp.fileSync({ postfix: fileName }); | ||||
| 
 | ||||
|     fs.writeSync(tmpObj.fd, content); | ||||
|     if (typeof content === "string") { | ||||
|         fs.writeSync(tmpObj.fd, content); | ||||
|     } else { | ||||
|         fs.writeSync(tmpObj.fd, content);    | ||||
|     } | ||||
| 
 | ||||
|     fs.closeSync(tmpObj.fd); | ||||
| 
 | ||||
|     log.info(`Saved temporary file ${tmpObj.name}`); | ||||
| @ -168,7 +174,7 @@ function saveToTmpDir(fileName, content, entityType, entityId) { | ||||
|                 type: 'openedFileUpdated', | ||||
|                 entityType: entityType, | ||||
|                 entityId: entityId, | ||||
|                 lastModifiedMs: stats.atimeMs, | ||||
|                 lastModifiedMs: stats?.atimeMs, | ||||
|                 filePath: tmpObj.name | ||||
|             }); | ||||
|         }); | ||||
| @ -179,7 +185,7 @@ function saveToTmpDir(fileName, content, entityType, entityId) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function uploadModifiedFileToNote(req) { | ||||
| function uploadModifiedFileToNote(req: Request) { | ||||
|     const noteId = req.params.noteId; | ||||
|     const {filePath} = req.body; | ||||
| 
 | ||||
| @ -198,7 +204,7 @@ function uploadModifiedFileToNote(req) { | ||||
|     note.setContent(fileContent); | ||||
| } | ||||
| 
 | ||||
| function uploadModifiedFileToAttachment(req) { | ||||
| function uploadModifiedFileToAttachment(req: Request) { | ||||
|     const {attachmentId} = req.params; | ||||
|     const {filePath} = req.body; | ||||
| 
 | ||||
| @ -217,7 +223,7 @@ function uploadModifiedFileToAttachment(req) { | ||||
|     attachment.setContent(fileContent); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     updateFile, | ||||
|     updateAttachment, | ||||
|     openFile, | ||||
| @ -1,6 +1,7 @@ | ||||
| const optionService = require('../../services/options'); | ||||
| import { Request, Response } from 'express'; | ||||
| import optionService = require('../../services/options'); | ||||
| 
 | ||||
| function getFontCss(req, res) { | ||||
| function getFontCss(req: Request, res: Response) { | ||||
|     res.setHeader('Content-Type', 'text/css'); | ||||
| 
 | ||||
|     if (!optionService.getOptionBool('overrideThemeFonts')) { | ||||
| @ -34,6 +35,6 @@ function getFontCss(req, res) { | ||||
|     res.send(style); | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     getFontCss | ||||
| }; | ||||
| @ -1,5 +1,5 @@ | ||||
| const log = require('../services/log'); | ||||
| const fileService = require('./api/files.js'); | ||||
| const fileService = require('./api/files'); | ||||
| const scriptService = require('../services/script'); | ||||
| const cls = require('../services/cls'); | ||||
| const sql = require('../services/sql'); | ||||
|  | ||||
| @ -24,9 +24,9 @@ const indexRoute = require('./index.js'); | ||||
| // API routes
 | ||||
| const treeApiRoute = require('./api/tree.js'); | ||||
| const notesApiRoute = require('./api/notes.js'); | ||||
| const branchesApiRoute = require('./api/branches.js'); | ||||
| const attachmentsApiRoute = require('./api/attachments.js'); | ||||
| const autocompleteApiRoute = require('./api/autocomplete.js'); | ||||
| const branchesApiRoute = require('./api/branches'); | ||||
| const attachmentsApiRoute = require('./api/attachments'); | ||||
| const autocompleteApiRoute = require('./api/autocomplete'); | ||||
| const cloningApiRoute = require('./api/cloning'); | ||||
| const revisionsApiRoute = require('./api/revisions'); | ||||
| const recentChangesApiRoute = require('./api/recent_changes.js'); | ||||
| @ -36,26 +36,26 @@ const syncApiRoute = require('./api/sync'); | ||||
| const loginApiRoute = require('./api/login.js'); | ||||
| const recentNotesRoute = require('./api/recent_notes.js'); | ||||
| const appInfoRoute = require('./api/app_info'); | ||||
| const exportRoute = require('./api/export.js'); | ||||
| const exportRoute = require('./api/export'); | ||||
| const importRoute = require('./api/import.js'); | ||||
| const setupApiRoute = require('./api/setup.js'); | ||||
| const sqlRoute = require('./api/sql'); | ||||
| const databaseRoute = require('./api/database.js'); | ||||
| const databaseRoute = require('./api/database'); | ||||
| const imageRoute = require('./api/image'); | ||||
| const attributesRoute = require('./api/attributes'); | ||||
| const scriptRoute = require('./api/script.js'); | ||||
| const senderRoute = require('./api/sender.js'); | ||||
| const filesRoute = require('./api/files.js'); | ||||
| const filesRoute = require('./api/files'); | ||||
| const searchRoute = require('./api/search'); | ||||
| const bulkActionRoute = require('./api/bulk_action.js'); | ||||
| const bulkActionRoute = require('./api/bulk_action'); | ||||
| const specialNotesRoute = require('./api/special_notes'); | ||||
| const noteMapRoute = require('./api/note_map.js'); | ||||
| const clipperRoute = require('./api/clipper.js'); | ||||
| const clipperRoute = require('./api/clipper'); | ||||
| const similarNotesRoute = require('./api/similar_notes.js'); | ||||
| const keysRoute = require('./api/keys.js'); | ||||
| const backendLogRoute = require('./api/backend_log.js'); | ||||
| const backendLogRoute = require('./api/backend_log'); | ||||
| const statsRoute = require('./api/stats.js'); | ||||
| const fontsRoute = require('./api/fonts.js'); | ||||
| const fontsRoute = require('./api/fonts'); | ||||
| const etapiTokensApiRoutes = require('./api/etapi_tokens'); | ||||
| const relationMapApiRoute = require('./api/relation-map'); | ||||
| const otherRoute = require('./api/other.js'); | ||||
|  | ||||
| @ -80,7 +80,6 @@ interface Api { | ||||
|      | ||||
|     /** | ||||
|      * Axios library for HTTP requests. See {@link https://axios-http.com} for documentation
 | ||||
|      * @type {axios} | ||||
|      * @deprecated use native (browser compatible) fetch() instead | ||||
|      */ | ||||
|     axios: typeof axios; | ||||
| @ -122,9 +121,6 @@ interface Api { | ||||
|     /** | ||||
|      * This is a powerful search method - you can search by attributes and their values, e.g.: | ||||
|      * "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options
 | ||||
|      * | ||||
|      * @param {string} query | ||||
|      * @param {Object} [searchParams] | ||||
|      */ | ||||
|     searchForNote(query: string, searchParams: SearchParams): BNote | null; | ||||
|      | ||||
|  | ||||
| @ -4,7 +4,8 @@ import protectedSessionService = require('./protected_session'); | ||||
| import utils = require('./utils'); | ||||
| import type { Blob } from "./blob-interface"; | ||||
| 
 | ||||
| function getBlobPojo(entityName: string, entityId: string) { | ||||
| function getBlobPojo(entityName: string, entityId: string, opts?: { preview: boolean }) { | ||||
|     // TODO: Unused opts.
 | ||||
|     const entity = becca.getEntity(entityName, entityId); | ||||
|     if (!entity) { | ||||
|         throw new NotFoundError(`Entity ${entityName} '${entityId}' was not found.`); | ||||
|  | ||||
| @ -27,7 +27,8 @@ function moveBranchToNote(branchToMove: BBranch, targetParentNoteId: string) { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| function moveBranchToBranch(branchToMove: BBranch, targetParentBranch: BBranch) { | ||||
| function moveBranchToBranch(branchToMove: BBranch, targetParentBranch: BBranch, branchId: string) { | ||||
|     // TODO: Unused branch ID argument.
 | ||||
|     const res = moveBranchToNote(branchToMove, targetParentBranch.noteId); | ||||
| 
 | ||||
|     if (!("success" in res) || !res.success) { | ||||
|  | ||||
| @ -150,7 +150,7 @@ function getActions(note: BNote) { | ||||
|         .filter(a => !!a); | ||||
| } | ||||
| 
 | ||||
| function executeActions(note: BNote, searchResultNoteIds: string[]) { | ||||
| function executeActions(note: BNote, searchResultNoteIds: string[] | Set<string>) { | ||||
|     const actions = getActions(note); | ||||
| 
 | ||||
|     for (const resultNoteId of searchResultNoteIds) { | ||||
|  | ||||
| @ -58,7 +58,7 @@ function cloneNoteToBranch(noteId: string, parentBranchId: string, prefix: strin | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| function ensureNoteIsPresentInParent(noteId: string, parentNoteId: string, prefix: string) { | ||||
| function ensureNoteIsPresentInParent(noteId: string, parentNoteId: string, prefix?: string) { | ||||
|     if (!(noteId in becca.notes)) { | ||||
|         return { branch: null, success: false, message: `Note '${noteId}' is deleted.` }; | ||||
|     } else if (!(parentNoteId in becca.notes)) { | ||||
| @ -109,7 +109,7 @@ function ensureNoteIsAbsentFromParent(noteId: string, parentNoteId: string) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function toggleNoteInParent(present: boolean, noteId: string, parentNoteId: string, prefix: string) { | ||||
| function toggleNoteInParent(present: boolean, noteId: string, parentNoteId: string, prefix?: string) { | ||||
|     if (present) { | ||||
|         return ensureNoteIsPresentInParent(noteId, parentNoteId, prefix); | ||||
|     } | ||||
|  | ||||
| @ -913,7 +913,7 @@ sqlInit.dbReady.then(() => { | ||||
|     setTimeout(cls.wrap(runPeriodicChecks), 4 * 1000); | ||||
| }); | ||||
| 
 | ||||
| module.exports = { | ||||
| export = { | ||||
|     runOnDemandChecks, | ||||
|     runEntityChangesChecks | ||||
| }; | ||||
|  | ||||
| @ -49,8 +49,12 @@ interface Message { | ||||
|     messages?: string[]; | ||||
|     startNoteId?: string; | ||||
|     currentNoteId?: string; | ||||
|     entityType?: string; | ||||
|     entityId?: string; | ||||
|     originEntityName?: "notes"; | ||||
|     originEntityId?: string | null; | ||||
|     lastModifiedMs?: number; | ||||
|     filePath?: string; | ||||
| } | ||||
| 
 | ||||
| type SessionParser = (req: IncomingMessage, params: {}, cb: () => void) => void; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran