mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-30 18:05:55 +01:00 
			
		
		
		
	refactoring of note creation APIs WIP
This commit is contained in:
		| @@ -475,7 +475,7 @@ class Note extends Entity { | ||||
|     /** | ||||
|      * @return {Promise<Attribute>} | ||||
|      */ | ||||
|     async createAttribute(type, name, value = "") { | ||||
|     async addAttribute(type, name, value = "") { | ||||
|         const attr = new Attribute({ | ||||
|             noteId: this.noteId, | ||||
|             type: type, | ||||
| @@ -490,12 +490,12 @@ class Note extends Entity { | ||||
|         return attr; | ||||
|     } | ||||
|  | ||||
|     async createLabel(name, value = "") { | ||||
|         return await this.createAttribute(LABEL, name, value); | ||||
|     async addLabel(name, value = "") { | ||||
|         return await this.addAttribute(LABEL, name, value); | ||||
|     } | ||||
|  | ||||
|     async createRelation(name, targetNoteId) { | ||||
|         return await this.createAttribute(RELATION, name, targetNoteId); | ||||
|     async addRelation(name, targetNoteId) { | ||||
|         return await this.addAttribute(RELATION, name, targetNoteId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -31,7 +31,11 @@ async function addClipping(req) { | ||||
|     let clippingNote = await findClippingNote(todayNote, pageUrl); | ||||
|  | ||||
|     if (!clippingNote) { | ||||
|         clippingNote = (await noteService.createNote(todayNote.noteId, title, '')).note; | ||||
|         clippingNote = (await noteService.createNewNote({ | ||||
|             parentNoteId: todayNote.noteId, | ||||
|             title: title, | ||||
|             content: '' | ||||
|         })).note; | ||||
|  | ||||
|         await clippingNote.setLabel('clipType', 'clippings'); | ||||
|         await clippingNote.setLabel('pageUrl', pageUrl); | ||||
| @@ -51,7 +55,11 @@ async function createNote(req) { | ||||
|  | ||||
|     const todayNote = await dateNoteService.getDateNote(dateUtils.localNowDate()); | ||||
|  | ||||
|     const {note} = await noteService.createNote(todayNote.noteId, title, content); | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: todayNote.noteId, | ||||
|         title, | ||||
|         content | ||||
|     }); | ||||
|  | ||||
|     await note.setLabel('clipType', clipType); | ||||
|  | ||||
|   | ||||
| @@ -53,10 +53,10 @@ async function getChildren(req) { | ||||
| } | ||||
|  | ||||
| async function createNote(req) { | ||||
|     const parentNoteId = req.params.parentNoteId; | ||||
|     const newNote = req.body; | ||||
|     const params = Object.assign({}, req.body); // clone | ||||
|     params.parentNoteId = req.params.parentNoteId; | ||||
|  | ||||
|     const { note, branch } = await noteService.createNewNote(parentNoteId, newNote, req); | ||||
|     const { note, branch } = await noteService.createNewNote(params); | ||||
|  | ||||
|     note.cssClass = (await note.getLabels("cssClass")).map(label => label.value).join(" "); | ||||
|  | ||||
|   | ||||
| @@ -26,10 +26,10 @@ async function uploadImage(req) { | ||||
| async function saveNote(req) { | ||||
|     const parentNote = await dateNoteService.getDateNote(req.headers['x-local-date']); | ||||
|  | ||||
|     const {note, branch} = await noteService.createNewNote(parentNote.noteId, { | ||||
|     const {note, branch} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title: req.body.title, | ||||
|         content: req.body.content, | ||||
|         target: 'into', | ||||
|         isProtected: false, | ||||
|         type: 'text', | ||||
|         mime: 'text/html' | ||||
|   | ||||
| @@ -178,7 +178,7 @@ function BackendScriptApi(currentNote, apiParams) { | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
|      * @typedef {object} CreateNoteExtraOptions | ||||
|      * @typedef {object} CreateNoteParams | ||||
|      * @property {boolean} [json=false] - should the note be JSON | ||||
|      * @property {boolean} [isProtected=false] - should the note be protected | ||||
|      * @property {string} [type='text'] - note type | ||||
| @@ -189,13 +189,10 @@ function BackendScriptApi(currentNote, apiParams) { | ||||
|     /** | ||||
|      * @method | ||||
|      * | ||||
|      * @param {string} parentNoteId - create new note under this parent | ||||
|      * @param {string} title | ||||
|      * @param {string} [content=""] | ||||
|      * @param {CreateNoteExtraOptions} [extraOptions={}] | ||||
|      * @param {CreateNoteParams} [extraOptions={}] | ||||
|      * @returns {Promise<{note: Note, branch: Branch}>} object contains newly created entities note and branch | ||||
|      */ | ||||
|     this.createNote = noteService.createNote; | ||||
|     this.createNote = noteService.createNewNote; | ||||
|  | ||||
|     /** | ||||
|      * Creates new note according to given params and force all connected clients to refresh their tree. | ||||
| @@ -205,11 +202,11 @@ function BackendScriptApi(currentNote, apiParams) { | ||||
|      * @param {string} parentNoteId - create new note under this parent | ||||
|      * @param {string} title | ||||
|      * @param {string} [content=""] | ||||
|      * @param {CreateNoteExtraOptions} [extraOptions={}] | ||||
|      * @param {CreateNoteParams} [extraOptions={}] | ||||
|      * @returns {Promise<{note: Note, branch: Branch}>} object contains newly created entities note and branch | ||||
|      */ | ||||
|     this.createNoteAndRefresh = async function(parentNoteId, title, content, extraOptions) { | ||||
|         const ret = await noteService.createNote(parentNoteId, title, content, extraOptions); | ||||
|         const ret = await noteService.createNewNote(parentNoteId, title, content, extraOptions); | ||||
|  | ||||
|         ws.refreshTree(); | ||||
|          | ||||
|   | ||||
| @@ -14,10 +14,10 @@ const DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Satur | ||||
| const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December']; | ||||
|  | ||||
| async function createNote(parentNoteId, noteTitle, noteText) { | ||||
|     return (await noteService.createNewNote(parentNoteId, { | ||||
|     return (await noteService.createNewNote({ | ||||
|         parentNoteId: parentNoteId, | ||||
|         title: noteTitle, | ||||
|         content: noteText, | ||||
|         target: 'into', | ||||
|         isProtected: false | ||||
|     })).note; | ||||
| } | ||||
| @@ -35,7 +35,8 @@ async function getRootCalendarNote() { | ||||
|     let rootNote = await attributeService.getNoteWithLabel(CALENDAR_ROOT_LABEL); | ||||
|  | ||||
|     if (!rootNote) { | ||||
|         rootNote = (await noteService.createNewNote('root', { | ||||
|         rootNote = (await noteService.createNewNote({ | ||||
|             parentNoteId: 'root', | ||||
|             title: 'Calendar', | ||||
|             target: 'into', | ||||
|             isProtected: false | ||||
|   | ||||
| @@ -57,14 +57,17 @@ async function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSw | ||||
|  | ||||
|     const parentNote = await repository.getNote(parentNoteId); | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNoteId, fileName, buffer, { | ||||
|         target: 'into', | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId, | ||||
|         title: fileName, | ||||
|         content: buffer, | ||||
|         type: 'image', | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|         mime: 'image/' + imageFormat.ext.toLowerCase(), | ||||
|         attributes: [{ type: 'label', name: 'originalFileName', value: originalName }] | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable() | ||||
|     }); | ||||
|  | ||||
|     await note.addLabel('originalFileName', originalName); | ||||
|  | ||||
|     return { | ||||
|         fileName, | ||||
|         note, | ||||
|   | ||||
| @@ -30,7 +30,10 @@ async function importEnex(taskContext, file, parentNote) { | ||||
|         : file.originalname; | ||||
|  | ||||
|     // root note is new note into all ENEX/notebook's notes will be imported | ||||
|     const rootNote = (await noteService.createNote(parentNote.noteId, rootNoteTitle, "", { | ||||
|     const rootNote = (await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title: rootNoteTitle, | ||||
|         content: "", | ||||
|         type: 'text', | ||||
|         mime: 'text/html', | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
| @@ -207,14 +210,20 @@ async function importEnex(taskContext, file, parentNote) { | ||||
|         // following is workaround for this issue: https://github.com/Leonidas-from-XIV/node-xml2js/issues/484 | ||||
|         content = extractContent(xmlObject['en-note']); | ||||
|  | ||||
|         const noteEntity = (await noteService.createNote(rootNote.noteId, title, content, { | ||||
|             attributes, | ||||
|         const noteEntity = (await noteService.createNewNote({ | ||||
|             parentNoteId: rootNote.noteId, | ||||
|             title, | ||||
|             content, | ||||
|             utcDateCreated, | ||||
|             type: 'text', | ||||
|             mime: 'text/html', | ||||
|             isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|         })).note; | ||||
|  | ||||
|         for (const attr of resource.attributes) { | ||||
|             await note.addAttribute(attr.type, attr.name, attr.value); | ||||
|         } | ||||
|  | ||||
|         taskContext.increaseProgressCount(); | ||||
|  | ||||
|         let noteContent = await noteEntity.getContent(); | ||||
| @@ -231,13 +240,19 @@ async function importEnex(taskContext, file, parentNote) { | ||||
|             } | ||||
|  | ||||
|             const createFileNote = async () => { | ||||
|                 const resourceNote = (await noteService.createNote(noteEntity.noteId, resource.title, resource.content, { | ||||
|                     attributes: resource.attributes, | ||||
|                 const resourceNote = (await noteService.createNewNote({ | ||||
|                     parentNoteId: noteEntity.noteId, | ||||
|                     title: resource.title, | ||||
|                     content: resource.content, | ||||
|                     type: 'file', | ||||
|                     mime: resource.mime, | ||||
|                     isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|                 })).note; | ||||
|  | ||||
|                 for (const attr of resource.attributes) { | ||||
|                     await note.addAttribute(attr.type, attr.name, attr.value); | ||||
|                 } | ||||
|  | ||||
|                 taskContext.increaseProgressCount(); | ||||
|  | ||||
|                 const resourceLink = `<a href="#root/${resourceNote.noteId}">${utils.escapeHtml(resource.title)}</a>`; | ||||
|   | ||||
| @@ -44,8 +44,11 @@ async function importOpml(taskContext, fileBuffer, parentNote) { | ||||
|             throw new Error("Unrecognized OPML version " + opmlVersion); | ||||
|         } | ||||
|  | ||||
|         const {note} = await noteService.createNote(parentNoteId, title, content, { | ||||
|             isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|         const {note} = await noteService.createNewNote({ | ||||
|             parentNoteId, | ||||
|             title, | ||||
|             content, | ||||
|             isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable() | ||||
|         }); | ||||
|  | ||||
|         taskContext.increaseProgressCount(); | ||||
|   | ||||
| @@ -41,16 +41,18 @@ async function importImage(file, parentNote, taskContext) { | ||||
|  | ||||
| async function importFile(taskContext, file, parentNote) { | ||||
|     const originalName = file.originalname; | ||||
|     const size = file.size; | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNote.noteId, originalName, file.buffer, { | ||||
|         target: 'into', | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title: originalName, | ||||
|         content: file.buffer, | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|         type: 'file', | ||||
|         mime: mimeService.getMime(originalName) || file.mimetype, | ||||
|         attributes: [{ type: "label", name: "originalFileName", value: originalName }] | ||||
|         mime: mimeService.getMime(originalName) || file.mimetype | ||||
|     }); | ||||
|  | ||||
|     await note.addLabel("originalFileName", originalName); | ||||
|  | ||||
|     taskContext.increaseProgressCount(); | ||||
|  | ||||
|     return note; | ||||
| @@ -62,7 +64,10 @@ async function importCodeNote(taskContext, file, parentNote) { | ||||
|     const detectedMime = mimeService.getMime(file.originalname) || file.mimetype; | ||||
|     const mime = mimeService.normalizeMimeType(detectedMime); | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNote.noteId, title, content, { | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title, | ||||
|         content, | ||||
|         type: 'code', | ||||
|         mime: mime, | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable() | ||||
| @@ -78,7 +83,10 @@ async function importPlainText(taskContext, file, parentNote) { | ||||
|     const plainTextContent = file.buffer.toString("UTF-8"); | ||||
|     const htmlContent = convertTextToHtml(plainTextContent); | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, { | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title, | ||||
|         content: htmlContent, | ||||
|         type: 'text', | ||||
|         mime: 'text/html', | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
| @@ -118,7 +126,10 @@ async function importMarkdown(taskContext, file, parentNote) { | ||||
|  | ||||
|     const title = getFileNameWithoutExtension(file.originalname); | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, { | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title, | ||||
|         content: htmlContent, | ||||
|         type: 'text', | ||||
|         mime: 'text/html', | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
| @@ -133,7 +144,10 @@ async function importHtml(taskContext, file, parentNote) { | ||||
|     const title = getFileNameWithoutExtension(file.originalname); | ||||
|     const content = file.buffer.toString("UTF-8"); | ||||
|  | ||||
|     const {note} = await noteService.createNote(parentNote.noteId, title, content, { | ||||
|     const {note} = await noteService.createNewNote({ | ||||
|         parentNoteId: parentNote.noteId, | ||||
|         title, | ||||
|         content, | ||||
|         type: 'text', | ||||
|         mime: 'text/html', | ||||
|         isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||
|   | ||||
| @@ -177,8 +177,11 @@ async function importTar(taskContext, fileBuffer, importRootNote) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         ({note} = await noteService.createNote(parentNoteId, noteTitle, '', { | ||||
|             noteId, | ||||
|         ({note} = await noteService.createNewNote({ | ||||
|             parentNoteId: parentNoteId, | ||||
|             title: noteTitle, | ||||
|             content: '', | ||||
|             noteId: noteId, | ||||
|             type: noteMeta ? noteMeta.type : 'text', | ||||
|             mime: noteMeta ? noteMeta.mime : 'text/html', | ||||
|             prefix: noteMeta ? noteMeta.prefix : '', | ||||
| @@ -324,7 +327,10 @@ async function importTar(taskContext, fileBuffer, importRootNote) { | ||||
|             await note.setContent(content); | ||||
|         } | ||||
|         else { | ||||
|             ({note} = await noteService.createNote(parentNoteId, noteTitle, content, { | ||||
|             ({note} = await noteService.createNewNote({ | ||||
|                 parentNoteId: parentNoteId, | ||||
|                 title: noteTitle, | ||||
|                 content: content, | ||||
|                 noteId, | ||||
|                 type, | ||||
|                 mime, | ||||
|   | ||||
| @@ -34,30 +34,24 @@ async function triggerNoteTitleChanged(note) { | ||||
|     await eventService.emit(eventService.NOTE_TITLE_CHANGED, note); | ||||
| } | ||||
|  | ||||
| function deriveTypeAndMime(noteData, parentNote) { | ||||
|     if (!noteData.type) { | ||||
|         if (parentNote.type === 'text' || parentNote.type === 'code') { | ||||
|             noteData.type = parentNote.type; | ||||
|             noteData.mime = parentNote.mime; | ||||
|         } else { | ||||
|             // inheriting note type makes sense only for text and code | ||||
|             noteData.type = 'text'; | ||||
|             noteData.mime = 'text/html'; | ||||
|         } | ||||
| function deriveMime(type, mime) { | ||||
|     if (!type) { | ||||
|         throw new Error(`Note type is a required param`); | ||||
|     } | ||||
|  | ||||
|     if (!noteData.mime) { | ||||
|         if (noteData.type === 'text') { | ||||
|             noteData.mime = 'text/html'; | ||||
|         } else if (noteData.type === 'code') { | ||||
|             noteData.mime = 'text/plain'; | ||||
|         } else if (noteData.type === 'relation-map' || noteData.type === 'search') { | ||||
|             noteData.mime = 'application/json'; | ||||
|         } | ||||
|     if (mime) { | ||||
|         return mime; | ||||
|     } | ||||
|  | ||||
|     noteData.type = noteData.type || parentNote.type; | ||||
|     noteData.mime = noteData.mime || parentNote.mime; | ||||
|     if (type === 'text') { | ||||
|         mime = 'text/html'; | ||||
|     } else if (type === 'code') { | ||||
|         mime = 'text/plain'; | ||||
|     } else if (['relation-map', 'search'].includes(type)) { | ||||
|         mime = 'application/json'; | ||||
|     } | ||||
|  | ||||
|     return mime; | ||||
| } | ||||
|  | ||||
| async function copyChildAttributes(parentNote, childNote) { | ||||
| @@ -92,7 +86,7 @@ async function copyChildAttributes(parentNote, childNote) { | ||||
|  * - {integer} notePosition - default is last existing notePosition in a parent + 10 | ||||
|  * | ||||
|  * @param params | ||||
|  * @return {Promise<{note: Entity, branch: Entity}>} | ||||
|  * @return {Promise<{note: Note, branch: Branch}>} | ||||
|  */ | ||||
| async function createNewNote(params) { | ||||
|     const parentNote = await repository.getNote(params.parentNoteId); | ||||
| @@ -105,14 +99,12 @@ async function createNewNote(params) { | ||||
|         throw new Error(`Note title must not be empty`); | ||||
|     } | ||||
|  | ||||
|     deriveTypeAndMime(params, parentNote); | ||||
|  | ||||
|     const note = await new Note({ | ||||
|         noteId: params.noteId, // optionally can force specific noteId | ||||
|         title: params.title, | ||||
|         isProtected: !!params.isProtected, | ||||
|         type: params.type, | ||||
|         mime: params.mime | ||||
|         mime: deriveMime(params.type, params.mime) | ||||
|     }).save(); | ||||
|  | ||||
|     await note.setContent(params.content); | ||||
| @@ -161,41 +153,6 @@ async function createTextNote(parentNoteId, title, content = "", params = {}) { | ||||
|     return await createNewNote(params); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @deprecated | ||||
|  */ | ||||
| async function createNote(parentNoteId, title, content = "", extraOptions = {}) { | ||||
|     if (!parentNoteId) throw new Error("Empty parentNoteId"); | ||||
|     if (!title) throw new Error("Empty title"); | ||||
|  | ||||
|     const noteData = { | ||||
|         title: title, | ||||
|         content: content, | ||||
|         target: 'into', | ||||
|         noteId: extraOptions.noteId, | ||||
|         isProtected: !!extraOptions.isProtected, | ||||
|         type: extraOptions.type, | ||||
|         mime: extraOptions.mime, | ||||
|         dateCreated: extraOptions.dateCreated, | ||||
|         isExpanded: extraOptions.isExpanded, | ||||
|         notePosition: extraOptions.notePosition | ||||
|     }; | ||||
|  | ||||
|     const {note, branch} = await createNewNote(parentNoteId, title, noteData); | ||||
|  | ||||
|     for (const attr of extraOptions.attributes || []) { | ||||
|         await attributeService.createAttribute({ | ||||
|             noteId: note.noteId, | ||||
|             type: attr.type, | ||||
|             name: attr.name, | ||||
|             value: attr.value, | ||||
|             isInheritable: !!attr.isInheritable | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     return {note, branch}; | ||||
| } | ||||
|  | ||||
| async function protectNoteRecursively(note, protect, taskContext) { | ||||
|     await protectNote(note, protect); | ||||
|  | ||||
| @@ -555,7 +512,6 @@ sqlInit.dbReady.then(() => { | ||||
|  | ||||
| module.exports = { | ||||
|     createNewNote, | ||||
|     createNote, | ||||
|     updateNote, | ||||
|     deleteBranch, | ||||
|     protectNoteRecursively, | ||||
|   | ||||
| @@ -50,7 +50,12 @@ async function start() { | ||||
|         const content = loremIpsum({ count: paragraphCount, units: 'paragraphs', sentenceLowerBound: 1, sentenceUpperBound: 15, | ||||
|             paragraphLowerBound: 3, paragraphUpperBound: 10, format: 'html' }); | ||||
|  | ||||
|         const {note} = await noteService.createNote(getRandomParentNoteId(), title, content); | ||||
|         const {note} = await noteService.createNewNote({ | ||||
|             parentNoteId: getRandomParentNoteId(), | ||||
|             title, | ||||
|             content, | ||||
|             type: 'text' | ||||
|         }); | ||||
|  | ||||
|         console.log(`Created note ${i}: ${title}`); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user