mirror of
https://github.com/zadam/trilium.git
synced 2026-02-06 06:29:19 +01:00
chore(core): integrate date_utils
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
import BNote from "./bnote.js";
|
||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import dateUtils from "../../services/date_utils.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import TaskContext from "../../services/task_context.js";
|
||||
import cls from "../../services/cls.js";
|
||||
import log from "../../services/log.js";
|
||||
|
||||
import type { BranchRow } from "@triliumnext/commons";
|
||||
|
||||
import cls from "../../services/cls.js";
|
||||
import dateUtils from "../../services/date_utils.js";
|
||||
import handlers from "../../services/handlers.js";
|
||||
import log from "../../services/log.js";
|
||||
import TaskContext from "../../services/task_context.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import BNote from "./bnote.js";
|
||||
|
||||
/**
|
||||
* Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
|
||||
@@ -199,9 +200,9 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
|
||||
note.markAsDeleted(deleteId);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
override beforeSaving() {
|
||||
@@ -268,15 +269,15 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
|
||||
existingBranch.notePosition = notePosition;
|
||||
}
|
||||
return existingBranch;
|
||||
} else {
|
||||
return new BBranch({
|
||||
noteId: this.noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
notePosition: notePosition || null,
|
||||
prefix: this.prefix,
|
||||
isExpanded: this.isExpanded
|
||||
});
|
||||
}
|
||||
}
|
||||
return new BBranch({
|
||||
noteId: this.noteId,
|
||||
parentNoteId,
|
||||
notePosition: notePosition || null,
|
||||
prefix: this.prefix,
|
||||
isExpanded: this.isExpanded
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getParentNote() {
|
||||
|
||||
@@ -25,10 +25,6 @@ function getComponentId() {
|
||||
return getContext().get("componentId");
|
||||
}
|
||||
|
||||
function getLocalNowDateTime() {
|
||||
return getContext().get("localNowDateTime");
|
||||
}
|
||||
|
||||
function disableEntityEvents() {
|
||||
getContext().set("disableEntityEvents", true);
|
||||
}
|
||||
@@ -93,7 +89,6 @@ export default {
|
||||
set,
|
||||
getHoistedNoteId,
|
||||
getComponentId,
|
||||
getLocalNowDateTime,
|
||||
disableEntityEvents,
|
||||
enableEntityEvents,
|
||||
isEntityEventsDisabled,
|
||||
|
||||
@@ -1,107 +1,2 @@
|
||||
import { dayjs } from "@triliumnext/commons";
|
||||
import cls from "./cls.js";
|
||||
|
||||
const LOCAL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss.SSSZZ";
|
||||
const UTC_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ssZ";
|
||||
|
||||
function utcNowDateTime() {
|
||||
return utcDateTimeStr(new Date());
|
||||
}
|
||||
|
||||
// CLS date time is important in web deployments - server often runs in different time zone than user is located in,
|
||||
// so we'd prefer client timezone to be used to record local dates. For this reason, requests from clients contain
|
||||
// "trilium-local-now-datetime" header which is then stored in CLS
|
||||
function localNowDateTime() {
|
||||
return cls.getLocalNowDateTime() || dayjs().format(LOCAL_DATETIME_FORMAT);
|
||||
}
|
||||
|
||||
function localNowDate() {
|
||||
const clsDateTime = cls.getLocalNowDateTime();
|
||||
|
||||
if (clsDateTime) {
|
||||
return clsDateTime.substr(0, 10);
|
||||
} else {
|
||||
const date = new Date();
|
||||
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
||||
}
|
||||
}
|
||||
|
||||
function pad(num: number) {
|
||||
return num <= 9 ? `0${num}` : `${num}`;
|
||||
}
|
||||
|
||||
function utcDateStr(date: Date) {
|
||||
return date.toISOString().split("T")[0];
|
||||
}
|
||||
|
||||
function utcDateTimeStr(date: Date) {
|
||||
return date.toISOString().replace("T", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str - needs to be in the ISO 8601 format "YYYY-MM-DDTHH:MM:SS.sssZ" format as outputted by dateStr().
|
||||
* also is assumed to be GMT time (as indicated by the "Z" at the end), *not* local time
|
||||
*/
|
||||
function parseDateTime(str: string) {
|
||||
try {
|
||||
return new Date(Date.parse(str));
|
||||
} catch (e: any) {
|
||||
throw new Error(`Can't parse date from '${str}': ${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseLocalDate(str: string) {
|
||||
const datePart = str.substr(0, 10);
|
||||
|
||||
// not specifying the timezone and specifying the time means Date.parse() will use the local timezone
|
||||
return parseDateTime(`${datePart} 12:00:00.000`);
|
||||
}
|
||||
|
||||
function getDateTimeForFile() {
|
||||
return new Date().toISOString().substr(0, 19).replace(/:/g, "");
|
||||
}
|
||||
|
||||
function validateLocalDateTime(str: string | null | undefined) {
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}[+-][0-9]{4}/.test(str)) {
|
||||
return `Invalid local date time format in '${str}'. Correct format shoud follow example: '2023-08-21 23:38:51.110+0200'`;
|
||||
}
|
||||
|
||||
if (!dayjs(str, LOCAL_DATETIME_FORMAT)) {
|
||||
return `Date '${str}' appears to be in the correct format, but cannot be parsed. It likely represents an invalid date.`;
|
||||
}
|
||||
}
|
||||
|
||||
function validateUtcDateTime(str: string | undefined) {
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z/.test(str)) {
|
||||
return `Invalid UTC date time format in '${str}'. Correct format shoud follow example: '2023-08-21 23:38:51.110Z'`;
|
||||
}
|
||||
|
||||
if (!dayjs(str, UTC_DATETIME_FORMAT)) {
|
||||
return `Date '${str}' appears to be in the correct format, but cannot be parsed. It likely represents an invalid date.`;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
LOCAL_DATETIME_FORMAT,
|
||||
UTC_DATETIME_FORMAT,
|
||||
utcNowDateTime,
|
||||
localNowDateTime,
|
||||
localNowDate,
|
||||
|
||||
utcDateStr,
|
||||
utcDateTimeStr,
|
||||
parseDateTime,
|
||||
parseLocalDate,
|
||||
getDateTimeForFile,
|
||||
validateLocalDateTime,
|
||||
validateUtcDateTime
|
||||
};
|
||||
import { date_utils } from "@triliumnext/core";
|
||||
export default date_utils;
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import sql from "./sql.js";
|
||||
import optionService from "./options.js";
|
||||
import dateUtils from "./date_utils.js";
|
||||
import entityChangesService from "./entity_changes.js";
|
||||
import eventService from "./events.js";
|
||||
import cls from "../services/cls.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import log from "../services/log.js";
|
||||
import { newEntityId, unescapeHtml, quoteRegex, toMap } from "../services/utils.js";
|
||||
import revisionService from "./revisions.js";
|
||||
import request from "./request.js";
|
||||
import type { AttachmentRow, AttributeRow, BranchRow, NoteRow } from "@triliumnext/commons";
|
||||
import { dayjs } from "@triliumnext/commons";
|
||||
import { date_utils } from "@triliumnext/core";
|
||||
import fs from "fs";
|
||||
import html2plaintext from "html2plaintext";
|
||||
import { t } from "i18next";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import becca from "../becca/becca.js";
|
||||
import BAttachment from "../becca/entities/battachment.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import BBranch from "../becca/entities/bbranch.js";
|
||||
import BNote from "../becca/entities/bnote.js";
|
||||
import BAttribute from "../becca/entities/battribute.js";
|
||||
import BAttachment from "../becca/entities/battachment.js";
|
||||
import { dayjs } from "@triliumnext/commons";
|
||||
import htmlSanitizer from "./html_sanitizer.js";
|
||||
import ValidationError from "../errors/validation_error.js";
|
||||
import noteTypesService from "./note_types.js";
|
||||
import fs from "fs";
|
||||
import ws from "./ws.js";
|
||||
import html2plaintext from "html2plaintext";
|
||||
import type { AttachmentRow, AttributeRow, BranchRow, NoteRow } from "@triliumnext/commons";
|
||||
import type TaskContext from "./task_context.js";
|
||||
import type { NoteParams } from "./note-interface.js";
|
||||
import cls from "../services/cls.js";
|
||||
import log from "../services/log.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import { newEntityId, quoteRegex, toMap,unescapeHtml } from "../services/utils.js";
|
||||
import entityChangesService from "./entity_changes.js";
|
||||
import eventService from "./events.js";
|
||||
import htmlSanitizer from "./html_sanitizer.js";
|
||||
import imageService from "./image.js";
|
||||
import { t } from "i18next";
|
||||
import noteTypesService from "./note_types.js";
|
||||
import type { NoteParams } from "./note-interface.js";
|
||||
import optionService from "./options.js";
|
||||
import request from "./request.js";
|
||||
import revisionService from "./revisions.js";
|
||||
import sql from "./sql.js";
|
||||
import type TaskContext from "./task_context.js";
|
||||
import ws from "./ws.js";
|
||||
|
||||
interface FoundLink {
|
||||
name: "imageLink" | "internalLink" | "includeNoteLink" | "relationMapLink";
|
||||
@@ -47,14 +48,14 @@ function getNewNotePosition(parentNote: BNote) {
|
||||
.reduce((min, note) => Math.min(min, note?.notePosition || 0), 0);
|
||||
|
||||
return minNotePos - 10;
|
||||
} else {
|
||||
const maxNotePos = parentNote
|
||||
.getChildBranches()
|
||||
.filter((branch) => branch?.noteId !== "_hidden") // has "always last" note position
|
||||
.reduce((max, note) => Math.max(max, note?.notePosition || 0), 0);
|
||||
|
||||
return maxNotePos + 10;
|
||||
}
|
||||
const maxNotePos = parentNote
|
||||
.getChildBranches()
|
||||
.filter((branch) => branch?.noteId !== "_hidden") // has "always last" note position
|
||||
.reduce((max, note) => Math.max(max, note?.notePosition || 0), 0);
|
||||
|
||||
return maxNotePos + 10;
|
||||
|
||||
}
|
||||
|
||||
function triggerNoteTitleChanged(note: BNote) {
|
||||
@@ -88,7 +89,7 @@ function copyChildAttributes(parentNote: BNote, childNote: BNote) {
|
||||
new BAttribute({
|
||||
noteId: childNote.noteId,
|
||||
type: attr.type,
|
||||
name: name,
|
||||
name,
|
||||
value: attr.value,
|
||||
position: attr.position,
|
||||
isInheritable: attr.isInheritable
|
||||
@@ -121,7 +122,7 @@ function getNewNoteTitle(parentNote: BNote) {
|
||||
|
||||
if (titleTemplate !== null) {
|
||||
try {
|
||||
const now = dayjs(cls.getLocalNowDateTime() || new Date());
|
||||
const now = dayjs(date_utils.localNowDateTime() || new Date());
|
||||
|
||||
// "officially" injected values:
|
||||
// - now
|
||||
@@ -189,11 +190,11 @@ function createNewNote(params: NoteParams): {
|
||||
}
|
||||
|
||||
let error;
|
||||
if ((error = dateUtils.validateLocalDateTime(params.dateCreated))) {
|
||||
if ((error = date_utils.validateLocalDateTime(params.dateCreated))) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
if ((error = dateUtils.validateUtcDateTime(params.utcDateCreated))) {
|
||||
if ((error = date_utils.validateUtcDateTime(params.utcDateCreated))) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
@@ -260,7 +261,7 @@ function createNewNote(params: NoteParams): {
|
||||
eventService.emit(eventService.ENTITY_CHANGED, { entityName: "blobs", entity: note });
|
||||
eventService.emit(eventService.ENTITY_CREATED, { entityName: "branches", entity: branch });
|
||||
eventService.emit(eventService.ENTITY_CHANGED, { entityName: "branches", entity: branch });
|
||||
eventService.emit(eventService.CHILD_NOTE_CREATED, { childNote: note, parentNote: parentNote });
|
||||
eventService.emit(eventService.CHILD_NOTE_CREATED, { childNote: note, parentNote });
|
||||
|
||||
log.info(`Created new note '${note.noteId}', branch '${branch.branchId}' of type '${note.type}', mime '${note.mime}'`);
|
||||
|
||||
@@ -308,9 +309,9 @@ function createNewNoteWithTarget(target: "into" | "after" | "before", targetBran
|
||||
entityChangesService.putNoteReorderingEntityChange(params.parentNoteId);
|
||||
|
||||
return retObject;
|
||||
} else {
|
||||
throw new Error(`Unknown target '${target}'`);
|
||||
}
|
||||
throw new Error(`Unknown target '${target}'`);
|
||||
|
||||
}
|
||||
|
||||
function protectNoteRecursively(note: BNote, protect: boolean, includingSubTree: boolean, taskContext: TaskContext<"protectNotes">) {
|
||||
@@ -384,7 +385,7 @@ function checkImageAttachments(note: BNote, content: string) {
|
||||
attachment.utcDateScheduledForErasureSince = null;
|
||||
attachment.save();
|
||||
} else if (!attachment.utcDateScheduledForErasureSince && !attachmentInContent) {
|
||||
attachment.utcDateScheduledForErasureSince = dateUtils.utcNowDateTime();
|
||||
attachment.utcDateScheduledForErasureSince = date_utils.utcNowDateTime();
|
||||
attachment.save();
|
||||
}
|
||||
}
|
||||
@@ -488,7 +489,7 @@ function findRelationMapLinks(content: string, foundLinks: FoundLink[]) {
|
||||
});
|
||||
}
|
||||
} catch (e: any) {
|
||||
log.error("Could not scan for relation map links: " + e.message);
|
||||
log.error(`Could not scan for relation map links: ${ e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,8 +657,8 @@ function saveAttachments(note: BNote, content: string) {
|
||||
|
||||
const attachment = note.saveAttachment({
|
||||
role: "file",
|
||||
mime: mime,
|
||||
title: title,
|
||||
mime,
|
||||
title,
|
||||
content: buffer
|
||||
});
|
||||
|
||||
@@ -739,11 +740,11 @@ function saveRevisionIfNeeded(note: BNote) {
|
||||
const now = new Date();
|
||||
const revisionSnapshotTimeInterval = parseInt(optionService.getOption("revisionSnapshotTimeInterval"));
|
||||
|
||||
const revisionCutoff = dateUtils.utcDateTimeStr(new Date(now.getTime() - revisionSnapshotTimeInterval * 1000));
|
||||
const revisionCutoff = date_utils.utcDateTimeStr(new Date(now.getTime() - revisionSnapshotTimeInterval * 1000));
|
||||
|
||||
const existingRevisionId = sql.getValue("SELECT revisionId FROM revisions WHERE noteId = ? AND utcDateCreated >= ?", [note.noteId, revisionCutoff]);
|
||||
|
||||
const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.utcDateCreated).getTime();
|
||||
const msSinceDateCreated = now.getTime() - date_utils.parseDateTime(note.utcDateCreated).getTime();
|
||||
|
||||
if (!existingRevisionId && msSinceDateCreated >= revisionSnapshotTimeInterval * 1000) {
|
||||
note.saveRevision();
|
||||
@@ -953,7 +954,7 @@ function duplicateSubtree(origNoteId: string, newParentNoteId: string) {
|
||||
const duplicateNoteSuffix = t("notes.duplicate-note-suffix");
|
||||
|
||||
if (!res.note.title.endsWith(duplicateNoteSuffix) && !res.note.title.startsWith(duplicateNoteSuffix)) {
|
||||
res.note.title = t("notes.duplicate-note-title", { noteTitle: res.note.title, duplicateNoteSuffix: duplicateNoteSuffix });
|
||||
res.note.title = t("notes.duplicate-note-title", { noteTitle: res.note.title, duplicateNoteSuffix });
|
||||
}
|
||||
|
||||
res.note.save();
|
||||
@@ -999,8 +1000,8 @@ function duplicateSubtreeInner(origNote: BNote, origBranch: BBranch | null | und
|
||||
const newNote = new BNote({
|
||||
...origNote,
|
||||
noteId: newNoteId,
|
||||
dateCreated: dateUtils.localNowDateTime(),
|
||||
utcDateCreated: dateUtils.utcNowDateTime()
|
||||
dateCreated: date_utils.localNowDateTime(),
|
||||
utcDateCreated: date_utils.utcNowDateTime()
|
||||
}).save();
|
||||
|
||||
let content = origNote.getContent();
|
||||
@@ -1050,13 +1051,13 @@ function duplicateSubtreeInner(origNote: BNote, origBranch: BBranch | null | und
|
||||
note: existingNote,
|
||||
branch: createDuplicatedBranch()
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
// order here is important, note needs to be created first to not mess up the becca
|
||||
note: createDuplicatedNote(),
|
||||
branch: createDuplicatedBranch()
|
||||
};
|
||||
}
|
||||
return {
|
||||
// order here is important, note needs to be created first to not mess up the becca
|
||||
note: createDuplicatedNote(),
|
||||
branch: createDuplicatedBranch()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function getNoteIdMapping(origNote: BNote) {
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@triliumnext/commons": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ export * from "./services/sql/index";
|
||||
export * as protected_session from "./services/encryption/protected_session";
|
||||
export { default as data_encryption } from "./services/encryption/data_encryption"
|
||||
export * as binary_utils from "./services/utils/binary";
|
||||
export type { ExecutionContext } from "./services/context";
|
||||
export { default as date_utils } from "./services/utils/date";
|
||||
export { getContext, type ExecutionContext } from "./services/context";
|
||||
export type { CryptoProvider } from "./services/encryption/crypto";
|
||||
|
||||
export function initializeCore({ dbConfig, executionContext, crypto }: {
|
||||
|
||||
111
packages/trilium-core/src/services/utils/date.ts
Normal file
111
packages/trilium-core/src/services/utils/date.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { dayjs } from "@triliumnext/commons";
|
||||
import { getContext } from "../context.js";
|
||||
|
||||
const LOCAL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss.SSSZZ";
|
||||
const UTC_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ssZ";
|
||||
|
||||
function utcNowDateTime() {
|
||||
return utcDateTimeStr(new Date());
|
||||
}
|
||||
|
||||
// CLS date time is important in web deployments - server often runs in different time zone than user is located in,
|
||||
// so we'd prefer client timezone to be used to record local dates. For this reason, requests from clients contain
|
||||
// "trilium-local-now-datetime" header which is then stored in CLS
|
||||
function localNowDateTime() {
|
||||
return getLocalNowDateTime() || dayjs().format(LOCAL_DATETIME_FORMAT);
|
||||
}
|
||||
|
||||
function localNowDate() {
|
||||
const clsDateTime = getLocalNowDateTime();
|
||||
|
||||
if (clsDateTime) {
|
||||
return clsDateTime.substr(0, 10);
|
||||
} else {
|
||||
const date = new Date();
|
||||
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
||||
}
|
||||
}
|
||||
|
||||
function pad(num: number) {
|
||||
return num <= 9 ? `0${num}` : `${num}`;
|
||||
}
|
||||
|
||||
function utcDateStr(date: Date) {
|
||||
return date.toISOString().split("T")[0];
|
||||
}
|
||||
|
||||
function utcDateTimeStr(date: Date) {
|
||||
return date.toISOString().replace("T", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str - needs to be in the ISO 8601 format "YYYY-MM-DDTHH:MM:SS.sssZ" format as outputted by dateStr().
|
||||
* also is assumed to be GMT time (as indicated by the "Z" at the end), *not* local time
|
||||
*/
|
||||
function parseDateTime(str: string) {
|
||||
try {
|
||||
return new Date(Date.parse(str));
|
||||
} catch (e: any) {
|
||||
throw new Error(`Can't parse date from '${str}': ${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseLocalDate(str: string) {
|
||||
const datePart = str.substr(0, 10);
|
||||
|
||||
// not specifying the timezone and specifying the time means Date.parse() will use the local timezone
|
||||
return parseDateTime(`${datePart} 12:00:00.000`);
|
||||
}
|
||||
|
||||
function getDateTimeForFile() {
|
||||
return new Date().toISOString().substr(0, 19).replace(/:/g, "");
|
||||
}
|
||||
|
||||
function validateLocalDateTime(str: string | null | undefined) {
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}[+-][0-9]{4}/.test(str)) {
|
||||
return `Invalid local date time format in '${str}'. Correct format shoud follow example: '2023-08-21 23:38:51.110+0200'`;
|
||||
}
|
||||
|
||||
if (!dayjs(str, LOCAL_DATETIME_FORMAT)) {
|
||||
return `Date '${str}' appears to be in the correct format, but cannot be parsed. It likely represents an invalid date.`;
|
||||
}
|
||||
}
|
||||
|
||||
function validateUtcDateTime(str: string | undefined) {
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z/.test(str)) {
|
||||
return `Invalid UTC date time format in '${str}'. Correct format shoud follow example: '2023-08-21 23:38:51.110Z'`;
|
||||
}
|
||||
|
||||
if (!dayjs(str, UTC_DATETIME_FORMAT)) {
|
||||
return `Date '${str}' appears to be in the correct format, but cannot be parsed. It likely represents an invalid date.`;
|
||||
}
|
||||
}
|
||||
|
||||
function getLocalNowDateTime() {
|
||||
return getContext().get("localNowDateTime");
|
||||
}
|
||||
|
||||
export default {
|
||||
LOCAL_DATETIME_FORMAT,
|
||||
UTC_DATETIME_FORMAT,
|
||||
utcNowDateTime,
|
||||
localNowDateTime,
|
||||
localNowDate,
|
||||
|
||||
utcDateStr,
|
||||
utcDateTimeStr,
|
||||
parseDateTime,
|
||||
parseLocalDate,
|
||||
getDateTimeForFile,
|
||||
validateLocalDateTime,
|
||||
validateUtcDateTime
|
||||
};
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -1444,7 +1444,11 @@ importers:
|
||||
specifier: 5.1.0
|
||||
version: 5.1.0(karma@6.4.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))
|
||||
|
||||
packages/trilium-core: {}
|
||||
packages/trilium-core:
|
||||
dependencies:
|
||||
'@triliumnext/commons':
|
||||
specifier: workspace:*
|
||||
version: link:../commons
|
||||
|
||||
packages/turndown-plugin-gfm:
|
||||
devDependencies:
|
||||
@@ -15558,6 +15562,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-utils': 47.3.0
|
||||
ckeditor5: 47.3.0
|
||||
es-toolkit: 1.39.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-editor-classic@47.3.0':
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user