server-ts: Fix more errors in becca entities

This commit is contained in:
Elian Doran 2024-02-17 11:13:53 +02:00
parent 9aec3390dd
commit 3a20bef1a9
No known key found for this signature in database
9 changed files with 49 additions and 47 deletions

View File

@ -273,7 +273,7 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> {
* *
* This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead. * 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<T>); const constructorData = (this.constructor as unknown as ConstructorData<T>);
const entityId = (this as any)[constructorData.primaryKeyName]; const entityId = (this as any)[constructorData.primaryKeyName];
const entityName = constructorData.entityName; const entityName = constructorData.entityName;

View File

@ -36,7 +36,7 @@ class BAttachment extends AbstractBeccaEntity<BAttachment> {
noteId?: number; noteId?: number;
attachmentId?: string; attachmentId?: string;
/** either noteId or revisionId to which this attachment belongs */ /** either noteId or revisionId to which this attachment belongs */
ownerId: string; ownerId?: string;
role: string; role: string;
mime: string; mime: string;
title: string; title: string;

View File

@ -7,6 +7,10 @@ import promotedAttributeDefinitionParser = require('../../services/promoted_attr
import sanitizeAttributeName = require('../../services/sanitize_attribute_name'); import sanitizeAttributeName = require('../../services/sanitize_attribute_name');
import { AttributeRow, AttributeType } from './rows.js'; import { AttributeRow, AttributeType } from './rows.js';
interface SavingOpts {
skipValidation?: boolean;
}
/** /**
* Attribute is an abstract concept which has two real uses - label (key - value pair) * Attribute is an abstract concept which has two real uses - label (key - value pair)
* and relation (representing named relationship between source and target note) * and relation (representing named relationship between source and target note)
@ -174,7 +178,7 @@ class BAttribute extends AbstractBeccaEntity<BAttribute> {
return !(this.attributeId in this.becca.attributes); return !(this.attributeId in this.becca.attributes);
} }
beforeSaving(opts = {}) { beforeSaving(opts: SavingOpts = {}) {
if (!opts.skipValidation) { if (!opts.skipValidation) {
this.validate(); this.validate();
} }

View File

@ -83,7 +83,7 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
} }
const parentNote = this.parentNote; const parentNote = this.parentNote;
if (parentNote) {
if (!childNote.parents.includes(parentNote)) { if (!childNote.parents.includes(parentNote)) {
childNote.parents.push(parentNote); childNote.parents.push(parentNote);
} }
@ -92,9 +92,9 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
parentNote.children.push(childNote); parentNote.children.push(childNote);
} }
} }
}
/** @returns {BNote} */ get childNote(): BNote {
get childNote() {
if (!(this.noteId in this.becca.notes)) { if (!(this.noteId in this.becca.notes)) {
// entities can come out of order in sync/import, create skeleton which will be filled later // 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})); this.becca.addNote(this.noteId, new BNote({noteId: this.noteId}));
@ -103,13 +103,12 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
return this.becca.notes[this.noteId]; return this.becca.notes[this.noteId];
} }
/** @returns {BNote} */ getNote(): BNote {
getNote() {
return this.childNote; return this.childNote;
} }
/** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */ /** @returns root branch will have undefined parent, all other branches have to have a parent note */
get parentNote() { get parentNote(): BNote | undefined {
if (!(this.parentNoteId in this.becca.notes) && this.parentNoteId !== 'none') { 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 // 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})); this.becca.addNote(this.parentNoteId, new BNote({noteId: this.parentNoteId}));
@ -119,7 +118,7 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
} }
get isDeleted() { get isDeleted() {
return !(this.branchId in this.becca.branches); return (this.branchId == undefined || !(this.branchId in this.becca.branches));
} }
/** /**

View File

@ -64,15 +64,16 @@ class BNote extends AbstractBeccaEntity<BNote> {
isBeingDeleted!: boolean; isBeingDeleted!: boolean;
isDecrypted!: boolean; isDecrypted!: boolean;
ownedAttributes!: BAttribute[];
parentBranches!: BBranch[];
parents!: BNote[];
children!: BNote[];
targetRelations!: BAttribute[];
private __flatTextCache!: string | null; private __flatTextCache!: string | null;
private parentBranches!: BBranch[];
private parents!: BNote[];
private children!: BNote[];
private ownedAttributes!: BAttribute[];
private __attributeCache!: BAttribute[] | null; private __attributeCache!: BAttribute[] | null;
private __inheritableAttributeCache!: BAttribute[] | null; private __inheritableAttributeCache!: BAttribute[] | null;
private targetRelations!: BAttribute[];
private __ancestorCache!: BNote[] | null; private __ancestorCache!: BNote[] | null;
// following attributes are filled during searching in the database // following attributes are filled during searching in the database
@ -85,7 +86,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
/** number of note revisions for this note */ /** number of note revisions for this note */
private revisionCount!: number | null; private revisionCount!: number | null;
constructor(row: NoteRow) { constructor(row: Partial<NoteRow>) {
super(); super();
if (!row) { if (!row) {
@ -96,7 +97,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
this.init(); this.init();
} }
updateFromRow(row: NoteRow) { updateFromRow(row: Partial<NoteRow>) {
this.update([ this.update([
row.noteId, row.noteId,
row.title, row.title,
@ -215,17 +216,15 @@ class BNote extends AbstractBeccaEntity<BNote> {
* - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and entity changes records) * - 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) * - 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)
*/ */
// FIXME: original declaration was (string | Buffer), but everywhere it's used as a string.
/** @returns {string|Buffer} */ getContent(): string {
getContent() { return this._getContent() as string;
return this._getContent();
} }
/** /**
* @returns {*}
* @throws Error in case of invalid JSON */ * @throws Error in case of invalid JSON */
getJsonContent() { getJsonContent(): {} | null {
const content = this.getContent() as string; const content = this.getContent();
if (!content || !content.trim()) { if (!content || !content.trim()) {
return null; return null;
@ -1496,7 +1495,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
return null; return null;
} }
const content = this.getContent() as string; const content = this.getContent();
const parentNote = this.getParentNotes()[0]; const parentNote = this.getParentNotes()[0];
const attachment = parentNote.saveAttachment({ const attachment = parentNote.saveAttachment({
@ -1506,7 +1505,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
content: content content: content
}); });
let parentContent = parentNote.getContent() as string; let parentContent = parentNote.getContent();
const oldNoteUrl = `api/images/${this.noteId}/`; const oldNoteUrl = `api/images/${this.noteId}/`;
const newAttachmentUrl = `api/attachments/${attachment.attachmentId}/image/`; const newAttachmentUrl = `api/attachments/${attachment.attachmentId}/image/`;
@ -1584,7 +1583,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
*/ */
saveRevision() { saveRevision() {
return sql.transactional(() => { return sql.transactional(() => {
let noteContent = this.getContent() as string; let noteContent = this.getContent();
const revision = new BRevision({ const revision = new BRevision({
noteId: this.noteId, noteId: this.noteId,

View File

@ -7,7 +7,7 @@ import { OptionRow } from './rows';
/** /**
* Option represents a name-value pair, either directly configurable by the user or some system property. * Option represents a name-value pair, either directly configurable by the user or some system property.
*/ */
class BOption extends AbstractBeccaEntity { class BOption extends AbstractBeccaEntity<BOption> {
static get entityName() { return "options"; } static get entityName() { return "options"; }
static get primaryKeyName() { return "name"; } static get primaryKeyName() { return "name"; }
static get hashedProperties() { return ["name", "value"]; } static get hashedProperties() { return ["name", "value"]; }

View File

@ -7,10 +7,8 @@ import AbstractBeccaEntity = require('./abstract_becca_entity.js');
/** /**
* RecentNote represents recently visited note. * RecentNote represents recently visited note.
*
* @extends AbstractBeccaEntity
*/ */
class BRecentNote extends AbstractBeccaEntity { class BRecentNote extends AbstractBeccaEntity<BRecentNote> {
static get entityName() { return "recent_notes"; } static get entityName() { return "recent_notes"; }
static get primaryKeyName() { return "noteId"; } static get primaryKeyName() { return "noteId"; }

View File

@ -28,18 +28,19 @@ class BRevision extends AbstractBeccaEntity<BRevision> {
static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated",
"utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; } "utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; }
revisionId: string; revisionId?: string;
noteId: string; noteId: string;
type: string; type: string;
mime: string; mime: string;
isProtected: boolean; isProtected: boolean;
title: string; title: string;
blobId: string; blobId?: string;
dateLastEdited: string; dateLastEdited?: string;
dateCreated: string; dateCreated: string;
utcDateLastEdited: string; utcDateLastEdited?: string;
utcDateCreated: string; utcDateCreated: string;
contentLength?: number; contentLength?: number;
content?: string;
constructor(row: RevisionRow, titleDecrypted = false) { constructor(row: RevisionRow, titleDecrypted = false) {
super(); super();
@ -68,8 +69,8 @@ class BRevision extends AbstractBeccaEntity<BRevision> {
return becca.notes[this.noteId]; return becca.notes[this.noteId];
} }
/** @returns {boolean} true if the note has string content (not binary) */ /** @returns true if the note has string content (not binary) */
hasStringContent() { hasStringContent(): boolean {
return utils.isStringNote(this.type, this.mime); return utils.isStringNote(this.type, this.mime);
} }
@ -87,8 +88,9 @@ class BRevision extends AbstractBeccaEntity<BRevision> {
* *
* This is the same approach as is used for Note's content. * This is the same approach as is used for Note's content.
*/ */
getContent(): string | Buffer { // FIXME: initial declaration included Buffer, but everywhere it's treated as a string.
return this._getContent(); getContent(): string {
return this._getContent() as string;
} }
/** /**

View File

@ -93,7 +93,7 @@ function getOptionMap() {
return map; return map;
} }
module.exports = { export = {
getOption, getOption,
getOptionInt, getOptionInt,
getOptionBool, getOptionBool,