Merge branch 'feature/server_esm_part2' into feature/server_esm_part3

This commit is contained in:
Elian Doran
2024-07-22 20:20:34 +03:00
56 changed files with 4148 additions and 12626 deletions

View File

@@ -1153,7 +1153,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
.map(row => new BAttachment(row));
}
getAttachmentByTitle(title: string): BAttachment {
getAttachmentByTitle(title: string): BAttachment | undefined {
// cannot use SQL to filter by title since it can be encrypted
return this.getAttachments().filter(attachment => attachment.title === title)[0];
}

View File

@@ -301,7 +301,7 @@ export default class GlobalMenuWidget extends BasicWidget {
}
async fetchLatestVersion() {
const RELEASES_API_URL = "https://api.github.com/repos/zadam/trilium/releases/latest";
const RELEASES_API_URL = "https://api.github.com/repos/TriliumNext/Notes/releases/latest";
const resp = await fetch(RELEASES_API_URL);
const data = await resp.json();

View File

@@ -41,22 +41,20 @@ function returnImageInt(image: BNote | BRevision | null, res: Response) {
}
function renderSvgAttachment(image: BNote | BRevision, res: Response, attachmentName: string) {
let svgString = '<svg/>'
let svg: string | Buffer = '<svg/>'
const attachment = image.getAttachmentByTitle(attachmentName);
const content = attachment.getContent();
if (attachment && typeof content === "string") {
svgString = content;
if (attachment) {
svg = attachment.getContent();
} else {
// backwards compatibility, before attachments, the SVG was stored in the main note content as a separate key
const contentSvg = image.getJsonContentSafely()?.svg;
if (contentSvg) {
svgString = contentSvg;
svg = contentSvg;
}
}
const svg = svgString
res.set('Content-Type', "image/svg+xml");
res.set("Cache-Control", "no-cache, no-store, must-revalidate");
res.send(svg);

View File

@@ -5,7 +5,6 @@ import { JSDOM } from "jsdom";
import BNote from "../../becca/entities/bnote.js";
import BAttribute from "../../becca/entities/battribute.js";
import { Request } from 'express';
import ValidationError from "../../errors/validation_error.js";
function buildDescendantCountMap(noteIdsToCount: string[]) {
if (!Array.isArray(noteIdsToCount)) {

View File

@@ -63,7 +63,7 @@ interface Api {
* Note where the script started executing (entrypoint).
* As an analogy, in C this would be the file which contains the main() function of the current process.
*/
startNote?: BNote;
startNote?: BNote | null;
/**
* Note where the script is currently executing. This comes into play when your script is spread in multiple code
@@ -76,7 +76,7 @@ interface Api {
/**
* Entity whose event triggered this execution
*/
originEntity?: AbstractBeccaEntity<any>;
originEntity?: AbstractBeccaEntity<any> | null;
/**
* Axios library for HTTP requests. See {@link https://axios-http.com} for documentation

View File

@@ -3,8 +3,8 @@ import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js";
import BNote from "../becca/entities/bnote.js";
export interface ApiParams {
startNote?: BNote;
originEntity?: AbstractBeccaEntity<any>;
startNote?: BNote | null;
originEntity?: AbstractBeccaEntity<any> | null;
pathParams?: string[],
req?: Request,
res?: Response

View File

@@ -1 +1,4 @@
export default { buildDate:"2024-07-14T22:32:45+03:00", buildRevision: "b811f3d399aed7e740bd8e92ef7edc7d15de7038" };
export default {
buildDate: "2024-07-21T10:25:01Z",
buildRevision: "715a952148ae6e83fda0886f5ceec8dc329972ae"
};

View File

@@ -95,10 +95,6 @@ function executeScript(script: string, params: ScriptParams, startNoteId: string
throw new Error("Unable to determine script bundle.");
}
if (!startNote || !originEntity) {
throw new Error("Missing start note or origin entity.");
}
return executeBundle(bundle, { startNote, originEntity });
}

View File

@@ -33,11 +33,8 @@ const numericComparators: Record<string, Comparator<number>> = {
function buildComparator(operator: string, comparedValue: string) {
comparedValue = comparedValue.toLowerCase();
if (operator in numericComparators) {
const floatValue = parseFloat(comparedValue);
if (!isNaN(floatValue)) {
return numericComparators[operator](floatValue);
}
if (operator in numericComparators && !isNaN(+comparedValue)) {
return numericComparators[operator](parseFloat(comparedValue));
}
if (operator in stringComparators) {

View File

@@ -41,15 +41,13 @@ function updateEntities(entityChanges: EntityChangeRecord[], instanceId: string)
atLeastOnePullApplied = true;
}
if (entity) {
updateEntity(entityChange, entity, instanceId, updateContext);
}
updateEntity(entityChange, entity, instanceId, updateContext);
}
logUpdateContext(updateContext);
}
function updateEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow, instanceId: string, updateContext: UpdateContext) {
function updateEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow | undefined, instanceId: string, updateContext: UpdateContext) {
if (!remoteEntityRow && remoteEC.entityName === 'options') {
return; // can be undefined for options with isSynced=false
}
@@ -74,14 +72,13 @@ function updateEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow, instan
}
}
function updateNormalEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow, instanceId: string, updateContext: UpdateContext) {
const localEC = sql.getRow<EntityChange>(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [remoteEC.entityName, remoteEC.entityId]);
function updateNormalEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow | undefined, instanceId: string, updateContext: UpdateContext) {
const localEC = sql.getRow<EntityChange | undefined>(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [remoteEC.entityName, remoteEC.entityId]);
const localECIsOlderOrSameAsRemote = (
localEC && localEC.utcDateChanged && remoteEC.utcDateChanged &&
localEC.utcDateChanged <= remoteEC.utcDateChanged);
if (!localEC.utcDateChanged || !remoteEC.utcDateChanged) {
throw new Error("Missing date changed.");
}
if (!localEC || localEC.utcDateChanged <= remoteEC.utcDateChanged) {
if (!localEC || localECIsOlderOrSameAsRemote) {
if (remoteEC.isErased) {
if (localEC?.isErased) {
eraseEntity(remoteEC); // make sure it's erased anyway
@@ -104,7 +101,7 @@ function updateNormalEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow,
}
if (!localEC
|| localEC.utcDateChanged < remoteEC.utcDateChanged
|| localECIsOlderOrSameAsRemote
|| localEC.hash !== remoteEC.hash
|| localEC.isErased !== remoteEC.isErased
) {
@@ -113,7 +110,7 @@ function updateNormalEntity(remoteEC: EntityChange, remoteEntityRow: EntityRow,
return true;
} else if ((localEC.hash !== remoteEC.hash || localEC.isErased !== remoteEC.isErased)
&& localEC.utcDateChanged > remoteEC.utcDateChanged) {
&& !localECIsOlderOrSameAsRemote) {
// the change on our side is newer than on the other side, so the other side should update
entityChangesService.putEntityChangeForOtherInstances(localEC);
@@ -140,7 +137,7 @@ function preProcessContent(remoteEC: EntityChange, remoteEntityRow: EntityRow) {
}
}
function updateNoteReordering(remoteEC: EntityChange, remoteEntityRow: EntityRow, instanceId: string) {
function updateNoteReordering(remoteEC: EntityChange, remoteEntityRow: EntityRow | undefined, instanceId: string) {
if (!remoteEntityRow) {
throw new Error(`Empty note_reordering body for: ${JSON.stringify(remoteEC)}`);
}