diff --git a/src/becca/entities/abstract_becca_entity.ts b/src/becca/entities/abstract_becca_entity.ts index 50e76a212..1505a8830 100644 --- a/src/becca/entities/abstract_becca_entity.ts +++ b/src/becca/entities/abstract_becca_entity.ts @@ -273,7 +273,7 @@ abstract class AbstractBeccaEntity> { * * This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead. */ - markAsDeleted(deleteId = null) { + markAsDeleted(deleteId: string | null = null) { const constructorData = (this.constructor as unknown as ConstructorData); const entityId = (this as any)[constructorData.primaryKeyName]; const entityName = constructorData.entityName; diff --git a/src/becca/entities/battachment.ts b/src/becca/entities/battachment.ts index 728ee5e14..d2d0b8498 100644 --- a/src/becca/entities/battachment.ts +++ b/src/becca/entities/battachment.ts @@ -36,7 +36,7 @@ class BAttachment extends AbstractBeccaEntity { noteId?: number; attachmentId?: string; /** either noteId or revisionId to which this attachment belongs */ - ownerId: string; + ownerId?: string; role: string; mime: string; title: string; diff --git a/src/becca/entities/battribute.ts b/src/becca/entities/battribute.ts index 5afea9fdb..15e6ea911 100644 --- a/src/becca/entities/battribute.ts +++ b/src/becca/entities/battribute.ts @@ -7,6 +7,10 @@ import promotedAttributeDefinitionParser = require('../../services/promoted_attr import sanitizeAttributeName = require('../../services/sanitize_attribute_name'); import { AttributeRow, AttributeType } from './rows.js'; +interface SavingOpts { + skipValidation?: boolean; +} + /** * Attribute is an abstract concept which has two real uses - label (key - value pair) * and relation (representing named relationship between source and target note) @@ -174,7 +178,7 @@ class BAttribute extends AbstractBeccaEntity { return !(this.attributeId in this.becca.attributes); } - beforeSaving(opts = {}) { + beforeSaving(opts: SavingOpts = {}) { if (!opts.skipValidation) { this.validate(); } diff --git a/src/becca/entities/bbranch.ts b/src/becca/entities/bbranch.ts index 8892166c4..6c767197e 100644 --- a/src/becca/entities/bbranch.ts +++ b/src/becca/entities/bbranch.ts @@ -83,18 +83,18 @@ class BBranch extends AbstractBeccaEntity { } const parentNote = this.parentNote; - - if (!childNote.parents.includes(parentNote)) { - childNote.parents.push(parentNote); - } - - if (!parentNote.children.includes(childNote)) { - parentNote.children.push(childNote); + if (parentNote) { + if (!childNote.parents.includes(parentNote)) { + childNote.parents.push(parentNote); + } + + if (!parentNote.children.includes(childNote)) { + parentNote.children.push(childNote); + } } } - /** @returns {BNote} */ - get childNote() { + get childNote(): BNote { if (!(this.noteId in this.becca.notes)) { // entities can come out of order in sync/import, create skeleton which will be filled later this.becca.addNote(this.noteId, new BNote({noteId: this.noteId})); @@ -103,13 +103,12 @@ class BBranch extends AbstractBeccaEntity { return this.becca.notes[this.noteId]; } - /** @returns {BNote} */ - getNote() { + getNote(): BNote { return this.childNote; } - /** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */ - get parentNote() { + /** @returns root branch will have undefined parent, all other branches have to have a parent note */ + get parentNote(): BNote | undefined { if (!(this.parentNoteId in this.becca.notes) && this.parentNoteId !== 'none') { // entities can come out of order in sync/import, create skeleton which will be filled later this.becca.addNote(this.parentNoteId, new BNote({noteId: this.parentNoteId})); @@ -119,7 +118,7 @@ class BBranch extends AbstractBeccaEntity { } get isDeleted() { - return !(this.branchId in this.becca.branches); + return (this.branchId == undefined || !(this.branchId in this.becca.branches)); } /** diff --git a/src/becca/entities/bnote.ts b/src/becca/entities/bnote.ts index 6c7ed6895..232df43f4 100644 --- a/src/becca/entities/bnote.ts +++ b/src/becca/entities/bnote.ts @@ -64,15 +64,16 @@ class BNote extends AbstractBeccaEntity { isBeingDeleted!: boolean; isDecrypted!: boolean; + ownedAttributes!: BAttribute[]; + parentBranches!: BBranch[]; + parents!: BNote[]; + children!: BNote[]; + targetRelations!: BAttribute[]; + private __flatTextCache!: string | null; - private parentBranches!: BBranch[]; - private parents!: BNote[]; - private children!: BNote[]; - private ownedAttributes!: BAttribute[]; private __attributeCache!: BAttribute[] | null; private __inheritableAttributeCache!: BAttribute[] | null; - private targetRelations!: BAttribute[]; private __ancestorCache!: BNote[] | null; // following attributes are filled during searching in the database @@ -85,7 +86,7 @@ class BNote extends AbstractBeccaEntity { /** number of note revisions for this note */ private revisionCount!: number | null; - constructor(row: NoteRow) { + constructor(row: Partial) { super(); if (!row) { @@ -96,7 +97,7 @@ class BNote extends AbstractBeccaEntity { this.init(); } - updateFromRow(row: NoteRow) { + updateFromRow(row: Partial) { this.update([ row.noteId, row.title, @@ -215,17 +216,15 @@ class BNote extends AbstractBeccaEntity { * - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and entity changes records) * - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity) */ - - /** @returns {string|Buffer} */ - getContent() { - return this._getContent(); + // FIXME: original declaration was (string | Buffer), but everywhere it's used as a string. + getContent(): string { + return this._getContent() as string; } /** - * @returns {*} * @throws Error in case of invalid JSON */ - getJsonContent() { - const content = this.getContent() as string; + getJsonContent(): {} | null { + const content = this.getContent(); if (!content || !content.trim()) { return null; @@ -1496,7 +1495,7 @@ class BNote extends AbstractBeccaEntity { return null; } - const content = this.getContent() as string; + const content = this.getContent(); const parentNote = this.getParentNotes()[0]; const attachment = parentNote.saveAttachment({ @@ -1506,7 +1505,7 @@ class BNote extends AbstractBeccaEntity { content: content }); - let parentContent = parentNote.getContent() as string; + let parentContent = parentNote.getContent(); const oldNoteUrl = `api/images/${this.noteId}/`; const newAttachmentUrl = `api/attachments/${attachment.attachmentId}/image/`; @@ -1584,7 +1583,7 @@ class BNote extends AbstractBeccaEntity { */ saveRevision() { return sql.transactional(() => { - let noteContent = this.getContent() as string; + let noteContent = this.getContent(); const revision = new BRevision({ noteId: this.noteId, diff --git a/src/becca/entities/boption.ts b/src/becca/entities/boption.ts index 871e44157..c72a41c11 100644 --- a/src/becca/entities/boption.ts +++ b/src/becca/entities/boption.ts @@ -7,7 +7,7 @@ import { OptionRow } from './rows'; /** * Option represents a name-value pair, either directly configurable by the user or some system property. */ -class BOption extends AbstractBeccaEntity { +class BOption extends AbstractBeccaEntity { static get entityName() { return "options"; } static get primaryKeyName() { return "name"; } static get hashedProperties() { return ["name", "value"]; } diff --git a/src/becca/entities/brecent_note.ts b/src/becca/entities/brecent_note.ts index a6796d0ff..8dbaf533c 100644 --- a/src/becca/entities/brecent_note.ts +++ b/src/becca/entities/brecent_note.ts @@ -7,10 +7,8 @@ import AbstractBeccaEntity = require('./abstract_becca_entity.js'); /** * RecentNote represents recently visited note. - * - * @extends AbstractBeccaEntity */ -class BRecentNote extends AbstractBeccaEntity { +class BRecentNote extends AbstractBeccaEntity { static get entityName() { return "recent_notes"; } static get primaryKeyName() { return "noteId"; } diff --git a/src/becca/entities/brevision.ts b/src/becca/entities/brevision.ts index 90250b876..cabbf5757 100644 --- a/src/becca/entities/brevision.ts +++ b/src/becca/entities/brevision.ts @@ -28,18 +28,19 @@ class BRevision extends AbstractBeccaEntity { static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; } - revisionId: string; + revisionId?: string; noteId: string; type: string; mime: string; isProtected: boolean; title: string; - blobId: string; - dateLastEdited: string; + blobId?: string; + dateLastEdited?: string; dateCreated: string; - utcDateLastEdited: string; + utcDateLastEdited?: string; utcDateCreated: string; contentLength?: number; + content?: string; constructor(row: RevisionRow, titleDecrypted = false) { super(); @@ -68,8 +69,8 @@ class BRevision extends AbstractBeccaEntity { return becca.notes[this.noteId]; } - /** @returns {boolean} true if the note has string content (not binary) */ - hasStringContent() { + /** @returns true if the note has string content (not binary) */ + hasStringContent(): boolean { return utils.isStringNote(this.type, this.mime); } @@ -87,8 +88,9 @@ class BRevision extends AbstractBeccaEntity { * * This is the same approach as is used for Note's content. */ - getContent(): string | Buffer { - return this._getContent(); + // FIXME: initial declaration included Buffer, but everywhere it's treated as a string. + getContent(): string { + return this._getContent() as string; } /** diff --git a/src/services/options.ts b/src/services/options.ts index 41532d74f..a7b5ad475 100644 --- a/src/services/options.ts +++ b/src/services/options.ts @@ -93,7 +93,7 @@ function getOptionMap() { return map; } -module.exports = { +export = { getOption, getOptionInt, getOptionBool,