diff --git a/src/entities/note.js b/src/entities/note.js index 233246e90..7a3e89aa4 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -475,7 +475,7 @@ class Note extends Entity { /** * @return {Promise} */ - 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); } /** diff --git a/src/routes/api/clipper.js b/src/routes/api/clipper.js index 9bf806950..0344037a5 100644 --- a/src/routes/api/clipper.js +++ b/src/routes/api/clipper.js @@ -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); diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index c06542111..210776074 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -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(" "); diff --git a/src/routes/api/sender.js b/src/routes/api/sender.js index 06d87d7b4..c60cab4ac 100644 --- a/src/routes/api/sender.js +++ b/src/routes/api/sender.js @@ -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' diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index c430c9f88..505bd9721 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -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(); diff --git a/src/services/date_notes.js b/src/services/date_notes.js index 7887b4b40..270258576 100644 --- a/src/services/date_notes.js +++ b/src/services/date_notes.js @@ -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 diff --git a/src/services/image.js b/src/services/image.js index 34cdb6ec7..21a3c3a3b 100644 --- a/src/services/image.js +++ b/src/services/image.js @@ -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, diff --git a/src/services/import/enex.js b/src/services/import/enex.js index c898498d9..2d9bd57cc 100644 --- a/src/services/import/enex.js +++ b/src/services/import/enex.js @@ -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 = `${utils.escapeHtml(resource.title)}`; diff --git a/src/services/import/opml.js b/src/services/import/opml.js index 3b9e4f852..b4bd1a70b 100644 --- a/src/services/import/opml.js +++ b/src/services/import/opml.js @@ -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(); diff --git a/src/services/import/single.js b/src/services/import/single.js index 18c871fd0..983cca355 100644 --- a/src/services/import/single.js +++ b/src/services/import/single.js @@ -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(), diff --git a/src/services/import/tar.js b/src/services/import/tar.js index b459d8c17..d71a6c55b 100644 --- a/src/services/import/tar.js +++ b/src/services/import/tar.js @@ -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, diff --git a/src/services/notes.js b/src/services/notes.js index f5b225039..4cd3e081d 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -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, diff --git a/src/tools/generate_document.js b/src/tools/generate_document.js index 7c2fb6b1e..bf250ca77 100644 --- a/src/tools/generate_document.js +++ b/src/tools/generate_document.js @@ -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}`);