refactoring of note creation APIs WIP

This commit is contained in:
zadam 2019-11-16 11:09:52 +01:00
parent de02e9e889
commit 13c0411533
13 changed files with 115 additions and 107 deletions

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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(" ");

View File

@ -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'

View File

@ -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();

View File

@ -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

View File

@ -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,

View File

@ -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>`;

View File

@ -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();

View File

@ -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(),

View File

@ -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,

View File

@ -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,

View File

@ -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}`);