diff --git a/docs/backend_api/AbstractBeccaEntity.html b/docs/backend_api/AbstractBeccaEntity.html index ad11edfb0..c520b336a 100644 --- a/docs/backend_api/AbstractBeccaEntity.html +++ b/docs/backend_api/AbstractBeccaEntity.html @@ -90,11 +90,6 @@ - -
Source:
-
@@ -180,11 +175,6 @@ - -
Source:
-
@@ -256,11 +246,6 @@ - -
Source:
-
@@ -340,11 +325,6 @@ - -
Source:
-
@@ -424,11 +404,6 @@ - -
Source:
-
@@ -508,11 +483,6 @@ - -
Source:
-
@@ -592,11 +562,6 @@ - -
Source:
-
@@ -676,11 +641,6 @@ - -
Source:
-
@@ -830,11 +790,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -918,11 +873,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -985,7 +935,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BAttribute.html b/docs/backend_api/BAttribute.html index 8ae4ede4f..a2d37d4c5 100644 --- a/docs/backend_api/BAttribute.html +++ b/docs/backend_api/BAttribute.html @@ -91,11 +91,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -202,11 +197,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -266,11 +256,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -333,11 +318,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -401,11 +381,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -469,11 +444,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -537,11 +507,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -605,11 +570,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -673,11 +633,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -741,11 +696,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -823,11 +773,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -912,11 +857,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -1001,11 +941,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -1090,11 +1025,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -1173,11 +1103,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -1284,11 +1209,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -1367,11 +1287,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -1478,11 +1393,6 @@ and relation (representing named relationship between source and target note)Source: -
- @@ -1561,11 +1471,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -1739,11 +1644,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1832,11 +1732,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1898,7 +1793,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BBranch.html b/docs/backend_api/BBranch.html index 7aea50f32..e12dbf829 100644 --- a/docs/backend_api/BBranch.html +++ b/docs/backend_api/BBranch.html @@ -94,11 +94,6 @@ Always check noteId instead. - -
Source:
-
@@ -201,11 +196,6 @@ Always check noteId instead. -
Source:
-
- @@ -268,11 +258,6 @@ Always check noteId instead. - -
Source:
-
@@ -326,11 +311,6 @@ Always check noteId instead. - -
Source:
-
@@ -394,11 +374,6 @@ Always check noteId instead. - -
Source:
-
@@ -460,11 +435,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -528,11 +498,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -596,11 +561,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -654,11 +614,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -722,11 +677,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -790,11 +740,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -858,11 +803,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -940,11 +880,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1029,11 +964,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1210,11 +1140,6 @@ of deletion should not act as a clone. - -
Source:
-
@@ -1322,11 +1247,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1411,11 +1331,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1500,11 +1415,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1589,11 +1499,6 @@ of deletion should not act as a clone. -
Source:
-
- @@ -1748,11 +1653,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1841,11 +1741,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1907,7 +1802,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BEtapiToken.html b/docs/backend_api/BEtapiToken.html index 3e9bcbe39..3ef744252 100644 --- a/docs/backend_api/BEtapiToken.html +++ b/docs/backend_api/BEtapiToken.html @@ -96,11 +96,6 @@ from tokenHash and token. - -
Source:
-
@@ -203,11 +198,6 @@ from tokenHash and token. -
Source:
-
- @@ -270,11 +260,6 @@ from tokenHash and token. - -
Source:
-
@@ -338,11 +323,6 @@ from tokenHash and token. - -
Source:
-
@@ -406,11 +386,6 @@ from tokenHash and token. - -
Source:
-
@@ -474,11 +449,6 @@ from tokenHash and token. - -
Source:
-
@@ -542,11 +512,6 @@ from tokenHash and token. - -
Source:
-
@@ -610,11 +575,6 @@ from tokenHash and token. - -
Source:
-
@@ -692,11 +652,6 @@ from tokenHash and token. -
Source:
-
- @@ -781,11 +736,6 @@ from tokenHash and token. -
Source:
-
- @@ -870,11 +820,6 @@ from tokenHash and token. -
Source:
-
- @@ -959,11 +904,6 @@ from tokenHash and token. -
Source:
-
- @@ -1048,11 +988,6 @@ from tokenHash and token. -
Source:
-
- @@ -1137,11 +1072,6 @@ from tokenHash and token. -
Source:
-
- @@ -1296,11 +1226,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1389,11 +1314,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1455,7 +1375,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BNote.html b/docs/backend_api/BNote.html index cc39f2216..1ca80c827 100644 --- a/docs/backend_api/BNote.html +++ b/docs/backend_api/BNote.html @@ -90,11 +90,6 @@ - -
Source:
-
@@ -197,11 +192,6 @@ -
Source:
-
- @@ -264,11 +254,6 @@ - -
Source:
-
@@ -332,11 +317,6 @@ - -
Source:
-
@@ -403,11 +383,6 @@ - -
Source:
-
@@ -475,11 +450,6 @@ - -
Source:
-
@@ -543,11 +513,6 @@ - -
Source:
-
@@ -611,11 +576,6 @@ - -
Source:
-
@@ -679,11 +639,6 @@ - -
Source:
-
@@ -747,11 +702,6 @@ - -
Source:
-
@@ -815,11 +765,6 @@ - -
Source:
-
@@ -883,11 +828,6 @@ - -
Source:
-
@@ -951,11 +891,6 @@ - -
Source:
-
@@ -1019,11 +954,6 @@ - -
Source:
-
@@ -1315,11 +1245,6 @@ See addLabel, addRelation for more specific methods. - -
Source:
-
@@ -1423,11 +1348,6 @@ See addLabel, addRelation for more specific methods. -
Source:
-
- @@ -1651,11 +1571,6 @@ See addLabel, addRelation for more specific methods. - -
Source:
-
@@ -1897,11 +1812,6 @@ returned. - -
Source:
-
@@ -2005,11 +1915,6 @@ returned. -
Source:
-
- @@ -2132,11 +2037,6 @@ returned. - -
Source:
-
@@ -2332,11 +2232,6 @@ returned. - -
Source:
-
@@ -2422,11 +2317,6 @@ returned. -
Source:
-
- @@ -2511,11 +2401,6 @@ returned. -
Source:
-
- @@ -2594,11 +2479,6 @@ returned. - -
Source:
-
@@ -2700,11 +2580,6 @@ returned. - -
Source:
-
@@ -2874,11 +2749,6 @@ returned. - -
Source:
-
@@ -3052,11 +2922,6 @@ returned. - -
Source:
-
@@ -3255,11 +3120,6 @@ returned. - -
Source:
-
@@ -3316,7 +3176,7 @@ returned. -

getBranches() → {Array.<Branch>}

+

getBranches() → {Array.<BBranch>}

@@ -3364,11 +3224,6 @@ returned. -
Source:
-
- @@ -3402,7 +3257,7 @@ returned.
-Array.<Branch> +Array.<BBranch>
@@ -3420,7 +3275,7 @@ returned. -

getChildBranches() → {Array.<Branch>}

+

getChildBranches() → {Array.<BBranch>}

@@ -3465,11 +3320,6 @@ returned. - -
Source:
-
@@ -3504,7 +3354,7 @@ returned.
-Array.<Branch> +Array.<BBranch>
@@ -3567,11 +3417,6 @@ returned. - -
Source:
-
@@ -3669,11 +3514,6 @@ returned. - -
Source:
-
@@ -3771,11 +3611,6 @@ returned. - -
Source:
-
@@ -3876,11 +3711,6 @@ returned. -
Source:
-
- @@ -3965,11 +3795,6 @@ returned. - -
Source:
-
@@ -4071,11 +3896,6 @@ returned. - -
Source:
-
@@ -4222,11 +4042,6 @@ returned. - -
Source:
-
@@ -4380,11 +4195,6 @@ returned. - -
Source:
-
@@ -4550,11 +4360,6 @@ returned. - -
Source:
-
@@ -4717,11 +4522,6 @@ returned. - -
Source:
-
@@ -4823,11 +4623,6 @@ returned. - -
Source:
-
@@ -5003,11 +4798,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -5268,11 +5058,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -5423,11 +5208,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -5581,11 +5361,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -5751,11 +5526,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -5918,11 +5688,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6073,11 +5838,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6231,11 +5991,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6401,11 +6156,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6462,7 +6212,7 @@ This method can be significantly faster than the getAttribute() -

getParentBranches() → {Array.<Branch>}

+

getParentBranches() → {Array.<BBranch>}

@@ -6507,11 +6257,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6546,7 +6291,7 @@ This method can be significantly faster than the getAttribute()
-Array.<Branch> +Array.<BBranch>
@@ -6609,11 +6354,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -6717,11 +6457,6 @@ This method can be significantly faster than the getAttribute() -
Source:
-
- @@ -6849,11 +6584,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7007,11 +6737,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7177,11 +6902,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7283,11 +7003,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7392,11 +7107,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7449,7 +7159,7 @@ This method can be significantly faster than the getAttribute() -

getStrongParentBranches() → {Array.<Branch>}

+

getStrongParentBranches() → {Array.<BBranch>}

@@ -7498,11 +7208,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7537,7 +7242,7 @@ This method can be significantly faster than the getAttribute()
-Array.<Branch> +Array.<BBranch>
@@ -7600,11 +7305,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7702,11 +7402,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7808,11 +7503,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -7910,11 +7600,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -8023,11 +7708,6 @@ This method can be significantly faster than the getAttribute() -
Source:
-
- @@ -8106,11 +7786,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -8332,11 +8007,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -8434,11 +8104,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -8628,11 +8293,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -8857,11 +8517,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9055,11 +8710,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9253,11 +8903,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9451,11 +9096,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9601,11 +9241,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9707,11 +9342,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9813,11 +9443,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -9919,11 +9544,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -10025,11 +9645,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -10131,11 +9746,6 @@ This method can be significantly faster than the getAttribute() - -
Source:
-
@@ -10313,11 +9923,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -10523,11 +10128,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -10703,11 +10303,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -10883,11 +10478,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -10977,11 +10567,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -11078,11 +10663,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -11310,11 +10890,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -11490,11 +11065,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -11650,11 +11220,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -11892,11 +11457,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -12103,11 +11663,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -12314,11 +11869,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' - -
Source:
-
@@ -12363,7 +11913,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BNoteRevision.html b/docs/backend_api/BNoteRevision.html index 220d0b294..5b9b4b336 100644 --- a/docs/backend_api/BNoteRevision.html +++ b/docs/backend_api/BNoteRevision.html @@ -91,11 +91,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -198,11 +193,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -265,11 +255,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -333,11 +318,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -401,11 +381,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -469,11 +444,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -537,11 +507,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -605,11 +570,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -673,11 +633,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -741,11 +696,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -809,11 +759,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -877,11 +822,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -945,11 +885,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -1013,11 +948,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -1095,11 +1025,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1184,11 +1109,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1273,11 +1193,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1362,11 +1277,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1445,11 +1355,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -1547,11 +1452,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -1655,11 +1555,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1744,11 +1639,6 @@ It's used for seamless note versioning. -
Source:
-
- @@ -1827,11 +1717,6 @@ It's used for seamless note versioning. - -
Source:
-
@@ -2009,11 +1894,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -2102,11 +1982,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -2168,7 +2043,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BOption.html b/docs/backend_api/BOption.html index 729982cb5..d99af8540 100644 --- a/docs/backend_api/BOption.html +++ b/docs/backend_api/BOption.html @@ -90,11 +90,6 @@ - -
Source:
-
@@ -197,11 +192,6 @@ -
Source:
-
- @@ -264,11 +254,6 @@ - -
Source:
-
@@ -332,11 +317,6 @@ - -
Source:
-
@@ -400,11 +380,6 @@ - -
Source:
-
@@ -468,11 +443,6 @@ - -
Source:
-
@@ -550,11 +520,6 @@ -
Source:
-
- @@ -639,11 +604,6 @@ -
Source:
-
- @@ -728,11 +688,6 @@ -
Source:
-
- @@ -817,11 +772,6 @@ -
Source:
-
- @@ -906,11 +856,6 @@ -
Source:
-
- @@ -995,11 +940,6 @@ -
Source:
-
- @@ -1154,11 +1094,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1247,11 +1182,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1313,7 +1243,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BRecentNote.html b/docs/backend_api/BRecentNote.html index 62fc0b099..33f9799e9 100644 --- a/docs/backend_api/BRecentNote.html +++ b/docs/backend_api/BRecentNote.html @@ -90,11 +90,6 @@ - -
Source:
-
@@ -197,11 +192,6 @@ -
Source:
-
- @@ -264,11 +254,6 @@ - -
Source:
-
@@ -332,11 +317,6 @@ - -
Source:
-
@@ -400,11 +380,6 @@ - -
Source:
-
@@ -482,11 +457,6 @@ -
Source:
-
- @@ -571,11 +541,6 @@ -
Source:
-
- @@ -660,11 +625,6 @@ -
Source:
-
- @@ -749,11 +709,6 @@ -
Source:
-
- @@ -838,11 +793,6 @@ -
Source:
-
- @@ -927,11 +877,6 @@ -
Source:
-
- @@ -1086,11 +1031,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1179,11 +1119,6 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' -
Source:
-
- @@ -1245,7 +1180,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
diff --git a/docs/backend_api/BackendScriptApi.html b/docs/backend_api/BackendScriptApi.html index 4c4b8b850..222a2cfd6 100644 --- a/docs/backend_api/BackendScriptApi.html +++ b/docs/backend_api/BackendScriptApi.html @@ -78,11 +78,6 @@ - -
Source:
-
@@ -182,11 +177,6 @@ - -
Source:
-
@@ -292,11 +282,6 @@ - -
Source:
-
@@ -402,11 +387,6 @@ - -
Source:
-
@@ -512,11 +492,6 @@ - -
Source:
-
@@ -622,11 +597,6 @@ - -
Source:
-
@@ -732,11 +702,6 @@ - -
Source:
-
@@ -842,11 +807,6 @@ - -
Source:
-
@@ -952,11 +912,6 @@ - -
Source:
-
@@ -1128,11 +1083,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -1189,7 +1139,7 @@ JSON MIME type. See also createNewNote() for more options. -

createNewNote(paramsopt) → {Object}

+

createNewNote() → {Object}

@@ -1204,10 +1154,15 @@ JSON MIME type. See also createNewNote() for more options. -
Parameters:
+ + + + +
Properties:
+ - +
@@ -1217,8 +1172,6 @@ JSON MIME type. See also createNewNote() for more options. - - @@ -1237,7 +1190,187 @@ JSON MIME type. See also createNewNote() for more options. + + + + + + + + + +
TypeAttributes -CreateNewNoteParams +object + + + + +
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
parentNoteId + + +string + + + + + + + + + +
title + + +string + + + + + + + + + +
content + + +string +| + +buffer + + + + + + + + + +
type + + +string + + + + + + + + + + text, code, file, image, search, book, relationMap, canvas
mime + + +string @@ -1250,21 +1383,174 @@ JSON MIME type. See also createNewNote() for more options. + + + value is derived from default mimes for type
isProtected + + +boolean + + + + + + <optional>
+
+ + false + +
isExpanded + + +boolean + + + + + + <optional>
+ + + +
+ + false + +
prefix + + +string + + + + + + <optional>
+ + + +
+ + '' + +
notePosition + + +int + + + + + + <optional>
+ + + +
+ + default is last existing notePosition in a parent + 10
+
@@ -1295,11 +1581,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -1515,7 +1796,7 @@ JSON MIME type. See also createNewNote() for more options. -CreateNoteExtraOptions +object @@ -1553,6 +1834,340 @@ JSON MIME type. See also createNewNote() for more options. +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
extraOptions.json + + +boolean + + + + + + <optional>
+ + + +
+ + false + + should the note be JSON
extraOptions.isProtected + + +boolean + + + + + + <optional>
+ + + +
+ + false + + should the note be protected
extraOptions.type + + +string + + + + + + <optional>
+ + + +
+ + 'text' + + note type
extraOptions.mime + + +string + + + + + + <optional>
+ + + +
+ + 'text/html' + + MIME type of the note
extraOptions.attributes + + +Array.<object> + + + + + + <optional>
+ + + +
+ + [] + + attributes to be created for this note +
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
type + + +string + + + + + + + + attribute type - label, relation etc.
name + + +string + + + + + + + + attribute name
value + + +string + + + + + + <optional>
+ + + +
attribute value
+ +
+ + + +
@@ -1582,11 +2197,6 @@ JSON MIME type. See also createNewNote() for more options. -
Source:
-
- @@ -1642,7 +2252,7 @@ JSON MIME type. See also createNewNote() for more options. -

createOrUpdateLauncher(opts)

+

createOrUpdateLauncher(opts) → {Object}

@@ -1692,7 +2302,7 @@ JSON MIME type. See also createNewNote() for more options. -CreateOrUpdateLauncher +object @@ -1714,6 +2324,353 @@ JSON MIME type. See also createNewNote() for more options. +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
opts.id + + +string + + + + + + + + + + id of the launcher, only alphanumeric at least 6 characters long
opts.type + + +string + + + + + + + + + + one of + * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param) + * "script" - activating the launcher will execute the script (specified in scriptNoteId param) + * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param)
opts.title + + +string + + + + + + + + + +
opts.isVisible + + +boolean + + + + + + <optional>
+ + + +
+ + false + + if true, will be created in the "Visible launchers", otherwise in "Available launchers"
opts.icon + + +string + + + + + + <optional>
+ + + +
+ + name of the boxicon to be used (e.g. "bx-time")
opts.keyboardShortcut + + +string + + + + + + <optional>
+ + + +
+ + will activate the target note/script upon pressing, e.g. "ctrl+e"
opts.targetNoteId + + +string + + + + + + <optional>
+ + + +
+ + for type "note"
opts.scriptNoteId + + +string + + + + + + <optional>
+ + + +
+ + for type "script"
opts.widgetNoteId + + +string + + + + + + <optional>
+ + + +
+ + for type "customWidget"
+ + + +
@@ -1740,11 +2697,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -1768,6 +2720,24 @@ JSON MIME type. See also createNewNote() for more options. +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + @@ -1923,11 +2893,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2105,11 +3070,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2306,11 +3266,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2457,11 +3412,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2658,11 +3608,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2760,11 +3705,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2918,11 +3858,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -2978,7 +3913,7 @@ JSON MIME type. See also createNewNote() for more options. -

getBranch(branchId) → {Branch|null}

+

getBranch(branchId) → {BBranch|null}

@@ -3072,11 +4007,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -3111,7 +4041,7 @@ JSON MIME type. See also createNewNote() for more options.
-Branch +BBranch | null @@ -3276,11 +4206,6 @@ JSON MIME type. See also createNewNote() for more options. -
Source:
-
- @@ -3476,11 +4401,6 @@ JSON MIME type. See also createNewNote() for more options. - -
Source:
-
@@ -3586,11 +4506,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -3787,11 +4702,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -3941,11 +4851,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4142,11 +5047,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4343,11 +5243,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4449,11 +5344,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4619,11 +5509,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4853,11 +5738,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -5054,11 +5934,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -5207,11 +6082,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -5344,11 +6214,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -5453,11 +6318,6 @@ if some action needs to happen on only one specific instance. -
Source:
-
- @@ -5633,11 +6493,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -5835,11 +6690,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -6045,11 +6895,6 @@ This method looks similar to toggleNoteInParent() but differs because we're look -
Source:
-
- @@ -6166,7 +7011,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look -SortConfig +object @@ -6198,6 +7043,151 @@ This method looks similar to toggleNoteInParent() but differs because we're look +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
sortConfig.sortBy + + +string + + + + + + <optional>
+ + + +
+ + title + + 'title', 'dateCreated', 'dateModified' or a label name + see https://github.com/zadam/trilium/wiki/Sorting for details.
sortConfig.reverse + + +boolean + + + + + + <optional>
+ + + +
+ + false + +
sortConfig.foldersFirst + + +boolean + + + + + + <optional>
+ + + +
+ + false + +
+ + + +
@@ -6224,11 +7214,6 @@ This method looks similar to toggleNoteInParent() but differs because we're look - -
Source:
-
@@ -6360,11 +7345,6 @@ This method looks similar to toggleNoteInParent() but differs because we're look -
Source:
-
- @@ -6565,11 +7545,6 @@ This method looks similar to toggleNoteInParent() but differs because we're look - -
Source:
-
@@ -6721,11 +7696,6 @@ exists, then we'll use that transaction. - -
Source:
-
@@ -6876,11 +7846,6 @@ exists, then we'll use that transaction. - -
Source:
-
@@ -6947,7 +7912,7 @@ exists, then we'll use that transaction.
diff --git a/docs/backend_api/becca_entities_abstract_becca_entity.js.html b/docs/backend_api/becca_entities_abstract_becca_entity.js.html deleted file mode 100644 index 65f982723..000000000 --- a/docs/backend_api/becca_entities_abstract_becca_entity.js.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - JSDoc: Source: becca/entities/abstract_becca_entity.js - - - - - - - - - - -
- -

Source: becca/entities/abstract_becca_entity.js

- - - - - - -
-
-
"use strict";
-
-const utils = require('../../services/utils');
-const sql = require('../../services/sql');
-const entityChangesService = require('../../services/entity_changes');
-const eventService = require("../../services/events");
-const dateUtils = require("../../services/date_utils");
-const cls = require("../../services/cls");
-const log = require("../../services/log");
-
-let becca = null;
-
-/**
- * Base class for all backend entities.
- */
-class AbstractBeccaEntity {
-    /** @protected */
-    beforeSaving() {
-        this.generateIdIfNecessary();
-    }
-
-    /** @protected */
-    generateIdIfNecessary() {
-        if (!this[this.constructor.primaryKeyName]) {
-            this[this.constructor.primaryKeyName] = utils.newEntityId();
-        }
-    }
-
-    /** @protected */
-    generateHash(isDeleted = false) {
-        let contentToHash = "";
-
-        for (const propertyName of this.constructor.hashedProperties) {
-            contentToHash += `|${this[propertyName]}`;
-        }
-
-        if (isDeleted) {
-            contentToHash += "|deleted";
-        }
-
-        return utils.hash(contentToHash).substr(0, 10);
-    }
-
-    /** @protected */
-    getUtcDateChanged() {
-        return this.utcDateModified || this.utcDateCreated;
-    }
-
-    /**
-     * @protected
-     * @returns {Becca}
-     */
-    get becca() {
-        if (!becca) {
-            becca = require('../becca');
-        }
-
-        return becca;
-    }
-
-    /** @protected */
-    addEntityChange(isDeleted = false) {
-        entityChangesService.addEntityChange({
-            entityName: this.constructor.entityName,
-            entityId: this[this.constructor.primaryKeyName],
-            hash: this.generateHash(isDeleted),
-            isErased: false,
-            utcDateChanged: this.getUtcDateChanged(),
-            isSynced: this.constructor.entityName !== 'options' || !!this.isSynced
-        });
-    }
-
-    /** @protected */
-    getPojoToSave() {
-        return this.getPojo();
-    }
-
-    /**
-     * Saves entity - executes SQL, but doesn't commit the transaction on its own
-     *
-     * @returns {this}
-     */
-    save() {
-        const entityName = this.constructor.entityName;
-        const primaryKeyName = this.constructor.primaryKeyName;
-
-        const isNewEntity = !this[primaryKeyName];
-
-        if (this.beforeSaving) {
-            this.beforeSaving();
-        }
-
-        const pojo = this.getPojoToSave();
-
-        sql.transactional(() => {
-            sql.upsert(entityName, primaryKeyName, pojo);
-
-            if (entityName === 'recent_notes') {
-                return;
-            }
-
-            this.addEntityChange(false);
-
-            if (!cls.isEntityEventsDisabled()) {
-                const eventPayload = {
-                    entityName,
-                    entity: this
-                };
-
-                if (isNewEntity) {
-                    eventService.emit(eventService.ENTITY_CREATED, eventPayload);
-                }
-
-                eventService.emit(eventService.ENTITY_CHANGED, eventPayload);
-            }
-        });
-
-        return this;
-    }
-
-    /**
-     * Mark the entity as (soft) deleted. It will be completely erased later.
-     *
-     * This is a low level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead.
-     *
-     * @param [deleteId=null]
-     */
-    markAsDeleted(deleteId = null) {
-        const entityId = this[this.constructor.primaryKeyName];
-        const entityName = this.constructor.entityName;
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-
-        sql.execute(`UPDATE ${entityName} SET isDeleted = 1, deleteId = ?, utcDateModified = ?
-                           WHERE ${this.constructor.primaryKeyName} = ?`,
-            [deleteId, this.utcDateModified, entityId]);
-
-        if (this.dateModified) {
-            this.dateModified = dateUtils.localNowDateTime();
-
-            sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${this.constructor.primaryKeyName} = ?`,
-                [this.dateModified, entityId]);
-        }
-
-        log.info(`Marking ${entityName} ${entityId} as deleted`);
-
-        this.addEntityChange(true);
-
-        eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
-    }
-
-    markAsDeletedSimple() {
-        const entityId = this[this.constructor.primaryKeyName];
-        const entityName = this.constructor.entityName;
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-
-        sql.execute(`UPDATE ${entityName} SET isDeleted = 1, utcDateModified = ?
-                           WHERE ${this.constructor.primaryKeyName} = ?`,
-            [this.utcDateModified, entityId]);
-
-        log.info(`Marking ${entityName} ${entityId} as deleted`);
-
-        this.addEntityChange(true);
-
-        eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this });
-    }
-}
-
-module.exports = AbstractBeccaEntity;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_battribute.js.html b/docs/backend_api/becca_entities_battribute.js.html deleted file mode 100644 index 447c8fca3..000000000 --- a/docs/backend_api/becca_entities_battribute.js.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - - JSDoc: Source: becca/entities/battribute.js - - - - - - - - - - -
- -

Source: becca/entities/battribute.js

- - - - - - -
-
-
"use strict";
-
-const BNote = require('./bnote');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-const sql = require("../../services/sql");
-const dateUtils = require("../../services/date_utils");
-const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser");
-const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name");
-
-/**
- * Attribute is an abstract concept which has two real uses - label (key - value pair)
- * and relation (representing named relationship between source and target note)
- *
- * @extends AbstractBeccaEntity
- */
-class BAttribute extends AbstractBeccaEntity {
-    static get entityName() { return "attributes"; }
-    static get primaryKeyName() { return "attributeId"; }
-    static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; }
-
-    constructor(row) {
-        super();
-
-        if (!row) {
-            return;
-        }
-
-        this.updateFromRow(row);
-        this.init();
-    }
-
-    updateFromRow(row) {
-        this.update([
-            row.attributeId,
-            row.noteId,
-            row.type,
-            row.name,
-            row.value,
-            row.isInheritable,
-            row.position,
-            row.utcDateModified
-        ]);
-    }
-
-    update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]) {
-        /** @type {string} */
-        this.attributeId = attributeId;
-        /** @type {string} */
-        this.noteId = noteId;
-        /** @type {string} */
-        this.type = type;
-        /** @type {string} */
-        this.name = name;
-        /** @type {int} */
-        this.position = position;
-        /** @type {string} */
-        this.value = value || "";
-        /** @type {boolean} */
-        this.isInheritable = !!isInheritable;
-        /** @type {string} */
-        this.utcDateModified = utcDateModified;
-
-        return this;
-    }
-
-    init() {
-        if (this.attributeId) {
-            this.becca.attributes[this.attributeId] = this;
-        }
-
-        if (!(this.noteId in this.becca.notes)) {
-            // entities can come out of order in sync, create skeleton which will be filled later
-            this.becca.addNote(this.noteId, new BNote({noteId: this.noteId}));
-        }
-
-        this.becca.notes[this.noteId].ownedAttributes.push(this);
-
-        const key = `${this.type}-${this.name.toLowerCase()}`;
-        this.becca.attributeIndex[key] = this.becca.attributeIndex[key] || [];
-        this.becca.attributeIndex[key].push(this);
-
-        const targetNote = this.targetNote;
-
-        if (targetNote) {
-            targetNote.targetRelations.push(this);
-        }
-    }
-
-    validate() {
-        if (!["label", "relation"].includes(this.type)) {
-            throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}' of note '${this.noteId}'`);
-        }
-
-        if (!this.name?.trim()) {
-            throw new Error(`Invalid empty name in attribute '${this.attributeId}' of note '${this.noteId}'`);
-        }
-
-        if (this.type === 'relation' && !(this.value in this.becca.notes)) {
-            throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it target not existing note '${this.value}'.`);
-        }
-    }
-
-    get isAffectingSubtree() {
-        return this.isInheritable
-            || (this.type === 'relation' && this.name === 'template');
-    }
-
-    get targetNoteId() { // alias
-        return this.type === 'relation' ? this.value : undefined;
-    }
-
-    isAutoLink() {
-        return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name);
-    }
-
-    get note() {
-        return this.becca.notes[this.noteId];
-    }
-
-    get targetNote() {
-        if (this.type === 'relation') {
-            return this.becca.notes[this.value];
-        }
-    }
-
-    /**
-     * @returns {BNote|null}
-     */
-    getNote() {
-        const note = this.becca.getNote(this.noteId);
-
-        if (!note) {
-            throw new Error(`Note '${this.noteId}' of attribute '${this.attributeId}', type '${this.type}', name '${this.name}' does not exist.`);
-        }
-
-        return note;
-    }
-
-    /**
-     * @returns {BNote|null}
-     */
-    getTargetNote() {
-        if (this.type !== 'relation') {
-            throw new Error(`Attribute ${this.attributeId} is not relation`);
-        }
-
-        if (!this.value) {
-            return null;
-        }
-
-        return this.becca.getNote(this.value);
-    }
-
-    /**
-     * @return {boolean}
-     */
-    isDefinition() {
-        return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
-    }
-
-    getDefinition() {
-        return promotedAttributeDefinitionParser.parse(this.value);
-    }
-
-    getDefinedName() {
-        if (this.type === 'label' && this.name.startsWith('label:')) {
-            return this.name.substr(6);
-        } else if (this.type === 'label' && this.name.startsWith('relation:')) {
-            return this.name.substr(9);
-        } else {
-            return this.name;
-        }
-    }
-
-    get isDeleted() {
-        return !(this.attributeId in this.becca.attributes);
-    }
-
-    beforeSaving() {
-        this.validate();
-
-        this.name = sanitizeAttributeName(this.name);
-
-        if (!this.value) {
-            // null value isn't allowed
-            this.value = "";
-        }
-
-        if (this.position === undefined) {
-            // TODO: can be calculated from becca
-            this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
-        }
-
-        if (!this.isInheritable) {
-            this.isInheritable = false;
-        }
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-
-        super.beforeSaving();
-
-        this.becca.attributes[this.attributeId] = this;
-    }
-
-    getPojo() {
-        return {
-            attributeId: this.attributeId,
-            noteId: this.noteId,
-            type: this.type,
-            name: this.name,
-            position: this.position,
-            value: this.value,
-            isInheritable: this.isInheritable,
-            utcDateModified: this.utcDateModified,
-            isDeleted: false
-        };
-    }
-
-    createClone(type, name, value, isInheritable) {
-        return new BAttribute({
-            noteId: this.noteId,
-            type: type,
-            name: name,
-            value: value,
-            position: this.position,
-            isInheritable: isInheritable,
-            utcDateModified: this.utcDateModified
-        });
-    }
-}
-
-module.exports = BAttribute;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_bbranch.js.html b/docs/backend_api/becca_entities_bbranch.js.html deleted file mode 100644 index 516a40431..000000000 --- a/docs/backend_api/becca_entities_bbranch.js.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - JSDoc: Source: becca/entities/bbranch.js - - - - - - - - - - -
- -

Source: becca/entities/bbranch.js

- - - - - - -
-
-
"use strict";
-
-const BNote = require('./bnote');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-const dateUtils = require("../../services/date_utils");
-const utils = require("../../services/utils");
-const TaskContext = require("../../services/task_context");
-const cls = require("../../services/cls");
-const log = require("../../services/log");
-
-/**
- * Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
- * parents.
- *
- * Note that you should not rely on the branch's identity, since it can change easily with a note's move.
- * Always check noteId instead.
- *
- * @extends AbstractBeccaEntity
- */
-class BBranch extends AbstractBeccaEntity {
-    static get entityName() { return "branches"; }
-    static get primaryKeyName() { return "branchId"; }
-    // notePosition is not part of hash because it would produce a lot of updates in case of reordering
-    static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; }
-
-    constructor(row) {
-        super();
-
-        if (!row) {
-            return;
-        }
-
-        this.updateFromRow(row);
-        this.init();
-    }
-
-    updateFromRow(row) {
-        this.update([
-            row.branchId,
-            row.noteId,
-            row.parentNoteId,
-            row.prefix,
-            row.notePosition,
-            row.isExpanded,
-            row.utcDateModified
-        ]);
-    }
-
-    update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]) {
-        /** @type {string} */
-        this.branchId = branchId;
-        /** @type {string} */
-        this.noteId = noteId;
-        /** @type {string} */
-        this.parentNoteId = parentNoteId;
-        /** @type {string} */
-        this.prefix = prefix;
-        /** @type {int} */
-        this.notePosition = notePosition;
-        /** @type {boolean} */
-        this.isExpanded = !!isExpanded;
-        /** @type {string} */
-        this.utcDateModified = utcDateModified;
-
-        return this;
-    }
-
-    init() {
-        if (this.branchId) {
-            this.becca.branches[this.branchId] = this;
-        }
-
-        this.becca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this;
-
-        const childNote = this.childNote;
-
-        if (!childNote.parentBranches.includes(this)) {
-            childNote.parentBranches.push(this);
-        }
-
-        if (this.noteId === 'root') {
-            return;
-        }
-
-        const parentNote = this.parentNote;
-
-        if (!childNote.parents.includes(parentNote)) {
-            childNote.parents.push(parentNote);
-        }
-
-        if (!parentNote.children.includes(childNote)) {
-            parentNote.children.push(childNote);
-        }
-    }
-
-    /** @returns {BNote} */
-    get childNote() {
-        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}));
-        }
-
-        return this.becca.notes[this.noteId];
-    }
-
-    getNote() {
-        return this.childNote;
-    }
-
-    /** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */
-    get parentNote() {
-        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}));
-        }
-
-        return this.becca.notes[this.parentNoteId];
-    }
-
-    get isDeleted() {
-        return !(this.branchId in this.becca.branches);
-    }
-
-    /**
-     * Branch is weak when its existence should not hinder deletion of its note.
-     * As a result, note with only weak branches should be immediately deleted.
-     * An example is shared or bookmarked clones - they are created automatically and exist for technical reasons,
-     * not as user-intended actions. From user perspective, they don't count as real clones and for the purpose
-     * of deletion should not act as a clone.
-     *
-     * @returns {boolean}
-     */
-    get isWeak() {
-        return ['_share', '_lbBookmarks'].includes(this.parentNoteId);
-    }
-
-    /**
-     * Delete a branch. If this is a last note's branch, delete the note as well.
-     *
-     * @param {string} [deleteId] - optional delete identified
-     * @param {TaskContext} [taskContext]
-     *
-     * @return {boolean} - true if note has been deleted, false otherwise
-     */
-    deleteBranch(deleteId, taskContext) {
-        if (!deleteId) {
-            deleteId = utils.randomString(10);
-        }
-
-        if (!taskContext) {
-            taskContext = new TaskContext('no-progress-reporting');
-        }
-
-        taskContext.increaseProgressCount();
-
-        const note = this.getNote();
-
-        if (!taskContext.noteDeletionHandlerTriggered) {
-            const parentBranches = note.getParentBranches();
-
-            if (parentBranches.length === 1 && parentBranches[0] === this) {
-                // needs to be run before branches and attributes are deleted and thus attached relations disappear
-                const handlers = require("../../services/handlers");
-                handlers.runAttachedRelations(note, 'runOnNoteDeletion', note);
-            }
-        }
-
-        if (this.noteId === 'root'
-            || this.noteId === cls.getHoistedNoteId()) {
-
-            throw new Error("Can't delete root or hoisted branch/note");
-        }
-
-        this.markAsDeleted(deleteId);
-
-        const notDeletedBranches = note.getStrongParentBranches();
-
-        if (notDeletedBranches.length === 0) {
-            for (const weakBranch of note.getParentBranches()) {
-                weakBranch.markAsDeleted(deleteId);
-            }
-
-            for (const childBranch of note.getChildBranches()) {
-                childBranch.deleteBranch(deleteId, taskContext);
-            }
-
-            // first delete children and then parent - this will show up better in recent changes
-
-            log.info(`Deleting note ${note.noteId}`);
-
-            this.becca.notes[note.noteId].isBeingDeleted = true;
-
-            for (const attribute of note.getOwnedAttributes()) {
-                attribute.markAsDeleted(deleteId);
-            }
-
-            for (const relation of note.getTargetRelations()) {
-                relation.markAsDeleted(deleteId);
-            }
-
-            note.markAsDeleted(deleteId);
-
-            return true;
-        }
-        else {
-            return false;
-        }
-    }
-
-    beforeSaving() {
-        if (!this.noteId || !this.parentNoteId) {
-            throw new Error(`noteId and parentNoteId are mandatory properties for Branch`);
-        }
-
-        this.branchId = `${this.parentNoteId}_${this.noteId}`;
-
-        if (this.notePosition === undefined || this.notePosition === null) {
-            let maxNotePos = 0;
-
-            for (const childBranch of this.parentNote.getChildBranches()) {
-                if (maxNotePos < childBranch.notePosition
-                    && childBranch.noteId !== '_hidden' // hidden has very large notePosition to always stay last
-                ) {
-                    maxNotePos = childBranch.notePosition;
-                }
-            }
-
-            this.notePosition = maxNotePos + 10;
-        }
-
-        if (!this.isExpanded) {
-            this.isExpanded = false;
-        }
-
-        if (!this.prefix?.trim()) {
-            this.prefix = null;
-        }
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-
-        super.beforeSaving();
-
-        this.becca.branches[this.branchId] = this;
-    }
-
-    getPojo() {
-        return {
-            branchId: this.branchId,
-            noteId: this.noteId,
-            parentNoteId: this.parentNoteId,
-            prefix: this.prefix,
-            notePosition: this.notePosition,
-            isExpanded: this.isExpanded,
-            isDeleted: false,
-            utcDateModified: this.utcDateModified
-        };
-    }
-
-    createClone(parentNoteId, notePosition) {
-        const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId);
-
-        if (existingBranch) {
-            existingBranch.notePosition = notePosition;
-            return existingBranch;
-        } else {
-            return new BBranch({
-                noteId: this.noteId,
-                parentNoteId: parentNoteId,
-                notePosition: notePosition,
-                prefix: this.prefix,
-                isExpanded: this.isExpanded
-            });
-        }
-    }
-}
-
-module.exports = BBranch;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_betapi_token.js.html b/docs/backend_api/becca_entities_betapi_token.js.html deleted file mode 100644 index 78682c44c..000000000 --- a/docs/backend_api/becca_entities_betapi_token.js.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - JSDoc: Source: becca/entities/betapi_token.js - - - - - - - - - - -
- -

Source: becca/entities/betapi_token.js

- - - - - - -
-
-
"use strict";
-
-const dateUtils = require('../../services/date_utils');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-
-/**
- * EtapiToken is an entity representing token used to authenticate against Trilium REST API from client applications.
- * Used by:
- * - Trilium Sender
- * - ETAPI clients
- *
- * The format user is presented with is "<etapiTokenId>_<tokenHash>". This is also called "authToken" to distinguish it
- * from tokenHash and token.
- *
- * @extends AbstractBeccaEntity
- */
-class BEtapiToken extends AbstractBeccaEntity {
-    static get entityName() { return "etapi_tokens"; }
-    static get primaryKeyName() { return "etapiTokenId"; }
-    static get hashedProperties() { return ["etapiTokenId", "name", "tokenHash", "utcDateCreated", "utcDateModified", "isDeleted"]; }
-
-    constructor(row) {
-        super();
-
-        if (!row) {
-            return;
-        }
-
-        this.updateFromRow(row);
-        this.init();
-    }
-
-    updateFromRow(row) {
-        /** @type {string} */
-        this.etapiTokenId = row.etapiTokenId;
-        /** @type {string} */
-        this.name = row.name;
-        /** @type {string} */
-        this.tokenHash = row.tokenHash;
-        /** @type {string} */
-        this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime();
-        /** @type {string} */
-        this.utcDateModified = row.utcDateModified || this.utcDateCreated;
-        /** @type {boolean} */
-        this.isDeleted = !!row.isDeleted;
-
-        if (this.etapiTokenId) {
-            this.becca.etapiTokens[this.etapiTokenId] = this;
-        }
-    }
-
-    init() {
-        if (this.etapiTokenId) {
-            this.becca.etapiTokens[this.etapiTokenId] = this;
-        }
-    }
-
-    getPojo() {
-        return {
-            etapiTokenId: this.etapiTokenId,
-            name: this.name,
-            tokenHash: this.tokenHash,
-            utcDateCreated: this.utcDateCreated,
-            utcDateModified: this.utcDateModified,
-            isDeleted: this.isDeleted
-        }
-    }
-
-    beforeSaving() {
-        this.utcDateModified = dateUtils.utcNowDateTime();
-
-        super.beforeSaving();
-
-        this.becca.etapiTokens[this.etapiTokenId] = this;
-    }
-}
-
-module.exports = BEtapiToken;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_bnote.js.html b/docs/backend_api/becca_entities_bnote.js.html deleted file mode 100644 index 2e481ccf6..000000000 --- a/docs/backend_api/becca_entities_bnote.js.html +++ /dev/null @@ -1,1488 +0,0 @@ - - - - - JSDoc: Source: becca/entities/bnote.js - - - - - - - - - - -
- -

Source: becca/entities/bnote.js

- - - - - - -
-
-
"use strict";
-
-const protectedSessionService = require('../../services/protected_session');
-const log = require('../../services/log');
-const sql = require('../../services/sql');
-const utils = require('../../services/utils');
-const dateUtils = require('../../services/date_utils');
-const entityChangesService = require('../../services/entity_changes');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-const BNoteRevision = require("./bnote_revision");
-const TaskContext = require("../../services/task_context");
-const dayjs = require("dayjs");
-const utc = require('dayjs/plugin/utc');
-dayjs.extend(utc)
-
-const LABEL = 'label';
-const RELATION = 'relation';
-
-/**
- * Trilium's main entity which can represent text note, image, code note, file attachment etc.
- *
- * @extends AbstractBeccaEntity
- */
-class BNote extends AbstractBeccaEntity {
-    static get entityName() { return "notes"; }
-    static get primaryKeyName() { return "noteId"; }
-    static get hashedProperties() { return ["noteId", "title", "isProtected", "type", "mime"]; }
-
-    constructor(row) {
-        super();
-
-        if (!row) {
-            return;
-        }
-
-        this.updateFromRow(row);
-        this.init();
-    }
-
-    updateFromRow(row) {
-        this.update([
-            row.noteId,
-            row.title,
-            row.type,
-            row.mime,
-            row.isProtected,
-            row.dateCreated,
-            row.dateModified,
-            row.utcDateCreated,
-            row.utcDateModified
-        ]);
-    }
-
-    update([noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified]) {
-        // ------ Database persisted attributes ------
-
-        /** @type {string} */
-        this.noteId = noteId;
-        /** @type {string} */
-        this.title = title;
-        /** @type {boolean} */
-        this.isProtected = !!isProtected;
-        /** @type {string} */
-        this.type = type;
-        /** @type {string} */
-        this.mime = mime;
-        /** @type {string} */
-        this.dateCreated = dateCreated || dateUtils.localNowDateTime();
-        /** @type {string} */
-        this.dateModified = dateModified;
-        /** @type {string} */
-        this.utcDateCreated = utcDateCreated || dateUtils.utcNowDateTime();
-        /** @type {string} */
-        this.utcDateModified = utcDateModified;
-        /** @type {boolean} - set during the deletion operation, before it is completed (removed from becca completely) */
-        this.isBeingDeleted = false;
-
-        // ------ Derived attributes ------
-
-        /** @type {boolean} */
-        this.isDecrypted = !this.noteId || !this.isProtected;
-
-        this.decrypt();
-
-        /** @type {string|null} */
-        this.flatTextCache = null;
-
-        return this;
-    }
-
-    init() {
-        /** @type {Branch[]}
-         * @private */
-        this.parentBranches = [];
-        /** @type {BNote[]}
-         * @private */
-        this.parents = [];
-        /** @type {BNote[]}
-         * @private*/
-        this.children = [];
-        /** @type {Attribute[]}
-         * @private */
-        this.ownedAttributes = [];
-
-        /** @type {Attribute[]|null}
-         * @private */
-        this.__attributeCache = null;
-        /** @type {Attribute[]|null}
-         * @private*/
-        this.inheritableAttributeCache = null;
-
-        /** @type {Attribute[]}
-         * @private*/
-        this.targetRelations = [];
-
-        this.becca.addNote(this.noteId, this);
-
-        /** @type {BNote[]|null}
-         * @private */
-        this.ancestorCache = null;
-
-        // following attributes are filled during searching from database
-
-        /**
-         * size of the content in bytes
-         * @type {int|null}
-         * @private
-         */
-        this.contentSize = null;
-        /**
-         * size of the content and note revision contents in bytes
-         * @type {int|null}
-         * @private
-         */
-        this.noteSize = null;
-        /**
-         * number of note revisions for this note
-         * @type {int|null}
-         * @private
-         */
-        this.revisionCount = null;
-    }
-
-    isContentAvailable() {
-        return !this.noteId // new note which was not encrypted yet
-            || !this.isProtected
-            || protectedSessionService.isProtectedSessionAvailable()
-    }
-
-    getTitleOrProtected() {
-        return this.isContentAvailable() ? this.title : '[protected]';
-    }
-
-    /** @returns {Branch[]} */
-    getParentBranches() {
-        return this.parentBranches;
-    }
-
-    /**
-     * Returns <i>strong</i> (as opposed to <i>weak</i>) parent branches. See isWeak for details.
-     *
-     * @returns {Branch[]}
-     */
-    getStrongParentBranches() {
-        return this.getParentBranches().filter(branch => !branch.isWeak);
-    }
-
-    /**
-     * @returns {Branch[]}
-     * @deprecated use getParentBranches() instead
-     */
-    getBranches() {
-        return this.parentBranches;
-    }
-
-    /** @returns {BNote[]} */
-    getParentNotes() {
-        return this.parents;
-    }
-
-    /** @returns {BNote[]} */
-    getChildNotes() {
-        return this.children;
-    }
-
-    /** @returns {boolean} */
-    hasChildren() {
-        return this.children && this.children.length > 0;
-    }
-
-    /** @returns {Branch[]} */
-    getChildBranches() {
-        return this.children.map(childNote => this.becca.getBranchFromChildAndParent(childNote.noteId, this.noteId));
-    }
-
-    /*
-     * Note content has quite special handling - it's not a separate entity, but a lazily loaded
-     * part of Note entity with it's own sync. Reasons behind this hybrid design has been:
-     *
-     * - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search
-     * - 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 {*} */
-    getContent(silentNotFoundError = false) {
-        const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
-
-        if (!row) {
-            if (silentNotFoundError) {
-                return undefined;
-            }
-            else {
-                throw new Error(`Cannot find note content for noteId=${this.noteId}`);
-            }
-        }
-
-        let content = row.content;
-
-        if (this.isProtected) {
-            if (protectedSessionService.isProtectedSessionAvailable()) {
-                content = content === null ? null : protectedSessionService.decrypt(content);
-            }
-            else {
-                content = "";
-            }
-        }
-
-        if (this.isStringNote()) {
-            return content === null
-                ? ""
-                : content.toString("UTF-8");
-        }
-        else {
-            return content;
-        }
-    }
-
-    /** @returns {{contentLength, dateModified, utcDateModified}} */
-    getContentMetadata() {
-        return sql.getRow(`
-            SELECT 
-                LENGTH(content) AS contentLength, 
-                dateModified,
-                utcDateModified 
-            FROM note_contents 
-            WHERE noteId = ?`, [this.noteId]);
-    }
-
-    get dateCreatedObj() {
-        return this.dateCreated === null ? null : dayjs(this.dateCreated);
-    }
-
-    get utcDateCreatedObj() {
-        return this.utcDateCreated === null ? null : dayjs.utc(this.utcDateCreated);
-    }
-
-    get dateModifiedObj() {
-        return this.dateModified === null ? null : dayjs(this.dateModified);
-    }
-
-    get utcDateModifiedObj() {
-        return this.utcDateModified === null ? null : dayjs.utc(this.utcDateModified);
-    }
-
-    /** @returns {*} */
-    getJsonContent() {
-        const content = this.getContent();
-
-        if (!content || !content.trim()) {
-            return null;
-        }
-
-        return JSON.parse(content);
-    }
-
-    setContent(content, ignoreMissingProtectedSession = false) {
-        if (content === null || content === undefined) {
-            throw new Error(`Cannot set null content to note '${this.noteId}'`);
-        }
-
-        if (this.isStringNote()) {
-            content = content.toString();
-        }
-        else {
-            content = Buffer.isBuffer(content) ? content : Buffer.from(content);
-        }
-
-        const pojo = {
-            noteId: this.noteId,
-            content: content,
-            dateModified: dateUtils.localNowDateTime(),
-            utcDateModified: dateUtils.utcNowDateTime()
-        };
-
-        if (this.isProtected) {
-            if (protectedSessionService.isProtectedSessionAvailable()) {
-                pojo.content = protectedSessionService.encrypt(pojo.content);
-            }
-            else if (!ignoreMissingProtectedSession) {
-                throw new Error(`Cannot update content of noteId '${this.noteId}' since we're out of protected session.`);
-            }
-        }
-
-        sql.upsert("note_contents", "noteId", pojo);
-
-        const hash = utils.hash(`${this.noteId}|${pojo.content.toString()}`);
-
-        entityChangesService.addEntityChange({
-            entityName: 'note_contents',
-            entityId: this.noteId,
-            hash: hash,
-            isErased: false,
-            utcDateChanged: pojo.utcDateModified,
-            isSynced: true
-        });
-    }
-
-    setJsonContent(content) {
-        this.setContent(JSON.stringify(content, null, '\t'));
-    }
-
-    /** @returns {boolean} true if this note is the root of the note tree. Root note has "root" noteId */
-    isRoot() {
-        return this.noteId === 'root';
-    }
-
-    /** @returns {boolean} true if this note is of application/json content type */
-    isJson() {
-        return this.mime === "application/json";
-    }
-
-    /** @returns {boolean} true if this note is JavaScript (code or attachment) */
-    isJavaScript() {
-        return (this.type === "code" || this.type === "file" || this.type === 'launcher')
-            && (this.mime.startsWith("application/javascript")
-                || this.mime === "application/x-javascript"
-                || this.mime === "text/javascript");
-    }
-
-    /** @returns {boolean} true if this note is HTML */
-    isHtml() {
-        return ["code", "file", "render"].includes(this.type)
-            && this.mime === "text/html";
-    }
-
-    /** @returns {boolean} true if the note has string content (not binary) */
-    isStringNote() {
-        return utils.isStringNote(this.type, this.mime);
-    }
-
-    /** @returns {string|null} JS script environment - either "frontend" or "backend" */
-    getScriptEnv() {
-        if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith('env=frontend'))) {
-            return "frontend";
-        }
-
-        if (this.type === 'render') {
-            return "frontend";
-        }
-
-        if (this.isJavaScript() && this.mime.endsWith('env=backend')) {
-            return "backend";
-        }
-
-        return null;
-    }
-
-    /**
-     * @param {string} [type] - (optional) attribute type to filter
-     * @param {string} [name] - (optional) attribute name to filter
-     * @returns {Attribute[]} all note's attributes, including inherited ones
-     */
-    getAttributes(type, name) {
-        this.__validateTypeName(type, name);
-
-        this.__getAttributes([]);
-
-        if (type && name) {
-            return this.__attributeCache.filter(attr => attr.type === type && attr.name === name);
-        }
-        else if (type) {
-            return this.__attributeCache.filter(attr => attr.type === type);
-        }
-        else if (name) {
-            return this.__attributeCache.filter(attr => attr.name === name);
-        }
-        else {
-            // a bit unsafe to return the original array, but defensive copy would be costly
-            return this.__attributeCache;
-        }
-    }
-
-    /** @private */
-    __getAttributes(path) {
-        if (path.includes(this.noteId)) {
-            return [];
-        }
-
-        if (!this.__attributeCache) {
-            const parentAttributes = this.ownedAttributes.slice();
-            const newPath = [...path, this.noteId];
-
-            if (this.noteId !== 'root') {
-                for (const parentNote of this.parents) {
-                    parentAttributes.push(...parentNote.__getInheritableAttributes(newPath));
-                }
-            }
-
-            const templateAttributes = [];
-
-            for (const ownedAttr of parentAttributes) { // parentAttributes so we process also inherited templates
-                if (ownedAttr.type === 'relation' && ownedAttr.name === 'template') {
-                    const templateNote = this.becca.notes[ownedAttr.value];
-
-                    if (templateNote) {
-                        templateAttributes.push(
-                            ...templateNote.__getAttributes(newPath)
-                                // template attr is used as a marker for templates, but it's not meant to be inherited
-                                .filter(attr => !(attr.type === 'label' && (attr.name === 'template' || attr.name === 'workspacetemplate')))
-                        );
-                    }
-                }
-            }
-
-            this.__attributeCache = [];
-
-            const addedAttributeIds = new Set();
-
-            for (const attr of parentAttributes.concat(templateAttributes)) {
-                if (!addedAttributeIds.has(attr.attributeId)) {
-                    addedAttributeIds.add(attr.attributeId);
-
-                    this.__attributeCache.push(attr);
-                }
-            }
-
-            this.inheritableAttributeCache = [];
-
-            for (const attr of this.__attributeCache) {
-                if (attr.isInheritable) {
-                    this.inheritableAttributeCache.push(attr);
-                }
-            }
-        }
-
-        return this.__attributeCache;
-    }
-
-    /**
-     * @private
-     * @returns {Attribute[]}
-     */
-    __getInheritableAttributes(path) {
-        if (path.includes(this.noteId)) {
-            return [];
-        }
-
-        if (!this.inheritableAttributeCache) {
-            this.__getAttributes(path); // will refresh also this.inheritableAttributeCache
-        }
-
-        return this.inheritableAttributeCache;
-    }
-
-    __validateTypeName(type, name) {
-        if (type && type !== 'label' && type !== 'relation') {
-            throw new Error(`Unrecognized attribute type '${type}'. Only 'label' and 'relation' are possible values.`);
-        }
-
-        if (name) {
-            const firstLetter = name.charAt(0);
-            if (firstLetter === '#' || firstLetter === '~') {
-                throw new Error(`Detect '#' or '~' in the attribute's name. In the API, attribute names should be set without these characters.`);
-            }
-        }
-    }
-
-    /**
-     * @param type
-     * @param name
-     * @param [value]
-     * @returns {boolean}
-     */
-    hasAttribute(type, name, value = null) {
-        return !!this.getAttributes().find(attr =>
-            attr.type === type
-            && attr.name === name
-            && (value === undefined || value === null || attr.value === value)
-        );
-    }
-
-    getAttributeCaseInsensitive(type, name, value) {
-        name = name.toLowerCase();
-        value = value ? value.toLowerCase() : null;
-
-        return this.getAttributes().find(
-            attr => attr.type === type
-            && attr.name.toLowerCase() === name
-            && (!value || attr.value.toLowerCase() === value));
-    }
-
-    getRelationTarget(name) {
-        const relation = this.getAttributes().find(attr => attr.type === 'relation' && attr.name === name);
-
-        return relation ? relation.targetNote : null;
-    }
-
-    /**
-     * @param {string} name - label name
-     * @param {string} [value] - label value
-     * @returns {boolean} true if label exists (including inherited)
-     */
-    hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); }
-
-    /**
-     * @param {string} name - label name
-     * @param {string} [value] - label value
-     * @returns {boolean} true if label exists (excluding inherited)
-     */
-    hasOwnedLabel(name, value) { return this.hasOwnedAttribute(LABEL, name, value); }
-
-    /**
-     * @param {string} name - relation name
-     * @param {string} [value] - relation value
-     * @returns {boolean} true if relation exists (including inherited)
-     */
-    hasRelation(name, value) { return this.hasAttribute(RELATION, name, value); }
-
-    /**
-     * @param {string} name - relation name
-     * @param {string} [value] - relation value
-     * @returns {boolean} true if relation exists (excluding inherited)
-     */
-    hasOwnedRelation(name, value) { return this.hasOwnedAttribute(RELATION, name, value); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {Attribute|null} label if it exists, null otherwise
-     */
-    getLabel(name) { return this.getAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {Attribute|null} label if it exists, null otherwise
-     */
-    getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {Attribute|null} relation if it exists, null otherwise
-     */
-    getRelation(name) { return this.getAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {Attribute|null} relation if it exists, null otherwise
-     */
-    getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {string|null} label value if label exists, null otherwise
-     */
-    getLabelValue(name) { return this.getAttributeValue(LABEL, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {string|null} label value if label exists, null otherwise
-     */
-    getOwnedLabelValue(name) { return this.getOwnedAttributeValue(LABEL, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {string|null} relation value if relation exists, null otherwise
-     */
-    getRelationValue(name) { return this.getAttributeValue(RELATION, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {string|null} relation value if relation exists, null otherwise
-     */
-    getOwnedRelationValue(name) { return this.getOwnedAttributeValue(RELATION, name); }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value
-     * @returns {boolean} true if note has an attribute with given type and name (excluding inherited)
-     */
-    hasOwnedAttribute(type, name, value) {
-        return !!this.getOwnedAttribute(type, name, value);
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {Attribute} attribute of given type and name. If there's more such attributes, first is  returned. Returns null if there's no such attribute belonging to this note.
-     */
-    getAttribute(type, name) {
-        const attributes = this.getAttributes();
-
-        return attributes.find(attr => attr.type === type && attr.name === name);
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {string|null} attribute value of given type and name or null if no such attribute exists.
-     */
-    getAttributeValue(type, name) {
-        const attr = this.getAttribute(type, name);
-
-        return attr ? attr.value : null;
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {string|null} attribute value of given type and name or null if no such attribute exists.
-     */
-    getOwnedAttributeValue(type, name) {
-        const attr = this.getOwnedAttribute(type, name);
-
-        return attr ? attr.value : null;
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {Attribute[]} all note's labels (attributes with type label), including inherited ones
-     */
-    getLabels(name) {
-        return this.getAttributes(LABEL, name);
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {string[]} all note's label values, including inherited ones
-     */
-    getLabelValues(name) {
-        return this.getLabels(name).map(l => l.value);
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {Attribute[]} all note's labels (attributes with type label), excluding inherited ones
-     */
-    getOwnedLabels(name) {
-        return this.getOwnedAttributes(LABEL, name);
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {string[]} all note's label values, excluding inherited ones
-     */
-    getOwnedLabelValues(name) {
-        return this.getOwnedAttributes(LABEL, name).map(l => l.value);
-    }
-
-    /**
-     * @param {string} [name] - relation name to filter
-     * @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones
-     */
-    getRelations(name) {
-        return this.getAttributes(RELATION, name);
-    }
-
-    /**
-     * @param {string} [name] - relation name to filter
-     * @returns {Attribute[]} all note's relations (attributes with type relation), excluding inherited ones
-     */
-    getOwnedRelations(name) {
-        return this.getOwnedAttributes(RELATION, name);
-    }
-
-    /**
-     * @param {string|null} [type] - (optional) attribute type to filter
-     * @param {string|null} [name] - (optional) attribute name to filter
-     * @param {string|null} [value] - (optional) attribute value to filter
-     * @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
-     */
-    getOwnedAttributes(type = null, name = null, value = null) {
-        this.__validateTypeName(type, name);
-
-        if (type && name && value !== undefined && value !== null) {
-            return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name && attr.value === value);
-        }
-        else if (type && name) {
-            return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name);
-        }
-        else if (type) {
-            return this.ownedAttributes.filter(attr => attr.type === type);
-        }
-        else if (name) {
-            return this.ownedAttributes.filter(attr => attr.name === name);
-        }
-        else {
-            return this.ownedAttributes.slice();
-        }
-    }
-
-    /**
-     * @returns {Attribute} attribute belonging to this specific note (excludes inherited attributes)
-     *
-     * This method can be significantly faster than the getAttribute()
-     */
-    getOwnedAttribute(type, name, value = null) {
-        const attrs = this.getOwnedAttributes(type, name, value);
-
-        return attrs.length > 0 ? attrs[0] : null;
-    }
-
-    get isArchived() {
-        return this.hasAttribute('label', 'archived');
-    }
-
-    hasInheritableOwnedArchivedLabel() {
-        return !!this.ownedAttributes.find(attr => attr.type === 'label' && attr.name === 'archived' && attr.isInheritable);
-    }
-
-    // will sort the parents so that non-search & non-archived are first and archived at the end
-    // this is done so that non-search & non-archived paths are always explored as first when looking for note path
-    sortParents() {
-        this.parentBranches.sort((a, b) =>
-            a.branchId.startsWith('virt-') // FIXME: search virtual notes appear only in froca so this is probably not necessary
-            || a.parentNote?.hasInheritableOwnedArchivedLabel() ? 1 : -1);
-
-        this.parents = this.parentBranches
-            .map(branch => branch.parentNote)
-            .filter(note => !!note);
-    }
-
-    /**
-     * This is used for:
-     * - fast searching
-     * - note similarity evaluation
-     *
-     * @return {string} - returns flattened textual representation of note, prefixes and attributes
-     */
-    getFlatText() {
-        if (!this.flatTextCache) {
-            this.flatTextCache = `${this.noteId} ${this.type} ${this.mime} `;
-
-            for (const branch of this.parentBranches) {
-                if (branch.prefix) {
-                    this.flatTextCache += `${branch.prefix} `;
-                }
-            }
-
-            this.flatTextCache += `${this.title} `;
-
-            for (const attr of this.getAttributes()) {
-                // it's best to use space as separator since spaces are filtered from the search string by the tokenization into words
-                this.flatTextCache += `${attr.type === 'label' ? '#' : '~'}${attr.name}`;
-
-                if (attr.value) {
-                    this.flatTextCache += `=${attr.value}`;
-                }
-
-                this.flatTextCache += ' ';
-            }
-
-            this.flatTextCache = utils.normalize(this.flatTextCache);
-        }
-
-        return this.flatTextCache;
-    }
-
-    invalidateThisCache() {
-        this.flatTextCache = null;
-
-        this.__attributeCache = null;
-        this.inheritableAttributeCache = null;
-        this.ancestorCache = null;
-    }
-
-    invalidateSubTree(path = []) {
-        if (path.includes(this.noteId)) {
-            return;
-        }
-
-        this.invalidateThisCache();
-
-        if (this.children.length || this.targetRelations.length) {
-            path = [...path, this.noteId];
-        }
-
-        for (const childNote of this.children) {
-            childNote.invalidateSubTree(path);
-        }
-
-        for (const targetRelation of this.targetRelations) {
-            if (targetRelation.name === 'template') {
-                const note = targetRelation.note;
-
-                if (note) {
-                    note.invalidateSubTree(path);
-                }
-            }
-        }
-    }
-
-    invalidateSubtreeFlatText() {
-        this.flatTextCache = null;
-
-        for (const childNote of this.children) {
-            childNote.invalidateSubtreeFlatText();
-        }
-
-        for (const targetRelation of this.targetRelations) {
-            if (targetRelation.name === 'template') {
-                const note = targetRelation.note;
-
-                if (note) {
-                    note.invalidateSubtreeFlatText();
-                }
-            }
-        }
-    }
-
-    getRelationDefinitions() {
-        return this.getLabels()
-            .filter(l => l.name.startsWith("relation:"));
-    }
-
-    getLabelDefinitions() {
-        return this.getLabels()
-            .filter(l => l.name.startsWith("relation:"));
-    }
-
-    isTemplate() {
-        return !!this.targetRelations.find(rel => rel.name === 'template');
-    }
-
-    /** @returns {BNote[]} */
-    getSubtreeNotesIncludingTemplated() {
-        const set = new Set();
-
-        function inner(note) {
-            if (set.has(note)) {
-                return;
-            }
-
-            set.add(note);
-
-            for (const childNote of note.children) {
-                inner(childNote);
-            }
-
-            for (const targetRelation of note.targetRelations) {
-                if (targetRelation.name === 'template') {
-                    const targetNote = targetRelation.note;
-
-                    if (targetNote) {
-                        inner(targetNote);
-                    }
-                }
-            }
-        }
-
-        inner(this);
-
-        return Array.from(set);
-    }
-
-    /** @return {BNote[]} */
-    getSearchResultNotes() {
-        if (this.type !== 'search') {
-            return [];
-        }
-
-        try {
-            const searchService = require("../../services/search/services/search");
-            const {searchResultNoteIds} = searchService.searchFromNote(this);
-
-            const becca = this.becca;
-            return searchResultNoteIds
-                .map(resultNoteId => becca.notes[resultNoteId])
-                .filter(note => !!note);
-        }
-        catch (e) {
-            log.error(`Could not resolve search note ${this.noteId}: ${e.message}`);
-            return [];
-        }
-    }
-
-    /**
-     * @returns {{notes: BNote[], relationships: Array.<{parentNoteId: string, childNoteId: string}>}}
-     */
-    getSubtree({includeArchived = true, includeHidden = false, resolveSearch = false} = {}) {
-        const noteSet = new Set();
-        const relationships = []; // list of tuples parentNoteId -> childNoteId
-
-        function resolveSearchNote(searchNote) {
-            try {
-                for (const resultNote of searchNote.getSearchResultNotes()) {
-                    addSubtreeNotesInner(resultNote, searchNote);
-                }
-            }
-            catch (e) {
-                log.error(`Could not resolve search note ${searchNote?.noteId}: ${e.message}`);
-            }
-        }
-
-        function addSubtreeNotesInner(note, parentNote = null) {
-            if (note.noteId === '_hidden' && !includeHidden) {
-                return;
-            }
-
-            if (parentNote) {
-                // this needs to happen first before noteSet check to include all clone relationships
-                relationships.push({
-                    parentNoteId: parentNote.noteId,
-                    childNoteId: note.noteId
-                });
-            }
-
-            if (noteSet.has(note)) {
-                return;
-            }
-
-            if (!includeArchived && note.isArchived) {
-                return;
-            }
-
-            noteSet.add(note);
-
-            if (note.type === 'search') {
-                if (resolveSearch) {
-                    resolveSearchNote(note);
-                }
-            }
-            else {
-                for (const childNote of note.children) {
-                    addSubtreeNotesInner(childNote, note);
-                }
-            }
-        }
-
-        addSubtreeNotesInner(this);
-
-        return {
-            notes: Array.from(noteSet),
-            relationships
-        };
-    }
-
-    /** @returns {String[]} - includes the subtree node as well */
-    getSubtreeNoteIds({includeArchived = true, includeHidden = false, resolveSearch = false} = {}) {
-        return this.getSubtree({includeArchived, includeHidden, resolveSearch})
-            .notes
-            .map(note => note.noteId);
-    }
-
-    /** @deprecated use getSubtreeNoteIds() instead */
-    getDescendantNoteIds() {
-        return this.getSubtreeNoteIds();
-    }
-
-    get parentCount() {
-        return this.parents.length;
-    }
-
-    get childrenCount() {
-        return this.children.length;
-    }
-
-    get labelCount() {
-        return this.getAttributes().filter(attr => attr.type === 'label').length;
-    }
-
-    get ownedLabelCount() {
-        return this.ownedAttributes.filter(attr => attr.type === 'label').length;
-    }
-
-    get relationCount() {
-        return this.getAttributes().filter(attr => attr.type === 'relation' && !attr.isAutoLink()).length;
-    }
-
-    get relationCountIncludingLinks() {
-        return this.getAttributes().filter(attr => attr.type === 'relation').length;
-    }
-
-    get ownedRelationCount() {
-        return this.ownedAttributes.filter(attr => attr.type === 'relation' && !attr.isAutoLink()).length;
-    }
-
-    get ownedRelationCountIncludingLinks() {
-        return this.ownedAttributes.filter(attr => attr.type === 'relation').length;
-    }
-
-    get targetRelationCount() {
-        return this.targetRelations.filter(attr => !attr.isAutoLink()).length;
-    }
-
-    get targetRelationCountIncludingLinks() {
-        return this.targetRelations.length;
-    }
-
-    get attributeCount() {
-        return this.getAttributes().length;
-    }
-
-    get ownedAttributeCount() {
-        return this.getAttributes().length;
-    }
-
-    /** @returns {BNote[]} */
-    getAncestors() {
-        if (!this.ancestorCache) {
-            const noteIds = new Set();
-            this.ancestorCache = [];
-
-            for (const parent of this.parents) {
-                if (noteIds.has(parent.noteId)) {
-                    continue;
-                }
-
-                this.ancestorCache.push(parent);
-                noteIds.add(parent.noteId);
-
-                for (const ancestorNote of parent.getAncestors()) {
-                    if (!noteIds.has(ancestorNote.noteId)) {
-                        this.ancestorCache.push(ancestorNote);
-                        noteIds.add(ancestorNote.noteId);
-                    }
-                }
-            }
-        }
-
-        return this.ancestorCache;
-    }
-
-    /** @returns {boolean} */
-    hasAncestor(ancestorNoteId) {
-        for (const ancestorNote of this.getAncestors()) {
-            if (ancestorNote.noteId === ancestorNoteId) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    isInHiddenSubtree() {
-        return this.noteId === '_hidden' || this.hasAncestor('_hidden');
-    }
-
-    getTargetRelations() {
-        return this.targetRelations;
-    }
-
-    /** @returns {BNote[]} - returns only notes which are templated, does not include their subtrees
-     *                     in effect returns notes which are influenced by note's non-inheritable attributes */
-    getTemplatedNotes() {
-        const arr = [this];
-
-        for (const targetRelation of this.targetRelations) {
-            if (targetRelation.name === 'template') {
-                const note = targetRelation.note;
-
-                if (note) {
-                    arr.push(note);
-                }
-            }
-        }
-
-        return arr;
-    }
-
-    getDistanceToAncestor(ancestorNoteId) {
-        if (this.noteId === ancestorNoteId) {
-            return 0;
-        }
-
-        let minDistance = 999999;
-
-        for (const parent of this.parents) {
-            minDistance = Math.min(minDistance, parent.getDistanceToAncestor(ancestorNoteId) + 1);
-        }
-
-        return minDistance;
-    }
-
-    getNoteRevisions() {
-        return sql.getRows("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId])
-            .map(row => new BNoteRevision(row));
-    }
-
-    /**
-     * @return {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path)
-     */
-    getAllNotePaths() {
-        if (this.noteId === 'root') {
-            return [['root']];
-        }
-
-        const notePaths = [];
-
-        for (const parentNote of this.getParentNotes()) {
-            for (const parentPath of parentNote.getAllNotePaths()) {
-                parentPath.push(this.noteId);
-                notePaths.push(parentPath);
-            }
-        }
-
-        return notePaths;
-    }
-
-    /**
-     * @param ancestorNoteId
-     * @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
-     */
-    isDescendantOfNote(ancestorNoteId) {
-        const notePaths = this.getAllNotePaths();
-
-        return notePaths.some(path => path.includes(ancestorNoteId));
-    }
-
-    /**
-     * Update's given attribute's value or creates it if it doesn't exist
-     *
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value (optional)
-     */
-    setAttribute(type, name, value) {
-        const attributes = this.getOwnedAttributes();
-        const attr = attributes.find(attr => attr.type === type && attr.name === name);
-
-        value = value?.toString() || "";
-
-        if (attr) {
-            if (attr.value !== value) {
-                attr.value = value;
-                attr.save();
-            }
-        }
-        else {
-            const BAttribute = require("./battribute");
-
-            new BAttribute({
-                noteId: this.noteId,
-                type: type,
-                name: name,
-                value: value
-            }).save();
-        }
-    }
-
-    /**
-     * Removes given attribute name-value pair if it exists.
-     *
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value (optional)
-     */
-    removeAttribute(type, name, value) {
-        const attributes = this.getOwnedAttributes();
-
-        for (const attribute of attributes) {
-            if (attribute.type === type && attribute.name === name && (value === undefined || value === attribute.value)) {
-                attribute.markAsDeleted();
-            }
-        }
-    }
-
-    /**
-     * Adds a new attribute to this note. The attribute is saved and returned.
-     * See addLabel, addRelation for more specific methods.
-     *
-     * @param {string} type - attribute type (label / relation)
-     * @param {string} name - name of the attribute, not including the leading ~/#
-     * @param {string} [value] - value of the attribute - text for labels, target note ID for relations; optional.
-     * @param {boolean} [isInheritable=false]
-     * @param {int} [position]
-     * @return {Attribute}
-     */
-    addAttribute(type, name, value = "", isInheritable = false, position = 1000) {
-        const BAttribute = require("./battribute");
-
-        return new Attribute({
-            noteId: this.noteId,
-            type: type,
-            name: name,
-            value: value,
-            isInheritable: isInheritable,
-            position: position
-        }).save();
-    }
-
-    /**
-     * Adds a new label to this note. The label attribute is saved and returned.
-     *
-     * @param {string} name - name of the label, not including the leading #
-     * @param {string} [value] - text value of the label; optional
-     * @param {boolean} [isInheritable=false]
-     * @return {Attribute}
-     */
-    addLabel(name, value = "", isInheritable = false) {
-        return this.addAttribute(LABEL, name, value, isInheritable);
-    }
-
-    /**
-     * Adds a new relation to this note. The relation attribute is saved and
-     * returned.
-     *
-     * @param {string} name - name of the relation, not including the leading ~
-     * @param {string} targetNoteId
-     * @param {boolean} [isInheritable=false]
-     * @return {Attribute}
-     */
-    addRelation(name, targetNoteId, isInheritable = false) {
-        return this.addAttribute(RELATION, name, targetNoteId, isInheritable);
-    }
-
-    /**
-     * Based on enabled, attribute is either set or removed.
-     *
-     * @param {string} type - attribute type ('relation', 'label' etc.)
-     * @param {boolean} enabled - toggle On or Off
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value (optional)
-     */
-    toggleAttribute(type, enabled, name, value) {
-        if (enabled) {
-            this.setAttribute(type, name, value);
-        }
-        else {
-            this.removeAttribute(type, name, value);
-        }
-    }
-
-    /**
-     * Based on enabled, label is either set or removed.
-     *
-     * @param {boolean} enabled - toggle On or Off
-     * @param {string} name - label name
-     * @param {string} [value] - label value (optional)
-     */
-    toggleLabel(enabled, name, value) { return this.toggleAttribute(LABEL, enabled, name, value); }
-
-    /**
-     * Based on enabled, relation is either set or removed.
-     *
-     * @param {boolean} enabled - toggle On or Off
-     * @param {string} name - relation name
-     * @param {string} [value] - relation value (noteId)
-     */
-    toggleRelation(enabled, name, value) { return this.toggleAttribute(RELATION, enabled, name, value); }
-
-    /**
-     * Update's given label's value or creates it if it doesn't exist
-     *
-     * @param {string} name - label name
-     * @param {string} [value] - label value
-     */
-    setLabel(name, value) { return this.setAttribute(LABEL, name, value); }
-
-    /**
-     * Update's given relation's value or creates it if it doesn't exist
-     *
-     * @param {string} name - relation name
-     * @param {string} value - relation value (noteId)
-     */
-    setRelation(name, value) { return this.setAttribute(RELATION, name, value); }
-
-    /**
-     * Remove label name-value pair, if it exists.
-     *
-     * @param {string} name - label name
-     * @param {string} [value] - label value
-     */
-    removeLabel(name, value) { return this.removeAttribute(LABEL, name, value); }
-
-    /**
-     * Remove relation name-value pair, if it exists.
-     *
-     * @param {string} name - relation name
-     * @param {string} [value] - relation value (noteId)
-     */
-    removeRelation(name, value) { return this.removeAttribute(RELATION, name, value); }
-
-    searchNotesInSubtree(searchString) {
-        const searchService = require("../../services/search/services/search");
-
-        return searchService.searchNotes(searchString);
-    }
-
-    searchNoteInSubtree(searchString) {
-        return this.searchNotesInSubtree(searchString)[0];
-    }
-
-    /**
-     * @param parentNoteId
-     * @returns {{success: boolean, message: string}}
-     */
-    cloneTo(parentNoteId) {
-        const cloningService = require("../../services/cloning");
-
-        const branch = this.becca.getNote(parentNoteId).getParentBranches()[0];
-
-        return cloningService.cloneNoteToBranch(this.noteId, branch.branchId);
-    }
-
-    /**
-     * (Soft) delete a note and all its descendants.
-     *
-     * @param {string} [deleteId] - optional delete identified
-     * @param {TaskContext} [taskContext]
-     */
-    deleteNote(deleteId, taskContext) {
-        if (this.isDeleted) {
-            return;
-        }
-
-        if (!deleteId) {
-            deleteId = utils.randomString(10);
-        }
-
-        if (!taskContext) {
-            taskContext = new TaskContext('no-progress-reporting');
-        }
-
-        // needs to be run before branches and attributes are deleted and thus attached relations disappear
-        const handlers = require("../../services/handlers");
-        handlers.runAttachedRelations(this, 'runOnNoteDeletion', this);
-        taskContext.noteDeletionHandlerTriggered = true;
-
-        for (const branch of this.getParentBranches()) {
-            branch.deleteBranch(deleteId, taskContext);
-        }
-    }
-
-    decrypt() {
-        if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
-            try {
-                this.title = protectedSessionService.decryptString(this.title);
-                this.flatTextCache = null;
-
-                this.isDecrypted = true;
-            }
-            catch (e) {
-                log.error(`Could not decrypt note ${this.noteId}: ${e.message} ${e.stack}`);
-            }
-        }
-    }
-
-    isLaunchBarConfig() {
-        return this.type === 'launcher' || ['_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(this.noteId);
-    }
-
-    isOptions() {
-        return this.noteId.startsWith("options");
-    }
-
-    get isDeleted() {
-        return !(this.noteId in this.becca.notes) || this.isBeingDeleted;
-    }
-
-    /**
-     * @return {BNoteRevision|null}
-     */
-    saveNoteRevision() {
-        const content = this.getContent();
-
-        if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) {
-            return null;
-        }
-
-        const contentMetadata = this.getContentMetadata();
-
-        const noteRevision = new BNoteRevision({
-            noteId: this.noteId,
-            // title and text should be decrypted now
-            title: this.title,
-            type: this.type,
-            mime: this.mime,
-            isProtected: this.isProtected,
-            utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified
-                ? this.utcDateModified
-                : contentMetadata.utcDateModified,
-            utcDateCreated: dateUtils.utcNowDateTime(),
-            utcDateModified: dateUtils.utcNowDateTime(),
-            dateLastEdited: this.dateModified > contentMetadata.dateModified
-                ? this.dateModified
-                : contentMetadata.dateModified,
-            dateCreated: dateUtils.localNowDateTime()
-        }, true).save();
-
-        noteRevision.setContent(content);
-
-        return noteRevision;
-    }
-
-    beforeSaving() {
-        super.beforeSaving();
-
-        this.becca.addNote(this.noteId, this);
-
-        this.dateModified = dateUtils.localNowDateTime();
-        this.utcDateModified = dateUtils.utcNowDateTime();
-    }
-
-    getPojo() {
-        return {
-            noteId: this.noteId,
-            title: this.title,
-            isProtected: this.isProtected,
-            type: this.type,
-            mime: this.mime,
-            isDeleted: false,
-            dateCreated: this.dateCreated,
-            dateModified: this.dateModified,
-            utcDateCreated: this.utcDateCreated,
-            utcDateModified: this.utcDateModified
-        };
-    }
-
-    getPojoToSave() {
-        const pojo = this.getPojo();
-
-        if (pojo.isProtected) {
-            if (this.isDecrypted) {
-                pojo.title = protectedSessionService.encrypt(pojo.title);
-            }
-            else {
-                // updating protected note outside of protected session means we will keep original ciphertexts
-                delete pojo.title;
-            }
-        }
-
-        return pojo;
-    }
-}
-
-module.exports = BNote;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_bnote_revision.js.html b/docs/backend_api/becca_entities_bnote_revision.js.html deleted file mode 100644 index 134307c84..000000000 --- a/docs/backend_api/becca_entities_bnote_revision.js.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - JSDoc: Source: becca/entities/bnote_revision.js - - - - - - - - - - -
- -

Source: becca/entities/bnote_revision.js

- - - - - - -
-
-
"use strict";
-
-const protectedSessionService = require('../../services/protected_session');
-const utils = require('../../services/utils');
-const sql = require('../../services/sql');
-const dateUtils = require('../../services/date_utils');
-const becca = require('../becca');
-const entityChangesService = require('../../services/entity_changes');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-
-/**
- * NoteRevision represents snapshot of note's title and content at some point in the past.
- * It's used for seamless note versioning.
- *
- * @extends AbstractBeccaEntity
- */
-class BNoteRevision extends AbstractBeccaEntity {
-    static get entityName() { return "note_revisions"; }
-    static get primaryKeyName() { return "noteRevisionId"; }
-    static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
-
-    constructor(row, titleDecrypted = false) {
-        super();
-
-        /** @type {string} */
-        this.noteRevisionId = row.noteRevisionId;
-        /** @type {string} */
-        this.noteId = row.noteId;
-        /** @type {string} */
-        this.type = row.type;
-        /** @type {string} */
-        this.mime = row.mime;
-        /** @type {boolean} */
-        this.isProtected = !!row.isProtected;
-        /** @type {string} */
-        this.title = row.title;
-        /** @type {string} */
-        this.dateLastEdited = row.dateLastEdited;
-        /** @type {string} */
-        this.dateCreated = row.dateCreated;
-        /** @type {string} */
-        this.utcDateLastEdited = row.utcDateLastEdited;
-        /** @type {string} */
-        this.utcDateCreated = row.utcDateCreated;
-        /** @type {string} */
-        this.utcDateModified = row.utcDateModified;
-        /** @type {number} */
-        this.contentLength = row.contentLength;
-
-        if (this.isProtected && !titleDecrypted) {
-            this.title = protectedSessionService.isProtectedSessionAvailable()
-                ? protectedSessionService.decryptString(this.title)
-                : "[protected]";
-        }
-    }
-
-    getNote() {
-        return becca.notes[this.noteId];
-    }
-
-    /** @returns {boolean} true if the note has string content (not binary) */
-    isStringNote() {
-        return utils.isStringNote(this.type, this.mime);
-    }
-
-    /*
-     * Note revision content has quite special handling - it's not a separate entity, but a lazily loaded
-     * part of NoteRevision entity with its own sync. Reason behind this hybrid design is that
-     * content can be quite large, and it's not necessary to load it / fill memory for any note access even
-     * if we don't need a content, especially for bulk operations like search.
-     *
-     * This is the same approach as is used for Note's content.
-     */
-
-    /** @returns {*} */
-    getContent(silentNotFoundError = false) {
-        const res = sql.getRow(`SELECT content FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
-
-        if (!res) {
-            if (silentNotFoundError) {
-                return undefined;
-            }
-            else {
-                throw new Error(`Cannot find note revision content for noteRevisionId=${this.noteRevisionId}`);
-            }
-        }
-
-        let content = res.content;
-
-        if (this.isProtected) {
-            if (protectedSessionService.isProtectedSessionAvailable()) {
-                content = protectedSessionService.decrypt(content);
-            }
-            else {
-                content = "";
-            }
-        }
-
-        if (this.isStringNote()) {
-            return content === null
-                ? ""
-                : content.toString("UTF-8");
-        }
-        else {
-            return content;
-        }
-    }
-
-    setContent(content, ignoreMissingProtectedSession = false) {
-        const pojo = {
-            noteRevisionId: this.noteRevisionId,
-            content: content,
-            utcDateModified: dateUtils.utcNowDateTime()
-        };
-
-        if (this.isProtected) {
-            if (protectedSessionService.isProtectedSessionAvailable()) {
-                pojo.content = protectedSessionService.encrypt(pojo.content);
-            }
-            else if (!ignoreMissingProtectedSession) {
-                throw new Error(`Cannot update content of noteRevisionId=${this.noteRevisionId} since we're out of protected session.`);
-            }
-        }
-
-        sql.upsert("note_revision_contents", "noteRevisionId", pojo);
-
-        const hash = utils.hash(`${this.noteRevisionId}|${pojo.content.toString()}`);
-
-        entityChangesService.addEntityChange({
-            entityName: 'note_revision_contents',
-            entityId: this.noteRevisionId,
-            hash: hash,
-            isErased: false,
-            utcDateChanged: this.getUtcDateChanged(),
-            isSynced: true
-        });
-    }
-
-    /** @returns {{contentLength, dateModified, utcDateModified}} */
-    getContentMetadata() {
-        return sql.getRow(`
-            SELECT 
-                LENGTH(content) AS contentLength, 
-                dateModified,
-                utcDateModified 
-            FROM note_revision_contents 
-            WHERE noteRevisionId = ?`, [this.noteRevisionId]);
-    }
-
-    beforeSaving() {
-        super.beforeSaving();
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-    }
-
-    getPojo() {
-        return {
-            noteRevisionId: this.noteRevisionId,
-            noteId: this.noteId,
-            type: this.type,
-            mime: this.mime,
-            isProtected: this.isProtected,
-            title: this.title,
-            dateLastEdited: this.dateLastEdited,
-            dateCreated: this.dateCreated,
-            utcDateLastEdited: this.utcDateLastEdited,
-            utcDateCreated: this.utcDateCreated,
-            utcDateModified: this.utcDateModified,
-            content: this.content,
-            contentLength: this.contentLength
-        };
-    }
-
-    getPojoToSave() {
-        const pojo = this.getPojo();
-        delete pojo.content; // not getting persisted
-        delete pojo.contentLength; // not getting persisted
-
-        if (pojo.isProtected) {
-            if (protectedSessionService.isProtectedSessionAvailable()) {
-                pojo.title = protectedSessionService.encrypt(this.title);
-            }
-            else {
-                // updating protected note outside of protected session means we will keep original ciphertexts
-                delete pojo.title;
-            }
-        }
-
-        return pojo;
-    }
-}
-
-module.exports = BNoteRevision;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_boption.js.html b/docs/backend_api/becca_entities_boption.js.html deleted file mode 100644 index 3a35c6105..000000000 --- a/docs/backend_api/becca_entities_boption.js.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - JSDoc: Source: becca/entities/boption.js - - - - - - - - - - -
- -

Source: becca/entities/boption.js

- - - - - - -
-
-
"use strict";
-
-const dateUtils = require('../../services/date_utils');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-
-/**
- * Option represents name-value pair, either directly configurable by the user or some system property.
- *
- * @extends AbstractBeccaEntity
- */
-class BOption extends AbstractBeccaEntity {
-    static get entityName() { return "options"; }
-    static get primaryKeyName() { return "name"; }
-    static get hashedProperties() { return ["name", "value"]; }
-
-    constructor(row) {
-        super();
-
-        /** @type {string} */
-        this.name = row.name;
-        /** @type {string} */
-        this.value = row.value;
-        /** @type {boolean} */
-        this.isSynced = !!row.isSynced;
-        /** @type {string} */
-        this.utcDateModified = row.utcDateModified;
-
-        this.becca.options[this.name] = this;
-    }
-
-    beforeSaving() {
-        super.beforeSaving();
-
-        this.utcDateModified = dateUtils.utcNowDateTime();
-    }
-
-    getPojo() {
-        return {
-            name: this.name,
-            value: this.value,
-            isSynced: this.isSynced,
-            utcDateModified: this.utcDateModified
-        }
-    }
-}
-
-module.exports = BOption;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/becca_entities_brecent_note.js.html b/docs/backend_api/becca_entities_brecent_note.js.html deleted file mode 100644 index 359c20669..000000000 --- a/docs/backend_api/becca_entities_brecent_note.js.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - JSDoc: Source: becca/entities/brecent_note.js - - - - - - - - - - -
- -

Source: becca/entities/brecent_note.js

- - - - - - -
-
-
"use strict";
-
-const dateUtils = require('../../services/date_utils');
-const AbstractBeccaEntity = require("./abstract_becca_entity");
-
-/**
- * RecentNote represents recently visited note.
- *
- * @extends AbstractBeccaEntity
- */
-class BRecentNote extends AbstractBeccaEntity {
-    static get entityName() { return "recent_notes"; }
-    static get primaryKeyName() { return "noteId"; }
-
-    constructor(row) {
-        super();
-
-        /** @type {string} */
-        this.noteId = row.noteId;
-        /** @type {string} */
-        this.notePath = row.notePath;
-        /** @type {string} */
-        this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime();
-    }
-
-    getPojo() {
-        return {
-            noteId: this.noteId,
-            notePath: this.notePath,
-            utcDateCreated: this.utcDateCreated
-        }
-    }
-}
-
-module.exports = BRecentNote;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/global.html b/docs/backend_api/global.html deleted file mode 100644 index 099cb2d0b..000000000 --- a/docs/backend_api/global.html +++ /dev/null @@ -1,1726 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
- -

Global

- - - - - - -
- -
- -

- - -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - - - - - -

Type Definitions

- - - -

CreateNewNoteParams

- - - - - - -
Type:
-
    -
  • - -object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
parentNoteId - - -string - - - - MANDATORY
title - - -string - - - - MANDATORY
content - - -string -| - -buffer - - - - MANDATORY
type - - -string - - - - text, code, file, image, search, book, relationMap, canvas - MANDATORY
mime - - -string - - - - value is derived from default mimes for type
isProtected - - -boolean - - - - default is false
isExpanded - - -boolean - - - - default is false
prefix - - -string - - - - default is empty string
notePosition - - -int - - - - default is last existing notePosition in a parent + 10
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

CreateNoteAttribute

- - - - - - -
Type:
-
    -
  • - -object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
type - - -string - - - - - - - - attribute type - label, relation etc.
name - - -string - - - - - - - - attribute name
value - - -string - - - - - - <optional>
- - - -
attribute value
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

CreateNoteAttribute

- - - - - - -
Type:
-
    -
  • - -object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
type - - -string - - - - - - - - attribute type - label, relation etc.
name - - -string - - - - - - - - attribute name
value - - -string - - - - - - <optional>
- - - -
attribute value
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

CreateNoteExtraOptions

- - - - - - -
Type:
-
    -
  • - -object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDefaultDescription
json - - -boolean - - - - - - <optional>
- - - -
- - false - - should the note be JSON
isProtected - - -boolean - - - - - - <optional>
- - - -
- - false - - should the note be protected
type - - -string - - - - - - <optional>
- - - -
- - 'text' - - note type
mime - - -string - - - - - - <optional>
- - - -
- - 'text/html' - - MIME type of the note
attributes - - -Array.<CreateNoteAttribute> - - - - - - <optional>
- - - -
- - [] - - attributes to be created for this note
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

CreateOrUpdateLauncher

- - - - - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDefaultDescription
id - - -string - - - - - - - - - - id of the launcher, only alphanumeric at least 6 characters long
type - - -string - - - - - - - - - - one of - * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param) - * "script" - activating the launcher will execute the script (specified in scriptNoteId param) - * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param)
title - - -string - - - - - - - - - -
isVisible - - -boolean - - - - - - <optional>
- - - -
- - false - - if true, will be created in the "Visible launchers", otherwise in "Available launchers"
icon - - -string - - - - - - <optional>
- - - -
- - name of the boxicon to be used (e.g. "bx-time")
keyboardShortcut - - -string - - - - - - <optional>
- - - -
- - will activate the target note/script upon pressing, e.g. "ctrl+e"
targetNoteId - - -string - - - - - - <optional>
- - - -
- - for type "note"
scriptNoteId - - -string - - - - - - <optional>
- - - -
- - for type "script"
widgetNoteId - - -string - - - - - - <optional>
- - - -
- - for type "customWidget"
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

SortConfig

- - - - - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDefaultDescription
sortBy - - -string - - - - - - <optional>
- - - -
- - title - - 'title', 'dateCreated', 'dateModified' or a label name - see https://github.com/zadam/trilium/wiki/Sorting for details.
reverse - - -boolean - - - - - - <optional>
- - - -
- - false - -
foldersFirst - - -boolean - - - - - - <optional>
- - - -
- - false - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/docs/backend_api/index.html b/docs/backend_api/index.html index 7171d3635..455fa5fdc 100644 --- a/docs/backend_api/index.html +++ b/docs/backend_api/index.html @@ -50,7 +50,7 @@
diff --git a/docs/backend_api/module-sql.html b/docs/backend_api/module-sql.html index 1716e1a65..73bde2df5 100644 --- a/docs/backend_api/module-sql.html +++ b/docs/backend_api/module-sql.html @@ -64,11 +64,6 @@ - -
Source:
-
@@ -247,11 +242,6 @@ - -
Source:
-
@@ -427,11 +417,6 @@ - -
Source:
-
@@ -629,11 +614,6 @@ - -
Source:
-
@@ -831,11 +811,6 @@ - -
Source:
-
@@ -1033,11 +1008,6 @@ - -
Source:
-
@@ -1235,11 +1205,6 @@ - -
Source:
-
@@ -1294,7 +1259,7 @@
diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html deleted file mode 100644 index 9be900162..000000000 --- a/docs/backend_api/services_backend_script_api.js.html +++ /dev/null @@ -1,636 +0,0 @@ - - - - - JSDoc: Source: services/backend_script_api.js - - - - - - - - - - -
- -

Source: services/backend_script_api.js

- - - - - - -
-
-
const log = require('./log');
-const noteService = require('./notes');
-const sql = require('./sql');
-const utils = require('./utils');
-const attributeService = require('./attributes');
-const dateNoteService = require('./date_notes');
-const treeService = require('./tree');
-const config = require('./config');
-const axios = require('axios');
-const dayjs = require('dayjs');
-const xml2js = require('xml2js');
-const cloningService = require('./cloning');
-const appInfo = require('./app_info');
-const searchService = require('./search/services/search');
-const SearchContext = require("./search/search_context");
-const becca = require("../becca/becca");
-const ws = require("./ws");
-const SpacedUpdate = require("./spaced_update");
-const specialNotesService = require("./special_notes");
-const branchService = require("./branches");
-const exportService = require("./export/zip");
-
-/**
- * This is the main backend API interface for scripts. It's published in the local "api" object.
- *
- * @constructor
- * @hideconstructor
- */
-function BackendScriptApi(currentNote, apiParams) {
-    /** @property {BNote} note where script started executing */
-    this.startNote = apiParams.startNote;
-    /** @property {BNote} note where script is currently executing. Don't mix this up with concept of active note */
-    this.currentNote = currentNote;
-    /** @property {Entity} entity whose event triggered this executions */
-    this.originEntity = apiParams.originEntity;
-
-    for (const key in apiParams) {
-        this[key] = apiParams[key];
-    }
-
-    /** @property {axios} Axios library for HTTP requests. See https://axios-http.com/ for documentation */
-    this.axios = axios;
-    /** @property {dayjs} day.js library for date manipulation. See https://day.js.org/ for documentation */
-    this.dayjs = dayjs;
-    /** @property {axios} xml2js library for XML parsing. See https://github.com/Leonidas-from-XIV/node-xml2js for documentation */
-    this.xml2js = xml2js;
-
-    // DEPRECATED - use direct api.unescapeHtml
-    this.utils = {
-        unescapeHtml: utils.unescapeHtml
-    };
-
-    /**
-     * Instance name identifies particular Trilium instance. It can be useful for scripts
-     * if some action needs to happen on only one specific instance.
-     *
-     * @returns {string|null}
-     */
-    this.getInstanceName = () => config.General ? config.General.instanceName : null;
-
-    /**
-     * @method
-     * @param {string} noteId
-     * @returns {BNote|null}
-     */
-    this.getNote = noteId => becca.getNote(noteId);
-
-    /**
-     * @method
-     * @param {string} branchId
-     * @returns {Branch|null}
-     */
-    this.getBranch = branchId => becca.getBranch(branchId);
-
-    /**
-     * @method
-     * @param {string} attributeId
-     * @returns {Attribute|null}
-     */
-    this.getAttribute = attributeId => becca.getAttribute(attributeId);
-
-    /**
-     * This is a powerful search method - you can search by attributes and their values, e.g.:
-     * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
-     *
-     * @method
-     * @param {string} query
-     * @param {Object} [searchParams]
-     * @returns {BNote[]}
-     */
-    this.searchForNotes = (query, searchParams = {}) => {
-        if (searchParams.includeArchivedNotes === undefined) {
-            searchParams.includeArchivedNotes = true;
-        }
-
-        if (searchParams.ignoreHoistedNote === undefined) {
-            searchParams.ignoreHoistedNote = true;
-        }
-
-        const noteIds = searchService.findResultsWithQuery(query, new SearchContext(searchParams))
-            .map(sr => sr.noteId);
-
-        return becca.getNotes(noteIds);
-    };
-
-    /**
-     * This is a powerful search method - you can search by attributes and their values, e.g.:
-     * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
-     *
-     * @method
-     * @param {string} query
-     * @param {Object} [searchParams]
-     * @returns {BNote|null}
-     */
-    this.searchForNote = (query, searchParams = {}) => {
-        const notes = this.searchForNotes(query, searchParams);
-
-        return notes.length > 0 ? notes[0] : null;
-    };
-
-    /**
-     * Retrieves notes with given label name & value
-     *
-     * @method
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value
-     * @returns {BNote[]}
-     */
-    this.getNotesWithLabel = attributeService.getNotesWithLabel;
-
-    /**
-     * Retrieves first note with given label name & value
-     *
-     * @method
-     * @param {string} name - attribute name
-     * @param {string} [value] - attribute value
-     * @returns {BNote|null}
-     */
-    this.getNoteWithLabel = attributeService.getNoteWithLabel;
-
-    /**
-     * If there's no branch between note and parent note, create one. Otherwise, do nothing.
-     *
-     * @method
-     * @param {string} noteId
-     * @param {string} parentNoteId
-     * @param {string} prefix - if branch will be created between note and parent note, set this prefix
-     * @returns {void}
-     */
-    this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent;
-
-    /**
-     * If there's a branch between note and parent note, remove it. Otherwise, do nothing.
-     *
-     * @method
-     * @param {string} noteId
-     * @param {string} parentNoteId
-     * @returns {void}
-     */
-    this.ensureNoteIsAbsentFromParent = cloningService.ensureNoteIsAbsentFromParent;
-
-    /**
-     * Based on the value, either create or remove branch between note and parent note.
-     *
-     * @method
-     * @param {boolean} present - true if we want the branch to exist, false if we want it gone
-     * @param {string} noteId
-     * @param {string} parentNoteId
-     * @param {string} prefix - if branch will be created between note and parent note, set this prefix
-     * @returns {void}
-     */
-    this.toggleNoteInParent = cloningService.toggleNoteInParent;
-
-    /**
-     * @typedef {object} CreateNoteAttribute
-     * @property {string} type - attribute type - label, relation etc.
-     * @property {string} name - attribute name
-     * @property {string} [value] - attribute value
-     */
-
-    /**
-     * Create text note. See also createNewNote() for more options.
-     *
-     * @param {string} parentNoteId
-     * @param {string} title
-     * @param {string} content
-     * @return {{note: BNote, branch: Branch}} - object having "note" and "branch" keys representing respective objects
-     */
-    this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({
-        parentNoteId,
-        title,
-        content,
-        type: 'text'
-    });
-
-    /**
-     * Create data note - data in this context means object serializable to JSON. Created note will be of type 'code' and
-     * JSON MIME type. See also createNewNote() for more options.
-     *
-     * @param {string} parentNoteId
-     * @param {string} title
-     * @param {object} content
-     * @return {{note: BNote, branch: Branch}} object having "note" and "branch" keys representing respective objects
-     */
-    this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({
-        parentNoteId,
-        title,
-        content: JSON.stringify(content, null, '\t'),
-        type: 'code',
-        mime: 'application/json'
-    });
-
-    /**
-     * @typedef {object} CreateNewNoteParams
-     * @property {string} parentNoteId - MANDATORY
-     * @property {string} title - MANDATORY
-     * @property {string|buffer} content - MANDATORY
-     * @property {string} type - text, code, file, image, search, book, relationMap, canvas - MANDATORY
-     * @property {string} mime - value is derived from default mimes for type
-     * @property {boolean} isProtected - default is false
-     * @property {boolean} isExpanded - default is false
-     * @property {string} prefix - default is empty string
-     * @property {int} notePosition - default is last existing notePosition in a parent + 10
-     */
-
-    /**
-     * @method
-     *
-     * @param {CreateNewNoteParams} [params]
-     * @returns {{note: BNote, branch: Branch}} object contains newly created entities note and branch
-     */
-    this.createNewNote = noteService.createNewNote;
-
-    /**
-     * @typedef {object} CreateNoteAttribute
-     * @property {string} type - attribute type - label, relation etc.
-     * @property {string} name - attribute name
-     * @property {string} [value] - attribute value
-     */
-
-    /**
-     * @typedef {object} CreateNoteExtraOptions
-     * @property {boolean} [json=false] - should the note be JSON
-     * @property {boolean} [isProtected=false] - should the note be protected
-     * @property {string} [type='text'] - note type
-     * @property {string} [mime='text/html'] - MIME type of the note
-     * @property {CreateNoteAttribute[]} [attributes=[]] - attributes to be created for this note
-     */
-
-    /**
-     * @method
-     * @deprecated please use createTextNote() with similar API for simpler use cases or createNewNote() for more complex needs
-     *
-     * @param {string} parentNoteId - create new note under this parent
-     * @param {string} title
-     * @param {string} [content=""]
-     * @param {CreateNoteExtraOptions} [extraOptions={}]
-     * @returns {{note: BNote, branch: Branch}} object contains newly created entities note and branch
-     */
-    this.createNote = (parentNoteId, title, content = "", extraOptions= {}) => {
-        extraOptions.parentNoteId = parentNoteId;
-        extraOptions.title = title;
-
-        const parentNote = becca.getNote(parentNoteId);
-
-        // code note type can be inherited, otherwise text is default
-        extraOptions.type = parentNote.type === 'code' ? 'code' : 'text';
-        extraOptions.mime = parentNote.type === 'code' ? parentNote.mime : 'text/html';
-
-        if (extraOptions.json) {
-            extraOptions.content = JSON.stringify(content || {}, null, '\t');
-            extraOptions.type = 'code';
-            extraOptions.mime = 'application/json';
-        }
-        else {
-            extraOptions.content = content;
-        }
-
-        return sql.transactional(() => {
-            const {note, branch} = noteService.createNewNote(extraOptions);
-
-            for (const attr of extraOptions.attributes || []) {
-                attributeService.createAttribute({
-                    noteId: note.noteId,
-                    type: attr.type,
-                    name: attr.name,
-                    value: attr.value,
-                    isInheritable: !!attr.isInheritable
-                });
-            }
-
-            return {note, branch};
-        });
-    };
-
-    this.logMessages = {};
-    this.logSpacedUpdates = {};
-
-    /**
-     * Log given message to trilium logs and log pane in UI
-     *
-     * @param message
-     */
-    this.log = message => {
-        log.info(message);
-
-        const {noteId} = this.startNote;
-
-        this.logMessages[noteId] = this.logMessages[noteId] || [];
-        this.logSpacedUpdates[noteId] = this.logSpacedUpdates[noteId] || new SpacedUpdate(() => {
-            const messages = this.logMessages[noteId];
-            this.logMessages[noteId] = [];
-
-            ws.sendMessageToAllClients({
-                type: 'api-log-messages',
-                noteId,
-                messages
-            });
-        }, 100);
-
-        this.logMessages[noteId].push(message);
-        this.logSpacedUpdates[noteId].scheduleUpdate();
-    };
-
-    /**
-     * Returns root note of the calendar.
-     *
-     * @method
-     * @returns {BNote|null}
-     */
-    this.getRootCalendarNote = dateNoteService.getRootCalendarNote;
-
-    /**
-     * Returns day note for given date. If such note doesn't exist, it is created.
-     *
-     * @method
-     * @param {string} date in YYYY-MM-DD format
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     * @deprecated use getDayNote instead
-     */
-    this.getDateNote = dateNoteService.getDayNote;
-
-    /**
-     * Returns day note for given date. If such note doesn't exist, it is created.
-     *
-     * @method
-     * @param {string} date in YYYY-MM-DD format
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     */
-    this.getDayNote = dateNoteService.getDayNote;
-
-    /**
-     * Returns today's day note. If such note doesn't exist, it is created.
-     *
-     * @method
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     */
-    this.getTodayNote = dateNoteService.getTodayNote;
-
-    /**
-     * Returns note for the first date of the week of the given date.
-     *
-     * @method
-     * @param {string} date in YYYY-MM-DD format
-     * @param {object} [options] - "startOfTheWeek" - either "monday" (default) or "sunday"
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     */
-    this.getWeekNote = dateNoteService.getWeekNote;
-
-    /**
-     * Returns month note for given date. If such note doesn't exist, it is created.
-     *
-     * @method
-     * @param {string} date in YYYY-MM format
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     */
-    this.getMonthNote = dateNoteService.getMonthNote;
-
-    /**
-     * Returns year note for given year. If such note doesn't exist, it is created.
-     *
-     * @method
-     * @param {string} year in YYYY format
-     * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar
-     * @returns {BNote|null}
-     */
-    this.getYearNote = dateNoteService.getYearNote;
-
-    /**
-     * @method
-     * @deprecated - use sortNotes instead
-     * @param {string} parentNoteId - this note's child notes will be sorted
-     */
-    this.sortNotesByTitle = parentNoteId => treeService.sortNotes(parentNoteId);
-
-    /**
-     * @typedef {Object} SortConfig
-     * @property {string} [sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name
-     *                               see https://github.com/zadam/trilium/wiki/Sorting for details.
-     * @property {boolean} [reverse=false]
-     * @property {boolean} [foldersFirst=false]
-     */
-
-    /**
-     * Sort child notes of a given note.
-     *
-     * @method
-     * @param {string} parentNoteId - this note's child notes will be sorted
-     * @param {SortConfig} [sortConfig]
-     */
-    this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes(
-        parentNoteId,
-        sortConfig.sortBy || "title",
-        !!sortConfig.reverse,
-        !!sortConfig.foldersFirst
-    );
-
-    /**
-     * This method finds note by its noteId and prefix and either sets it to the given parentNoteId
-     * or removes the branch (if parentNoteId is not given).
-     *
-     * This method looks similar to toggleNoteInParent() but differs because we're looking up branch by prefix.
-     *
-     * @method
-     * @deprecated - this method is pretty confusing and serves specialized purpose only
-     * @param {string} noteId
-     * @param {string} prefix
-     * @param {string|null} parentNoteId
-     */
-    this.setNoteToParent = treeService.setNoteToParent;
-
-    /**
-     * This functions wraps code which is supposed to be running in transaction. If transaction already
-     * exists, then we'll use that transaction.
-     *
-     * @method
-     * @param {function} func
-     * @returns {?} result of func callback
-     */
-    this.transactional = sql.transactional;
-
-    /**
-     * Return randomly generated string of given length. This random string generation is NOT cryptographically secure.
-     *
-     * @method
-     * @param {number} length of the string
-     * @returns {string} random string
-     */
-    this.randomString = utils.randomString;
-
-    /**
-     * @method
-     * @param {string} string to escape
-     * @returns {string} escaped string
-     */
-    this.escapeHtml = utils.escapeHtml;
-
-    /**
-     * @method
-     * @param {string} string to unescape
-     * @returns {string} unescaped string
-     */
-    this.unescapeHtml = utils.unescapeHtml;
-
-    /**
-     * @property {module:sql} sql
-     */
-    this.sql = sql;
-
-    /**
-     * @method
-     * @deprecated - this is now no-op since all the changes should be gracefully handled per widget
-     */
-    this.refreshTree = () => {
-        console.warn("api.refreshTree() is a NO-OP and can be removed from your script.")
-    };
-
-    /**
-     * @return {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version
-     */
-    this.getAppInfo = () => appInfo
-
-    /**
-     * @typedef {Object} CreateOrUpdateLauncher
-     * @property {string} id - id of the launcher, only alphanumeric at least 6 characters long
-     * @property {string} type - one of
-     *                          * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param)
-     *                          * "script" -  activating the launcher will execute the script (specified in scriptNoteId param)
-     *                          * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param)
-     * @property {string} title
-     * @property {boolean} [isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers"
-     * @property {string} [icon] - name of the boxicon to be used (e.g. "bx-time")
-     * @property {string} [keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e"
-     * @property {string} [targetNoteId] - for type "note"
-     * @property {string} [scriptNoteId] - for type "script"
-     * @property {string} [widgetNoteId] - for type "customWidget"
-     */
-
-    /**
-     * Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated.
-     *
-     * @param {CreateOrUpdateLauncher} opts
-     */
-    this.createOrUpdateLauncher = opts => {
-        if (!opts.id) { throw new Error("ID is a mandatory parameter for api.createOrUpdateLauncher(opts)"); }
-        if (!opts.id.match(/[a-z0-9]{6,1000}/i)) { throw new Error(`ID must be an alphanumeric string at least 6 characters long.`); }
-        if (!opts.type) { throw new Error("Launcher Type is a mandatory parameter for api.createOrUpdateLauncher(opts)"); }
-        if (!["note", "script", "customWidget"].includes(opts.type)) { throw new Error(`Given launcher type '${opts.type}'`); }
-        if (!opts.title?.trim()) { throw new Error("Title is a mandatory parameter for api.createOrUpdateLauncher(opts)"); }
-        if (opts.type === 'note' && !opts.targetNoteId) { throw new Error("targetNoteId is mandatory for launchers of type 'note'"); }
-        if (opts.type === 'script' && !opts.scriptNoteId) { throw new Error("scriptNoteId is mandatory for launchers of type 'script'"); }
-        if (opts.type === 'customWidget' && !opts.widgetNoteId) { throw new Error("widgetNoteId is mandatory for launchers of type 'customWidget'"); }
-
-        const parentNoteId = !!opts.isVisible ? '_lbVisibleLaunchers' : '_lbAvailableLaunchers';
-        const noteId = 'al_' + opts.id;
-
-        const launcherNote =
-            becca.getNote(opts.id) ||
-            specialNotesService.createLauncher({
-                noteId: noteId,
-                parentNoteId: parentNoteId,
-                launcherType: opts.type,
-            }).note;
-
-        if (launcherNote.title !== opts.title) {
-            launcherNote.title = opts.title;
-            launcherNote.save();
-        }
-
-        if (launcherNote.getParentBranches().length === 1) {
-            const branch = launcherNote.getParentBranches()[0];
-
-            if (branch.parentNoteId !== parentNoteId) {
-                branchService.moveBranchToNote(branch, parentNoteId);
-            }
-        }
-
-        if (opts.type === 'note') {
-            launcherNote.setRelation('target', opts.targetNoteId);
-        } else if (opts.type === 'script') {
-            launcherNote.setRelation('script', opts.scriptNoteId);
-        } else if (opts.type === 'customWidget') {
-            launcherNote.setRelation('widget', opts.widgetNoteId);
-        } else {
-            throw new Error(`Unrecognized launcher type '${opts.type}'`);
-        }
-
-        if (opts.keyboardShortcut) {
-            launcherNote.setLabel('keyboardShortcut', opts.keyboardShortcut);
-        } else {
-            launcherNote.removeLabel('keyboardShortcut');
-        }
-
-        if (opts.icon) {
-            launcherNote.setLabel('iconClass', `bx ${opts.icon}`);
-        } else {
-            launcherNote.removeLabel('keyboardShortcut');
-        }
-    };
-
-    /**
-     * @method
-     * @param {string} noteId
-     * @param {string} format - either 'html' or 'markdown'
-     * @param {string} zipFilePath
-     * @returns {Promise}
-     */
-    this.exportSubtreeToZipFile = async (noteId, format, zipFilePath) => await exportService.exportToZipFile(noteId, format, zipFilePath);
-
-    /**
-     * This object contains "at your risk" and "no BC guarantees" objects for advanced use cases.
-     *
-     * @type {{becca: Becca}}
-     */
-    this.__private = {
-        becca
-    }
-}
-
-module.exports = BackendScriptApi;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/backend_api/services_sql.js.html b/docs/backend_api/services_sql.js.html deleted file mode 100644 index 66ec0b8fc..000000000 --- a/docs/backend_api/services_sql.js.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - JSDoc: Source: services/sql.js - - - - - - - - - - -
- -

Source: services/sql.js

- - - - - - -
-
-
"use strict";
-
-/**
- * @module sql
- */
-
-const log = require('./log');
-const Database = require('better-sqlite3');
-const dataDir = require('./data_dir');
-const cls = require('./cls');
-const fs = require("fs-extra");
-
-const dbConnection = new Database(dataDir.DOCUMENT_PATH);
-dbConnection.pragma('journal_mode = WAL');
-
-const LOG_ALL_QUERIES = false;
-
-[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach(eventType => {
-    process.on(eventType, () => {
-        if (dbConnection) {
-            // closing connection is especially important to fold -wal file into the main DB file
-            // (see https://sqlite.org/tempfiles.html for details)
-            dbConnection.close();
-        }
-    });
-});
-
-function insert(tableName, rec, replace = false) {
-    const keys = Object.keys(rec);
-    if (keys.length === 0) {
-        log.error(`Can't insert empty object into table ${tableName}`);
-        return;
-    }
-
-    const columns = keys.join(", ");
-    const questionMarks = keys.map(p => "?").join(", ");
-
-    const query = `INSERT
-    ${replace ? "OR REPLACE" : ""} INTO
-    ${tableName}
-    (
-    ${columns}
-    )
-    VALUES (${questionMarks})`;
-
-    const res = execute(query, Object.values(rec));
-
-    return res ? res.lastInsertRowid : null;
-}
-
-function replace(tableName, rec) {
-    return insert(tableName, rec, true);
-}
-
-function upsert(tableName, primaryKey, rec) {
-    const keys = Object.keys(rec);
-    if (keys.length === 0) {
-        log.error(`Can't upsert empty object into table ${tableName}`);
-        return;
-    }
-
-    const columns = keys.join(", ");
-
-    const questionMarks = keys.map(colName => `@${colName}`).join(", ");
-
-    const updateMarks = keys.map(colName => `${colName} = @${colName}`).join(", ");
-
-    const query = `INSERT INTO ${tableName} (${columns}) VALUES (${questionMarks}) 
-                   ON CONFLICT (${primaryKey}) DO UPDATE SET ${updateMarks}`;
-
-    for (const idx in rec) {
-        if (rec[idx] === true || rec[idx] === false) {
-            rec[idx] = rec[idx] ? 1 : 0;
-        }
-    }
-
-    execute(query, rec);
-}
-
-const statementCache = {};
-
-function stmt(sql) {
-    if (!(sql in statementCache)) {
-        statementCache[sql] = dbConnection.prepare(sql);
-    }
-
-    return statementCache[sql];
-}
-
-function getRow(query, params = []) {
-    return wrap(query, s => s.get(params));
-}
-
-function getRowOrNull(query, params = []) {
-    const all = getRows(query, params);
-
-    return all.length > 0 ? all[0] : null;
-}
-
-function getValue(query, params = []) {
-    return wrap(query, s => s.pluck().get(params));
-}
-
-// smaller values can result in better performance due to better usage of statement cache
-const PARAM_LIMIT = 100;
-
-function getManyRows(query, params) {
-    let results = [];
-
-    while (params.length > 0) {
-        const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT));
-        params = params.slice(curParams.length);
-
-        const curParamsObj = {};
-
-        let j = 1;
-        for (const param of curParams) {
-            curParamsObj['param' + j++] = param;
-        }
-
-        let i = 1;
-        const questionMarks = curParams.map(() => ":param" + i++).join(",");
-        const curQuery = query.replace(/\?\?\?/g, questionMarks);
-
-        const statement = curParams.length === PARAM_LIMIT
-            ? stmt(curQuery)
-            : dbConnection.prepare(curQuery);
-
-        const subResults = statement.all(curParamsObj);
-        results = results.concat(subResults);
-    }
-
-    return results;
-}
-
-function getRows(query, params = []) {
-    return wrap(query, s => s.all(params));
-}
-
-function getRawRows(query, params = []) {
-    return wrap(query, s => s.raw().all(params));
-}
-
-function iterateRows(query, params = []) {
-    if (LOG_ALL_QUERIES) {
-        console.log(query);
-    }
-
-    return stmt(query).iterate(params);
-}
-
-function getMap(query, params = []) {
-    const map = {};
-    const results = getRawRows(query, params);
-
-    for (const row of results) {
-        map[row[0]] = row[1];
-    }
-
-    return map;
-}
-
-function getColumn(query, params = []) {
-    return wrap(query, s => s.pluck().all(params));
-}
-
-function execute(query, params = []) {
-    return wrap(query, s => s.run(params));
-}
-
-function executeMany(query, params) {
-    if (LOG_ALL_QUERIES) {
-        console.log(query);
-    }
-
-    while (params.length > 0) {
-        const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT));
-        params = params.slice(curParams.length);
-
-        const curParamsObj = {};
-
-        let j = 1;
-        for (const param of curParams) {
-            curParamsObj['param' + j++] = param;
-        }
-
-        let i = 1;
-        const questionMarks = curParams.map(() => ":param" + i++).join(",");
-        const curQuery = query.replace(/\?\?\?/g, questionMarks);
-
-        dbConnection.prepare(curQuery).run(curParamsObj);
-    }
-}
-
-function executeScript(query) {
-    if (LOG_ALL_QUERIES) {
-        console.log(query);
-    }
-
-    return dbConnection.exec(query);
-}
-
-function wrap(query, func) {
-    const startTimestamp = Date.now();
-    let result;
-
-    if (LOG_ALL_QUERIES) {
-        console.log(query);
-    }
-
-    try {
-        result = func(stmt(query));
-    }
-    catch (e) {
-        if (e.message.includes("The database connection is not open")) {
-            // this often happens on killing the app which puts these alerts in front of user
-            // in these cases error should be simply ignored.
-            console.log(e.message);
-
-            return null
-        }
-
-        throw e;
-    }
-
-    const milliseconds = Date.now() - startTimestamp;
-
-    if (milliseconds >= 20) {
-        if (query.includes("WITH RECURSIVE")) {
-            log.info(`Slow recursive query took ${milliseconds}ms.`);
-        }
-        else {
-            log.info(`Slow query took ${milliseconds}ms: ${query.trim().replace(/\s+/g, " ")}`);
-        }
-    }
-
-    return result;
-}
-
-function transactional(func) {
-    try {
-        const ret = dbConnection.transaction(func).deferred();
-
-        if (!dbConnection.inTransaction) { // i.e. transaction was really committed (and not just savepoint released)
-            require('./ws').sendTransactionEntityChangesToAllClients();
-        }
-
-        return ret;
-    }
-    catch (e) {
-        const entityChangeIds = cls.getAndClearEntityChangeIds();
-
-        if (entityChangeIds.length > 0) {
-            log.info("Transaction rollback dirtied the becca, forcing reload.");
-
-            require('../becca/becca_loader').load();
-        }
-
-        throw e;
-    }
-}
-
-function fillParamList(paramIds, truncate = true) {
-    if (paramIds.length === 0) {
-        return;
-    }
-
-    if (truncate) {
-        execute("DELETE FROM param_list");
-    }
-
-    paramIds = Array.from(new Set(paramIds));
-
-    if (paramIds.length > 30000) {
-        fillParamList(paramIds.slice(30000), false);
-
-        paramIds = paramIds.slice(0, 30000);
-    }
-
-    // doing it manually to avoid this showing up on the sloq query list
-    const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`, paramIds);
-
-    s.run(paramIds);
-}
-
-async function copyDatabase(targetFilePath) {
-    try {
-        fs.unlinkSync(targetFilePath);
-    } catch (e) {
-    } // unlink throws exception if the file did not exist
-
-    await dbConnection.backup(targetFilePath);
-}
-
-module.exports = {
-    dbConnection,
-    insert,
-    replace,
-
-    /**
-     * Get single value from the given query - first column from first returned row.
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     * @return [object] - single value
-     */
-    getValue,
-
-    /**
-     * Get first returned row.
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     * @return {object} - map of column name to column value
-     */
-    getRow,
-    getRowOrNull,
-
-    /**
-     * Get all returned rows.
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     * @return {object[]} - array of all rows, each row is a map of column name to column value
-     */
-    getRows,
-    getRawRows,
-    iterateRows,
-    getManyRows,
-
-    /**
-     * Get a map of first column mapping to second column.
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     * @return {object} - map of first column to second column
-     */
-    getMap,
-
-    /**
-     * Get a first column in an array.
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     * @return {object[]} - array of first column of all returned rows
-     */
-    getColumn,
-
-    /**
-     * Execute SQL
-     *
-     * @method
-     * @param {string} query - SQL query with ? used as parameter placeholder
-     * @param {object[]} [params] - array of params if needed
-     */
-    execute,
-    executeMany,
-    executeScript,
-    transactional,
-    upsert,
-    fillParamList,
-    copyDatabase
-};
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/FAttribute.html b/docs/frontend_api/FAttribute.html index 5a1ca75a2..19721bc55 100644 --- a/docs/frontend_api/FAttribute.html +++ b/docs/frontend_api/FAttribute.html @@ -91,11 +91,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -191,11 +186,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -259,11 +249,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -327,11 +312,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -395,11 +375,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -463,11 +438,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -531,11 +501,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -599,11 +564,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -675,11 +635,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -777,11 +732,6 @@ and relation (representing named relationship between source and target note)Source: -
@@ -844,7 +794,7 @@ and relation (representing named relationship between source and target note)
diff --git a/docs/frontend_api/FBranch.html b/docs/frontend_api/FBranch.html index 864cc8008..07792adcb 100644 --- a/docs/frontend_api/FBranch.html +++ b/docs/frontend_api/FBranch.html @@ -91,11 +91,6 @@ parents. - -
Source:
-
@@ -195,11 +190,6 @@ parents. - -
Source:
-
@@ -263,11 +253,6 @@ parents. - -
Source:
-
@@ -331,11 +316,6 @@ parents. - -
Source:
-
@@ -399,11 +379,6 @@ parents. - -
Source:
-
@@ -467,11 +442,6 @@ parents. - -
Source:
-
@@ -535,11 +505,6 @@ parents. - -
Source:
-
@@ -603,11 +568,6 @@ parents. - -
Source:
-
@@ -679,11 +639,6 @@ parents. - -
Source:
-
@@ -781,11 +736,6 @@ parents. - -
Source:
-
@@ -883,11 +833,6 @@ parents. - -
Source:
-
@@ -985,11 +930,6 @@ parents. - -
Source:
-
@@ -1056,7 +996,7 @@ parents.
diff --git a/docs/frontend_api/FNote.html b/docs/frontend_api/FNote.html index 72731a225..a3afeef6e 100644 --- a/docs/frontend_api/FNote.html +++ b/docs/frontend_api/FNote.html @@ -158,11 +158,6 @@ - -
Source:
-
@@ -258,11 +253,6 @@ - -
Source:
-
@@ -326,11 +316,6 @@ - -
Source:
-
@@ -394,11 +379,6 @@ - -
Source:
-
@@ -462,11 +442,6 @@ - -
Source:
-
@@ -534,11 +509,6 @@ - -
Source:
-
@@ -602,11 +572,6 @@ - -
Source:
-
@@ -670,11 +635,6 @@ - -
Source:
-
@@ -738,11 +698,6 @@ - -
Source:
-
@@ -806,11 +761,6 @@ - -
Source:
-
@@ -874,11 +824,6 @@ - -
Source:
-
@@ -946,11 +891,6 @@ - -
Source:
-
@@ -1094,11 +1034,6 @@ - -
Source:
-
@@ -1272,11 +1207,6 @@ - -
Source:
-
@@ -1472,11 +1402,6 @@ - -
Source:
-
@@ -1581,11 +1506,6 @@ -
Source:
-
- @@ -1685,11 +1605,6 @@ -
Source:
-
- @@ -1786,11 +1701,6 @@ - -
Source:
-
@@ -1888,11 +1798,6 @@ - -
Source:
-
@@ -1990,11 +1895,6 @@ - -
Source:
-
@@ -2141,11 +2041,6 @@ - -
Source:
-
@@ -2296,11 +2191,6 @@ - -
Source:
-
@@ -2463,11 +2353,6 @@ - -
Source:
-
@@ -2573,11 +2458,6 @@ - -
Source:
-
@@ -2747,11 +2627,6 @@ - -
Source:
-
@@ -2925,11 +2800,6 @@ - -
Source:
-
@@ -3125,11 +2995,6 @@ - -
Source:
-
@@ -3280,11 +3145,6 @@ - -
Source:
-
@@ -3435,11 +3295,6 @@ - -
Source:
-
@@ -3602,11 +3457,6 @@ - -
Source:
-
@@ -3757,11 +3607,6 @@ - -
Source:
-
@@ -3912,11 +3757,6 @@ - -
Source:
-
@@ -4079,11 +3919,6 @@ - -
Source:
-
@@ -4185,11 +4020,6 @@ - -
Source:
-
@@ -4287,11 +4117,6 @@ - -
Source:
-
@@ -4389,11 +4214,6 @@ - -
Source:
-
@@ -4491,11 +4311,6 @@ - -
Source:
-
@@ -4642,11 +4457,6 @@ - -
Source:
-
@@ -4797,11 +4607,6 @@ - -
Source:
-
@@ -4967,11 +4772,6 @@ - -
Source:
-
@@ -5118,11 +4918,6 @@ - -
Source:
-
@@ -5285,11 +5080,6 @@ - -
Source:
-
@@ -5391,11 +5181,6 @@ - -
Source:
-
@@ -5504,11 +5289,6 @@ - -
Source:
-
@@ -5610,11 +5390,6 @@ - -
Source:
-
@@ -5712,11 +5487,6 @@ - -
Source:
-
@@ -5886,11 +5656,6 @@ - -
Source:
-
@@ -5992,11 +5757,6 @@ - -
Source:
-
@@ -6143,11 +5903,6 @@ - -
Source:
-
@@ -6321,11 +6076,6 @@ - -
Source:
-
@@ -6476,11 +6226,6 @@ - -
Source:
-
@@ -6631,11 +6376,6 @@ - -
Source:
-
@@ -6786,11 +6526,6 @@ - -
Source:
-
@@ -6895,11 +6630,6 @@ -
Source:
-
- @@ -6978,11 +6708,6 @@ - -
Source:
-
@@ -7084,11 +6809,6 @@ - -
Source:
-
@@ -7190,11 +6910,6 @@ - -
Source:
-
@@ -7257,7 +6972,7 @@
diff --git a/docs/frontend_api/FNoteComplement.html b/docs/frontend_api/FNoteComplement.html index 25eda287a..121ffd256 100644 --- a/docs/frontend_api/FNoteComplement.html +++ b/docs/frontend_api/FNoteComplement.html @@ -90,11 +90,6 @@ - -
Source:
-
@@ -190,11 +185,6 @@ - -
Source:
-
@@ -258,11 +248,6 @@ - -
Source:
-
@@ -330,11 +315,6 @@ - -
Source:
-
@@ -398,11 +378,6 @@ - -
Source:
-
@@ -466,11 +441,6 @@ - -
Source:
-
@@ -534,11 +504,6 @@ - -
Source:
-
@@ -602,11 +567,6 @@ - -
Source:
-
@@ -670,11 +630,6 @@ - -
Source:
-
@@ -738,11 +693,6 @@ - -
Source:
-
@@ -775,7 +725,7 @@
diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html index 6c41d1787..2e5667bca 100644 --- a/docs/frontend_api/FrontendScriptApi.html +++ b/docs/frontend_api/FrontendScriptApi.html @@ -78,11 +78,6 @@ - -
Source:
-
@@ -220,11 +215,6 @@ - -
Source:
-
@@ -326,11 +316,6 @@ - -
Source:
-
@@ -386,7 +371,7 @@ -CollapsibleWidget +RightPanelWidget @@ -423,7 +408,7 @@ - +
Deprecated:
  • use api.RightPanelWidget instead
@@ -433,10 +418,7 @@ -
Source:
-
+ @@ -538,11 +520,6 @@ - -
Source:
-
@@ -647,10 +624,106 @@ -
Source:
-
+ + + + + + +
+ + + + + + + + +

RightPanelWidget

+ + + + + + + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription
+ + +RightPanelWidget + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + @@ -755,11 +828,6 @@ -
Source:
-
- @@ -863,11 +931,6 @@ -
Source:
-
- @@ -972,11 +1035,6 @@ - -
Source:
-
@@ -1085,11 +1143,6 @@ - -
Source:
-
@@ -1195,11 +1248,6 @@ - -
Source:
-
@@ -1324,11 +1372,6 @@ - -
Source:
-
@@ -1479,11 +1522,6 @@ - -
Source:
-
@@ -1586,7 +1624,7 @@ -AddButtonToToolbarOptions +object @@ -1608,6 +1646,189 @@ +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
opts.id + + +string + + + + + + <optional>
+ + + +
id of the button, used to identify the old instances of this button to be replaced + ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only.
opts.title + + +string + + + + + + + +
opts.icon + + +string + + + + + + <optional>
+ + + +
name of the boxicon to be used (e.g. "time" for "bx-time" icon)
opts.action + + +function + + + + + + + + callback handling the click on the button
opts.shortcut + + +string + + + + + + <optional>
+ + + +
keyboard shortcut for the button, e.g. "alt+t"
+ + + +
@@ -1638,11 +1859,6 @@ -
Source:
-
- @@ -1774,11 +1990,6 @@ - -
Source:
-
@@ -1914,11 +2125,6 @@ -
Source:
-
- @@ -2121,11 +2327,6 @@ - -
Source:
-
@@ -2485,11 +2686,6 @@ - -
Source:
-
@@ -2618,11 +2814,6 @@ - -
Source:
-
@@ -2728,11 +2919,6 @@ - -
Source:
-
@@ -2834,11 +3020,6 @@ - -
Source:
-
@@ -2940,11 +3121,6 @@ - -
Source:
-
@@ -3050,11 +3226,6 @@ - -
Source:
-
@@ -3161,11 +3332,6 @@ implementation of actual widget type. - -
Source:
-
@@ -3266,11 +3432,6 @@ implementation of actual widget type. -
Source:
-
- @@ -3374,11 +3535,6 @@ implementation of actual widget type. -
Source:
-
- @@ -3542,11 +3698,6 @@ implementation of actual widget type. -
Source:
-
- @@ -3678,11 +3829,6 @@ implementation of actual widget type. - -
Source:
-
@@ -3836,11 +3982,6 @@ implementation of actual widget type. -
Source:
-
- @@ -3990,11 +4131,6 @@ implementation of actual widget type. - -
Source:
-
@@ -4097,11 +4233,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4252,11 +4383,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4408,11 +4534,6 @@ if some action needs to happen on only one specific instance. - -
Source:
-
@@ -4609,11 +4730,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -4715,11 +4831,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -4870,11 +4981,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5025,11 +5131,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5175,11 +5276,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5335,11 +5431,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5513,11 +5604,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5664,11 +5750,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -5773,11 +5854,6 @@ otherwise (by e.g. createNoteLink()) -
Source:
-
- @@ -5928,11 +6004,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -6084,11 +6155,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -6221,11 +6287,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -6375,11 +6436,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -6462,11 +6518,6 @@ otherwise (by e.g. createNoteLink()) -
Source:
-
- @@ -6598,11 +6649,6 @@ otherwise (by e.g. createNoteLink()) - -
Source:
-
@@ -6759,11 +6805,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -6868,11 +6909,6 @@ Internally this serializes the anonymous function into string and sends it to ba -
Source:
-
- @@ -7005,11 +7041,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7161,11 +7192,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7316,11 +7342,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7467,11 +7488,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7604,11 +7620,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7741,11 +7752,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -7901,11 +7907,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -8061,11 +8062,6 @@ Internally this serializes the anonymous function into string and sends it to ba - -
Source:
-
@@ -8153,11 +8149,6 @@ Typical use case is when new note has been created, we should wait until it is s - -
Source:
-
@@ -8202,7 +8193,7 @@ Typical use case is when new note has been created, we should wait until it is s
diff --git a/docs/frontend_api/entities_fattribute.js.html b/docs/frontend_api/entities_fattribute.js.html deleted file mode 100644 index 389c5e918..000000000 --- a/docs/frontend_api/entities_fattribute.js.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - JSDoc: Source: entities/fattribute.js - - - - - - - - - - -
- -

Source: entities/fattribute.js

- - - - - - -
-
-
import promotedAttributeDefinitionParser from '../services/promoted_attribute_definition_parser.js';
-
-/**
- * Attribute is an abstract concept which has two real uses - label (key - value pair)
- * and relation (representing named relationship between source and target note)
- */
-class FAttribute {
-    constructor(froca, row) {
-        this.froca = froca;
-
-        this.update(row);
-    }
-
-    update(row) {
-        /** @type {string} */
-        this.attributeId = row.attributeId;
-        /** @type {string} */
-        this.noteId = row.noteId;
-        /** @type {string} */
-        this.type = row.type;
-        /** @type {string} */
-        this.name = row.name;
-        /** @type {string} */
-        this.value = row.value;
-        /** @type {int} */
-        this.position = row.position;
-        /** @type {boolean} */
-        this.isInheritable = !!row.isInheritable;
-    }
-
-    /** @returns {FNote} */
-    getNote() {
-        return this.froca.notes[this.noteId];
-    }
-
-    /** @returns {Promise<FNote>} */
-    async getTargetNote() {
-        const targetNoteId = this.targetNoteId;
-
-        return await this.froca.getNote(targetNoteId, true);
-    }
-
-    get targetNoteId() { // alias
-        if (this.type !== 'relation') {
-            throw new Error(`FAttribute ${this.attributeId} is not a relation`);
-        }
-
-        return this.value;
-    }
-
-    get isAutoLink() {
-        return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name);
-    }
-
-    get toString() {
-        return `FAttribute(attributeId=${this.attributeId}, type=${this.type}, name=${this.name}, value=${this.value})`;
-    }
-
-    isDefinition() {
-        return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
-    }
-
-    getDefinition() {
-        return promotedAttributeDefinitionParser.parse(this.value);
-    }
-
-    isDefinitionFor(attr) {
-        return this.type === 'label' && this.name === `${attr.type}:${attr.name}`;
-    }
-
-    get dto() {
-        const dto = Object.assign({}, this);
-        delete dto.froca;
-
-        return dto;
-    }
-}
-
-export default FAttribute;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/entities_fbranch.js.html b/docs/frontend_api/entities_fbranch.js.html deleted file mode 100644 index 01423c8c5..000000000 --- a/docs/frontend_api/entities_fbranch.js.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - JSDoc: Source: entities/fbranch.js - - - - - - - - - - -
- -

Source: entities/fbranch.js

- - - - - - -
-
-
/**
- * Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
- * parents.
- */
-class FBranch {
-    constructor(froca, row) {
-        this.froca = froca;
-
-        this.update(row);
-    }
-
-    update(row) {
-        /**
-         * primary key
-         * @type {string}
-         */
-        this.branchId = row.branchId;
-        /** @type {string} */
-        this.noteId = row.noteId;
-        /** @type {string} */
-        this.parentNoteId = row.parentNoteId;
-        /** @type {int} */
-        this.notePosition = row.notePosition;
-        /** @type {string} */
-        this.prefix = row.prefix;
-        /** @type {boolean} */
-        this.isExpanded = !!row.isExpanded;
-        /** @type {boolean} */
-        this.fromSearchNote = !!row.fromSearchNote;
-    }
-
-    /** @returns {FNote} */
-    async getNote() {
-        return this.froca.getNote(this.noteId);
-    }
-
-    /** @returns {FNote} */
-    getNoteFromCache() {
-        return this.froca.getNoteFromCache(this.noteId);
-    }
-
-    /** @returns {FNote} */
-    async getParentNote() {
-        return this.froca.getNote(this.parentNoteId);
-    }
-
-    /** @returns {boolean} true if it's top level, meaning its parent is root note */
-    isTopLevel() {
-        return this.parentNoteId === 'root';
-    }
-
-    get toString() {
-        return `FBranch(branchId=${this.branchId})`;
-    }
-
-    get pojo() {
-        const pojo = {...this};
-        delete pojo.froca;
-        return pojo;
-    }
-}
-
-export default FBranch;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/entities_fnote.js.html b/docs/frontend_api/entities_fnote.js.html deleted file mode 100644 index a5cfbd7fe..000000000 --- a/docs/frontend_api/entities_fnote.js.html +++ /dev/null @@ -1,906 +0,0 @@ - - - - - JSDoc: Source: entities/fnote.js - - - - - - - - - - -
- -

Source: entities/fnote.js

- - - - - - -
-
-
import server from '../services/server.js';
-import noteAttributeCache from "../services/note_attribute_cache.js";
-import ws from "../services/ws.js";
-import options from "../services/options.js";
-import froca from "../services/froca.js";
-import protectedSessionHolder from "../services/protected_session_holder.js";
-import cssClassManager from "../services/css_class_manager.js";
-
-const LABEL = 'label';
-const RELATION = 'relation';
-
-const NOTE_TYPE_ICONS = {
-    "file": "bx bx-file",
-    "image": "bx bx-image",
-    "code": "bx bx-code",
-    "render": "bx bx-extension",
-    "search": "bx bx-file-find",
-    "relationMap": "bx bx-map-alt",
-    "book": "bx bx-book",
-    "noteMap": "bx bx-map-alt",
-    "mermaid": "bx bx-selection",
-    "canvas": "bx bx-pen",
-    "webView": "bx bx-globe-alt",
-    "launcher": "bx bx-link",
-    "doc": "bx bxs-file-doc",
-    "contentWidget": "bx bxs-widget"
-};
-
-class FNote {
-    /**
-     * @param {Froca} froca
-     * @param {Object.<string, Object>} row
-     */
-    constructor(froca, row) {
-        this.froca = froca;
-
-        /** @type {string[]} */
-        this.attributes = [];
-
-        /** @type {string[]} */
-        this.targetRelations = [];
-
-        /** @type {string[]} */
-        this.parents = [];
-        /** @type {string[]} */
-        this.children = [];
-
-        /** @type {Object.<string, string>} */
-        this.parentToBranch = {};
-
-        /** @type {Object.<string, string>} */
-        this.childToBranch = {};
-
-        this.update(row);
-    }
-
-    update(row) {
-        /** @type {string} */
-        this.noteId = row.noteId;
-        /** @type {string} */
-        this.title = row.title;
-        /** @type {boolean} */
-        this.isProtected = !!row.isProtected;
-        /**
-         * one of 'text', 'code', 'file' or 'render'
-         * @type {string}
-         */
-        this.type = row.type;
-        /**
-         * content-type, e.g. "application/json"
-         * @type {string}
-         */
-        this.mime = row.mime;
-    }
-
-    addParent(parentNoteId, branchId) {
-        if (parentNoteId === 'none') {
-            return;
-        }
-
-        if (!this.parents.includes(parentNoteId)) {
-            this.parents.push(parentNoteId);
-        }
-
-        this.parentToBranch[parentNoteId] = branchId;
-    }
-
-    addChild(childNoteId, branchId, sort = true) {
-        if (!(childNoteId in this.childToBranch)) {
-            this.children.push(childNoteId);
-        }
-
-        this.childToBranch[childNoteId] = branchId;
-
-        if (sort) {
-            this.sortChildren();
-        }
-    }
-
-    sortChildren() {
-        const branchIdPos = {};
-
-        for (const branchId of Object.values(this.childToBranch)) {
-            branchIdPos[branchId] = this.froca.getBranch(branchId).notePosition;
-        }
-
-        this.children.sort((a, b) => branchIdPos[this.childToBranch[a]] < branchIdPos[this.childToBranch[b]] ? -1 : 1);
-    }
-
-    /** @returns {boolean} */
-    isJson() {
-        return this.mime === "application/json";
-    }
-
-    async getContent() {
-        // we're not caching content since these objects are in froca and as such pretty long lived
-        const note = await server.get(`notes/${this.noteId}`);
-
-        return note.content;
-    }
-
-    async getJsonContent() {
-        const content = await this.getContent();
-
-        try {
-            return JSON.parse(content);
-        }
-        catch (e) {
-            console.log(`Cannot parse content of note '${this.noteId}': `, e.message);
-
-            return null;
-        }
-    }
-
-    /**
-     * @returns {string[]}
-     */
-    getParentBranchIds() {
-        return Object.values(this.parentToBranch);
-    }
-
-    /**
-     * @returns {string[]}
-     * @deprecated use getParentBranchIds() instead
-     */
-    getBranchIds() {
-        return this.getParentBranchIds();
-    }
-
-    /**
-     * @returns {FBranch[]}
-     */
-    getParentBranches() {
-        const branchIds = Object.values(this.parentToBranch);
-
-        return this.froca.getBranches(branchIds);
-    }
-
-    /**
-     * @returns {FBranch[]}
-     * @deprecated use getParentBranches() instead
-     */
-    getBranches() {
-        return this.getParentBranches();
-    }
-
-    /** @returns {boolean} */
-    hasChildren() {
-        return this.children.length > 0;
-    }
-
-    /** @returns {FBranch[]} */
-    getChildBranches() {
-        // don't use Object.values() to guarantee order
-        const branchIds = this.children.map(childNoteId => this.childToBranch[childNoteId]);
-
-        return this.froca.getBranches(branchIds);
-    }
-
-    /** @returns {string[]} */
-    getParentNoteIds() {
-        return this.parents;
-    }
-
-    /** @returns {FNote[]} */
-    getParentNotes() {
-        return this.froca.getNotesFromCache(this.parents);
-    }
-
-    // will sort the parents so that non-search & non-archived are first and archived at the end
-    // this is done so that non-search & non-archived paths are always explored as first when looking for note path
-    resortParents() {
-        this.parents.sort((aNoteId, bNoteId) => {
-            const aBranchId = this.parentToBranch[aNoteId];
-
-            if (aBranchId && aBranchId.startsWith('virt-')) {
-                return 1;
-            }
-
-            const aNote = this.froca.getNoteFromCache([aNoteId]);
-
-            if (aNote.hasLabel('archived')) {
-                return 1;
-            }
-
-            return -1;
-        });
-    }
-
-    /** @returns {string[]} */
-    getChildNoteIds() {
-        return this.children;
-    }
-
-    /** @returns {Promise<FNote[]>} */
-    async getChildNotes() {
-        return await this.froca.getNotes(this.children);
-    }
-
-    /**
-     * @param {string} [type] - (optional) attribute type to filter
-     * @param {string} [name] - (optional) attribute name to filter
-     * @returns {FAttribute[]} all note's attributes, including inherited ones
-     */
-    getOwnedAttributes(type, name) {
-        const attrs = this.attributes
-            .map(attributeId => this.froca.attributes[attributeId])
-            .filter(Boolean); // filter out nulls;
-
-        return this.__filterAttrs(attrs, type, name);
-    }
-
-    /**
-     * @param {string} [type] - (optional) attribute type to filter
-     * @param {string} [name] - (optional) attribute name to filter
-     * @returns {FAttribute[]} all note's attributes, including inherited ones
-     */
-    getAttributes(type, name) {
-        return this.__filterAttrs(this.__getCachedAttributes([]), type, name);
-    }
-
-    __getCachedAttributes(path) {
-        // notes/clones cannot form tree cycles, it is possible to create attribute inheritance cycle via templates
-        // when template instance is a parent of template itself
-        if (path.includes(this.noteId)) {
-            return [];
-        }
-
-        if (!(this.noteId in noteAttributeCache.attributes)) {
-            const newPath = [...path, this.noteId];
-            const attrArrs = [ this.getOwnedAttributes() ];
-
-            if (this.noteId !== 'root') {
-                for (const parentNote of this.getParentNotes()) {
-                    // these virtual parent-child relationships are also loaded into froca
-                    if (parentNote.type !== 'search') {
-                        attrArrs.push(parentNote.__getInheritableAttributes(newPath));
-                    }
-                }
-            }
-
-            for (const templateAttr of attrArrs.flat().filter(attr => attr.type === 'relation' && attr.name === 'template')) {
-                const templateNote = this.froca.notes[templateAttr.value];
-
-                if (templateNote && templateNote.noteId !== this.noteId) {
-                    attrArrs.push(
-                        templateNote.__getCachedAttributes(newPath)
-                            // template attr is used as a marker for templates, but it's not meant to be inherited
-                            .filter(attr => !(attr.type === 'label' && (attr.name === 'template' || attr.name === 'workspacetemplate')))
-                    );
-                }
-            }
-
-            noteAttributeCache.attributes[this.noteId] = [];
-            const addedAttributeIds = new Set();
-
-            for (const attr of attrArrs.flat()) {
-                if (!addedAttributeIds.has(attr.attributeId)) {
-                    addedAttributeIds.add(attr.attributeId);
-
-                    noteAttributeCache.attributes[this.noteId].push(attr);
-                }
-            }
-        }
-
-        return noteAttributeCache.attributes[this.noteId];
-    }
-
-    isRoot() {
-        return this.noteId === 'root';
-    }
-
-    getAllNotePaths(encounteredNoteIds = null) {
-        if (this.noteId === 'root') {
-            return [['root']];
-        }
-
-        if (!encounteredNoteIds) {
-            encounteredNoteIds = new Set();
-        }
-
-        encounteredNoteIds.add(this.noteId);
-
-        const parentNotes = this.getParentNotes();
-        let paths;
-
-        if (parentNotes.length === 1) { // optimization for the most common case
-            if (encounteredNoteIds.has(parentNotes[0].noteId)) {
-                return [];
-            }
-            else {
-                paths = parentNotes[0].getAllNotePaths(encounteredNoteIds);
-            }
-        }
-        else {
-            paths = [];
-
-            for (const parentNote of parentNotes) {
-                if (encounteredNoteIds.has(parentNote.noteId)) {
-                    continue;
-                }
-
-                const newSet = new Set(encounteredNoteIds);
-
-                paths.push(...parentNote.getAllNotePaths(newSet));
-            }
-        }
-
-        for (const path of paths) {
-            path.push(this.noteId);
-        }
-
-        return paths;
-    }
-
-    getSortedNotePaths(hoistedNotePath = 'root') {
-        const notePaths = this.getAllNotePaths().map(path => ({
-            notePath: path,
-            isInHoistedSubTree: path.includes(hoistedNotePath),
-            isArchived: path.find(noteId => froca.notes[noteId].hasLabel('archived')),
-            isSearch: path.find(noteId => froca.notes[noteId].type === 'search'),
-            isHidden: path.includes('_hidden')
-        }));
-
-        notePaths.sort((a, b) => {
-            if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
-                return a.isInHoistedSubTree ? -1 : 1;
-            } else if (a.isSearch !== b.isSearch) {
-                return a.isSearch ? 1 : -1;
-            } else if (a.isArchived !== b.isArchived) {
-                return a.isArchived ? 1 : -1;
-            } else if (a.isHidden !== b.isHidden) {
-                return a.isHidden ? 1 : -1;
-            } else {
-                return a.notePath.length - b.notePath.length;
-            }
-        });
-
-        return notePaths;
-    }
-
-    __filterAttrs(attributes, type, name) {
-        this.__validateTypeName(type, name);
-
-        if (!type && !name) {
-            return attributes;
-        } else if (type && name) {
-            return attributes.filter(attr => attr.type === type && attr.name === name);
-        } else if (type) {
-            return attributes.filter(attr => attr.type === type);
-        } else if (name) {
-            return attributes.filter(attr => attr.name === name);
-        }
-    }
-
-    __getInheritableAttributes(path) {
-        const attrs = this.__getCachedAttributes(path);
-
-        return attrs.filter(attr => attr.isInheritable);
-    }
-
-    __validateTypeName(type, name) {
-        if (type && type !== 'label' && type !== 'relation') {
-            throw new Error(`Unrecognized attribute type '${type}'. Only 'label' and 'relation' are possible values.`);
-        }
-
-        if (name) {
-            const firstLetter = name.charAt(0);
-            if (firstLetter === '#' || firstLetter === '~') {
-                throw new Error(`Detect '#' or '~' in the attribute's name. In the API, attribute names should be set without these characters.`);
-            }
-        }
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {FAttribute[]} all note's labels (attributes with type label), including inherited ones
-     */
-    getOwnedLabels(name) {
-        return this.getOwnedAttributes(LABEL, name);
-    }
-
-    /**
-     * @param {string} [name] - label name to filter
-     * @returns {FAttribute[]} all note's labels (attributes with type label), including inherited ones
-     */
-    getLabels(name) {
-        return this.getAttributes(LABEL, name);
-    }
-
-    getIcon() {
-        const iconClassLabels = this.getLabels('iconClass');
-        const workspaceIconClass = this.getWorkspaceIconClass();
-
-        if (iconClassLabels.length > 0) {
-            return iconClassLabels[0].value;
-        }
-        else if (workspaceIconClass) {
-            return workspaceIconClass;
-        }
-        else if (this.noteId === 'root') {
-            return "bx bx-chevrons-right";
-        }
-        if (this.noteId === '_share') {
-            return "bx bx-share-alt";
-        }
-        else if (this.type === 'text') {
-            if (this.isFolder()) {
-                return "bx bx-folder";
-            }
-            else {
-                return "bx bx-note";
-            }
-        }
-        else if (this.type === 'code' && this.mime.startsWith('text/x-sql')) {
-            return "bx bx-data";
-        }
-        else {
-            return NOTE_TYPE_ICONS[this.type];
-        }
-    }
-
-    getColorClass() {
-        const color = this.getLabelValue("color");
-        return cssClassManager.createClassForColor(color);
-    }
-
-    isFolder() {
-        return this.type === 'search'
-            || this.getFilteredChildBranches().length > 0;
-    }
-
-    getFilteredChildBranches() {
-        let childBranches = this.getChildBranches();
-
-        if (!childBranches) {
-            ws.logError(`No children for ${parentNote}. This shouldn't happen.`);
-            return;
-        }
-
-        if (options.is("hideIncludedImages_main")) {
-            const imageLinks = this.getRelations('imageLink');
-
-            // image is already visible in the parent note so no need to display it separately in the book
-            childBranches = childBranches.filter(branch => !imageLinks.find(rel => rel.value === branch.noteId));
-        }
-
-        // we're not checking hideArchivedNotes since that would mean we need to lazy load the child notes
-        // which would seriously slow down everything.
-        // we check this flag only once user chooses to expand the parent. This has the negative consequence that
-        // note may appear as folder but not contain any children when all of them are archived
-
-        return childBranches;
-    }
-
-    /**
-     * @param {string} [name] - relation name to filter
-     * @returns {FAttribute[]} all note's relations (attributes with type relation), including inherited ones
-     */
-    getOwnedRelations(name) {
-        return this.getOwnedAttributes(RELATION, name);
-    }
-
-    /**
-     * @param {string} [name] - relation name to filter
-     * @returns {FAttribute[]} all note's relations (attributes with type relation), including inherited ones
-     */
-    getRelations(name) {
-        return this.getAttributes(RELATION, name);
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {boolean} true if note has an attribute with given type and name (including inherited)
-     */
-    hasAttribute(type, name) {
-        return !!this.getAttribute(type, name);
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {boolean} true if note has an attribute with given type and name (including inherited)
-     */
-    hasOwnedAttribute(type, name) {
-        return !!this.getOwnedAttribute(type, name);
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {FAttribute} attribute of given type and name. If there's more such attributes, first is  returned. Returns null if there's no such attribute belonging to this note.
-     */
-    getOwnedAttribute(type, name) {
-        const attributes = this.getOwnedAttributes(type, name);
-
-        return attributes.length > 0 ? attributes[0] : 0;
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {FAttribute} attribute of given type and name. If there's more such attributes, first is  returned. Returns null if there's no such attribute belonging to this note.
-     */
-    getAttribute(type, name) {
-        const attributes = this.getAttributes(type, name);
-
-        return attributes.length > 0 ? attributes[0] : null;
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {string} attribute value of given type and name or null if no such attribute exists.
-     */
-    getOwnedAttributeValue(type, name) {
-        const attr = this.getOwnedAttribute(type, name);
-
-        return attr ? attr.value : null;
-    }
-
-    /**
-     * @param {string} type - attribute type (label, relation, etc.)
-     * @param {string} name - attribute name
-     * @returns {string} attribute value of given type and name or null if no such attribute exists.
-     */
-    getAttributeValue(type, name) {
-        const attr = this.getAttribute(type, name);
-
-        return attr ? attr.value : null;
-    }
-
-    /**
-     * @param {string} name - label name
-     * @returns {boolean} true if label exists (excluding inherited)
-     */
-    hasOwnedLabel(name) { return this.hasOwnedAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {boolean} true if label exists (including inherited)
-     */
-    hasLabel(name) { return this.hasAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {boolean} true if relation exists (excluding inherited)
-     */
-    hasOwnedRelation(name) { return this.hasOwnedAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {boolean} true if relation exists (including inherited)
-     */
-    hasRelation(name) { return this.hasAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {FAttribute} label if it exists, null otherwise
-     */
-    getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {FAttribute} label if it exists, null otherwise
-     */
-    getLabel(name) { return this.getAttribute(LABEL, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {FAttribute} relation if it exists, null otherwise
-     */
-    getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {FAttribute} relation if it exists, null otherwise
-     */
-    getRelation(name) { return this.getAttribute(RELATION, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {string} label value if label exists, null otherwise
-     */
-    getOwnedLabelValue(name) { return this.getOwnedAttributeValue(LABEL, name); }
-
-    /**
-     * @param {string} name - label name
-     * @returns {string} label value if label exists, null otherwise
-     */
-    getLabelValue(name) { return this.getAttributeValue(LABEL, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {string} relation value if relation exists, null otherwise
-     */
-    getOwnedRelationValue(name) { return this.getOwnedAttributeValue(RELATION, name); }
-
-    /**
-     * @param {string} name - relation name
-     * @returns {string} relation value if relation exists, null otherwise
-     */
-    getRelationValue(name) { return this.getAttributeValue(RELATION, name); }
-
-    /**
-     * @param {string} name
-     * @returns {Promise<FNote>|null} target note of the relation or null (if target is empty or note was not found)
-     */
-    async getRelationTarget(name) {
-        const targets = await this.getRelationTargets(name);
-
-        return targets.length > 0 ? targets[0] : null;
-    }
-
-    /**
-     * @param {string} [name] - relation name to filter
-     * @returns {Promise<FNote[]>}
-     */
-    async getRelationTargets(name) {
-        const relations = this.getRelations(name);
-        const targets = [];
-
-        for (const relation of relations) {
-            targets.push(await this.froca.getNote(relation.value));
-        }
-
-        return targets;
-    }
-
-    /**
-     * @returns {FNote[]}
-     */
-    getTemplateNotes() {
-        const relations = this.getRelations('template');
-
-        return relations.map(rel => this.froca.notes[rel.value]);
-    }
-
-    getPromotedDefinitionAttributes() {
-        if (this.hasLabel('hidePromotedAttributes')) {
-            return [];
-        }
-
-        const promotedAttrs = this.getAttributes()
-            .filter(attr => attr.isDefinition())
-            .filter(attr => {
-                const def = attr.getDefinition();
-
-                return def && def.isPromoted;
-            });
-
-        // attrs are not resorted if position changes after initial load
-        promotedAttrs.sort((a, b) => a.position < b.position ? -1 : 1);
-
-        return promotedAttrs;
-    }
-
-    hasAncestor(ancestorNoteId, visitedNoteIds = null) {
-        if (this.noteId === ancestorNoteId) {
-            return true;
-        }
-
-        if (!visitedNoteIds) {
-            visitedNoteIds = new Set();
-        } else if (visitedNoteIds.has(this.noteId)) {
-            // to avoid infinite cycle when template is descendent of the instance
-            return false;
-        }
-
-        visitedNoteIds.add(this.noteId);
-
-        for (const templateNote of this.getTemplateNotes()) {
-            if (templateNote.hasAncestor(ancestorNoteId, visitedNoteIds)) {
-                return true;
-            }
-        }
-
-        for (const parentNote of this.getParentNotes()) {
-            if (parentNote.hasAncestor(ancestorNoteId, visitedNoteIds)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    isInHiddenSubtree() {
-        return this.noteId === '_hidden' || this.hasAncestor('_hidden');
-    }
-
-    /**
-     * @deprecated NOOP
-     */
-    invalidateAttributeCache() {}
-
-    /**
-     * Get relations which target this note
-     *
-     * @returns {FAttribute[]}
-     */
-    getTargetRelations() {
-        return this.targetRelations
-            .map(attributeId => this.froca.attributes[attributeId]);
-    }
-
-    /**
-     * Get relations which target this note
-     *
-     * @returns {FNote[]}
-     */
-    async getTargetRelationSourceNotes() {
-        const targetRelations = this.getTargetRelations();
-
-        return await this.froca.getNotes(targetRelations.map(tr => tr.noteId));
-    }
-
-    /**
-     * Return note complement which is most importantly note's content
-     *
-     * @return {Promise<FNoteComplement>}
-     */
-    async getNoteComplement() {
-        return await this.froca.getNoteComplement(this.noteId);
-    }
-
-    toString() {
-        return `Note(noteId=${this.noteId}, title=${this.title})`;
-    }
-
-    get dto() {
-        const dto = Object.assign({}, this);
-        delete dto.froca;
-
-        return dto;
-    }
-
-    getCssClass() {
-        const labels = this.getLabels('cssClass');
-        return labels.map(l => l.value).join(' ');
-    }
-
-    getWorkspaceIconClass() {
-        const labels = this.getLabels('workspaceIconClass');
-        return labels.length > 0 ? labels[0].value : "";
-    }
-
-    getWorkspaceTabBackgroundColor() {
-        const labels = this.getLabels('workspaceTabBackgroundColor');
-        return labels.length > 0 ? labels[0].value : "";
-    }
-
-    /** @returns {boolean} true if this note is JavaScript (code or attachment) */
-    isJavaScript() {
-        return (this.type === "code" || this.type === "file" || this.type === 'launcher')
-            && (this.mime.startsWith("application/javascript")
-                || this.mime === "application/x-javascript"
-                || this.mime === "text/javascript");
-    }
-
-    /** @returns {boolean} true if this note is HTML */
-    isHtml() {
-        return (this.type === "code" || this.type === "file" || this.type === "render") && this.mime === "text/html";
-    }
-
-    /** @returns {string|null} JS script environment - either "frontend" or "backend" */
-    getScriptEnv() {
-        if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith('env=frontend'))) {
-            return "frontend";
-        }
-
-        if (this.type === 'render') {
-            return "frontend";
-        }
-
-        if (this.isJavaScript() && this.mime.endsWith('env=backend')) {
-            return "backend";
-        }
-
-        return null;
-    }
-
-    async executeScript() {
-        if (!this.isJavaScript()) {
-            throw new Error(`Note ${this.noteId} is of type ${this.type} and mime ${this.mime} and thus cannot be executed`);
-        }
-
-        const env = this.getScriptEnv();
-
-        if (env === "frontend") {
-            const bundleService = (await import("../services/bundle.js")).default;
-            return await bundleService.getAndExecuteBundle(this.noteId);
-        }
-        else if (env === "backend") {
-            const resp = await server.post(`script/run/${this.noteId}`);
-        }
-        else {
-            throw new Error(`Unrecognized env type ${env} for note ${this.noteId}`);
-        }
-    }
-
-    isShared() {
-        for (const parentNoteId of this.parents) {
-            if (parentNoteId === 'root' || parentNoteId === 'none') {
-                continue;
-            }
-
-            const parentNote = froca.notes[parentNoteId];
-
-            if (!parentNote || parentNote.type === 'search') {
-                continue;
-            }
-
-            if (parentNote.noteId === '_share' || parentNote.isShared()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    isContentAvailable() {
-        return !this.isProtected || protectedSessionHolder.isProtectedSessionAvailable()
-    }
-
-    isLaunchBarConfig() {
-        return this.type === 'launcher' || ['_lbRoot', '_lbAvailableLaunchers', '_lbVisibleLaunchers'].includes(this.noteId);
-    }
-
-    isOptions() {
-        return this.noteId.startsWith("options");
-    }
-}
-
-export default FNote;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/entities_fnote_complement.js.html b/docs/frontend_api/entities_fnote_complement.js.html deleted file mode 100644 index 6ed38dc95..000000000 --- a/docs/frontend_api/entities_fnote_complement.js.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - JSDoc: Source: entities/fnote_complement.js - - - - - - - - - - -
- -

Source: entities/fnote_complement.js

- - - - - - -
-
-
/**
- * Complements the FNote with the main note content and other extra attributes
- */
-class FNoteComplement {
-    constructor(row) {
-        /** @type {string} */
-        this.noteId = row.noteId;
-
-        /**
-         * can either contain the whole content (in e.g. string notes), only part (large text notes) or nothing at all (binary notes, images)
-         * @type {string}
-         */
-        this.content = row.content;
-
-        /** @type {int} */
-        this.contentLength = row.contentLength;
-
-        /** @type {string} */
-        this.dateCreated = row.dateCreated;
-
-        /** @type {string} */
-        this.dateModified = row.dateModified;
-
-        /** @type {string} */
-        this.utcDateCreated = row.utcDateCreated;
-
-        /** @type {string} */
-        this.utcDateModified = row.utcDateModified;
-
-        // "combined" date modified give larger out of note's and note_content's dateModified
-
-        /** @type {string} */
-        this.combinedDateModified = row.combinedDateModified;
-
-        /** @type {string} */
-        this.combinedUtcDateModified = row.combinedUtcDateModified;
-    }
-}
-
-export default FNoteComplement;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html deleted file mode 100644 index d7ba46285..000000000 --- a/docs/frontend_api/global.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
- -

Global

- - - - - - -
- -
- -

- - -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - - - -

Methods

- - - - - - - -

(async) doRenderBody()

- - - - - - -
- for overriding -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -

Type Definitions

- - - -

AddButtonToToolbarOptions

- - - - - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
id - - -string - - - - - - <optional>
- - - -
id of the button, used to identify the old instances of this button to be replaced - ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only.
title - - -string - - - - - - - -
icon - - -string - - - - - - <optional>
- - - -
name of the boxicon to be used (e.g. "time" for "bx-time" icon)
action - - -function - - - - - - - - callback handling the click on the button
shortcut - - -string - - - - - - <optional>
- - - -
keyboard shortcut for the button, e.g. "alt+t"
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/docs/frontend_api/index.html b/docs/frontend_api/index.html index 85abe287b..e6417de05 100644 --- a/docs/frontend_api/index.html +++ b/docs/frontend_api/index.html @@ -50,7 +50,7 @@
diff --git a/docs/frontend_api/module.exports.html b/docs/frontend_api/module.exports.html deleted file mode 100644 index 67fb32df4..000000000 --- a/docs/frontend_api/module.exports.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - JSDoc: Class: exports - - - - - - - - - - -
- -

Class: exports

- - - - - - -
- -
- -

exports()

- -
TODO: rename, it's not collapsible anymore
- - -
- -
-
- - - - -

Constructor

- - - -

new exports()

- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html deleted file mode 100644 index d2c928a8d..000000000 --- a/docs/frontend_api/services_frontend_script_api.js.html +++ /dev/null @@ -1,654 +0,0 @@ - - - - - JSDoc: Source: services/frontend_script_api.js - - - - - - - - - - -
- -

Source: services/frontend_script_api.js

- - - - - - -
-
-
import server from './server.js';
-import utils from './utils.js';
-import toastService from './toast.js';
-import linkService from './link.js';
-import froca from './froca.js';
-import noteTooltipService from './note_tooltip.js';
-import protectedSessionService from './protected_session.js';
-import dateNotesService from './date_notes.js';
-import searchService from './search.js';
-import CollapsibleWidget from '../widgets/collapsible_widget.js';
-import ws from "./ws.js";
-import appContext from "../components/app_context.js";
-import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js";
-import BasicWidget from "../widgets/basic_widget.js";
-import SpacedUpdate from "./spaced_update.js";
-import shortcutService from "./shortcuts.js";
-
-/**
- * This is the main frontend API interface for scripts. It's published in the local "api" object.
- *
- * @constructor
- * @hideconstructor
- */
-function FrontendScriptApi(startNote, currentNote, originEntity = null, $container = null) {
-    /** @property {jQuery} container of all the rendered script content */
-    this.$container = $container;
-
-    /** @property {object} note where script started executing */
-    this.startNote = startNote;
-    /** @property {object} note where script is currently executing */
-    this.currentNote = currentNote;
-    /** @property {object|null} entity whose event triggered this execution */
-    this.originEntity = originEntity;
-
-    // to keep consistency with backend API
-    this.dayjs = dayjs;
-
-    /** @property {CollapsibleWidget} */
-    this.CollapsibleWidget = CollapsibleWidget;
-
-    /** @property {NoteContextAwareWidget} */
-    this.NoteContextAwareWidget = NoteContextAwareWidget;
-
-    /**
-     * @property {NoteContextAwareWidget}
-     * @deprecated use NoteContextAwareWidget instead
-     */
-    this.TabAwareWidget = NoteContextAwareWidget;
-
-    /**
-     * @property {NoteContextAwareWidget}
-     * @deprecated use NoteContextAwareWidget instead
-     */
-    this.TabCachingWidget = NoteContextAwareWidget;
-
-    /**
-     * @property {NoteContextAwareWidget}
-     * @deprecated use NoteContextAwareWidget instead
-     */
-    this.NoteContextCachingWidget = NoteContextAwareWidget;
-
-    /** @property {BasicWidget} */
-    this.BasicWidget = BasicWidget;
-
-    /**
-     * Activates note in the tree and in the note detail.
-     *
-     * @method
-     * @param {string} notePath (or noteId)
-     * @returns {Promise<void>}
-     */
-    this.activateNote = async notePath => {
-        await appContext.tabManager.getActiveContext().setNote(notePath);
-    };
-
-    /**
-     * Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced.
-     *
-     * @param {string} notePath (or noteId)
-     * @return {Promise<void>}
-     */
-    this.activateNewNote = async notePath => {
-        await ws.waitForMaxKnownEntityChangeId();
-
-        await appContext.tabManager.getActiveContext().setNote(notePath);
-        appContext.triggerEvent('focusAndSelectTitle');
-    };
-
-    /**
-     * Open a note in a new tab.
-     *
-     * @param {string} notePath (or noteId)
-     * @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab
-     * @return {Promise<void>}
-     */
-    this.openTabWithNote = async (notePath, activate) => {
-        await ws.waitForMaxKnownEntityChangeId();
-
-        await appContext.tabManager.openContextWithNote(notePath, activate);
-
-        if (activate) {
-            appContext.triggerEvent('focusAndSelectTitle');
-        }
-    };
-
-    /**
-     * Open a note in a new split.
-     *
-     * @param {string} notePath (or noteId)
-     * @param {boolean} activate - set to true to activate the new split, false to stay on the current split
-     * @return {Promise<void>}
-     */
-    this.openSplitWithNote = async (notePath, activate) => {
-        await ws.waitForMaxKnownEntityChangeId();
-
-        const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
-        const {ntxId} = subContexts[subContexts.length - 1];
-
-        appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
-
-        if (activate) {
-            appContext.triggerEvent('focusAndSelectTitle');
-        }
-    };
-
-    /**
-     * @typedef {Object} AddButtonToToolbarOptions
-     * @property {string} [id] - id of the button, used to identify the old instances of this button to be replaced
-     *                          ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only.
-     * @property {string} title
-     * @property {string} [icon] - name of the boxicon to be used (e.g. "time" for "bx-time" icon)
-     * @property {function} action - callback handling the click on the button
-     * @property {string} [shortcut] - keyboard shortcut for the button, e.g. "alt+t"
-     */
-
-    /**
-     * Adds a new launcher to the launchbar. If the launcher (id) already exists, it will be updated.
-     *
-     * @deprecated you can now create/modify launchers in the top-left Menu -> Configure Launchbar
-     *             for special needs there's also backend API's createOrUpdateLauncher()
-     * @param {AddButtonToToolbarOptions} opts
-     */
-    this.addButtonToToolbar = async opts => {
-        console.warn("api.addButtonToToolbar() has been deprecated since v0.58 and may be removed in the future. Use  Menu -> Configure Launchbar to create/update launchers instead.");
-
-        const {action, ...reqBody} = opts;
-        reqBody.action = action.toString();
-
-        await server.put('special-notes/api-script-launcher', reqBody);
-    };
-
-    function prepareParams(params) {
-        if (!params) {
-            return params;
-        }
-
-        return params.map(p => {
-            if (typeof p === "function") {
-                return `!@#Function: ${p.toString()}`;
-            }
-            else {
-                return p;
-            }
-        });
-    }
-
-    /**
-     * Executes given anonymous function on the backend.
-     * Internally this serializes the anonymous function into string and sends it to backend via AJAX.
-     *
-     * @param {string} script - script to be executed on the backend
-     * @param {Array.<?>} params - list of parameters to the anonymous function to be send to backend
-     * @return {Promise<*>} return value of the executed function on the backend
-     */
-    this.runOnBackend = async (script, params = []) => {
-        if (typeof script === "function") {
-            script = script.toString();
-        }
-
-        const ret = await server.post('script/exec', {
-            script: script,
-            params: prepareParams(params),
-            startNoteId: startNote.noteId,
-            currentNoteId: currentNote.noteId,
-            originEntityName: "notes", // currently there's no other entity on frontend which can trigger event
-            originEntityId: originEntity ? originEntity.noteId : null
-        }, "script");
-
-        if (ret.success) {
-            await ws.waitForMaxKnownEntityChangeId();
-
-            return ret.executionResult;
-        }
-        else {
-            throw new Error(`server error: ${ret.error}`);
-        }
-    };
-
-    /**
-     * @deprecated new name of this API call is runOnBackend so use that
-     * @method
-     */
-    this.runOnServer = this.runOnBackend;
-
-    /**
-     * This is a powerful search method - you can search by attributes and their values, e.g.:
-     * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
-     *
-     * @method
-     * @param {string} searchString
-     * @returns {Promise<FNote[]>}
-     */
-    this.searchForNotes = async searchString => {
-        return await searchService.searchForNotes(searchString);
-    };
-
-    /**
-     * This is a powerful search method - you can search by attributes and their values, e.g.:
-     * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
-     *
-     * @method
-     * @param {string} searchString
-     * @returns {Promise<FNote|null>}
-     */
-    this.searchForNote = async searchString => {
-        const notes = await this.searchForNotes(searchString);
-
-        return notes.length > 0 ? notes[0] : null;
-    };
-
-    /**
-     * Returns note by given noteId. If note is missing from cache, it's loaded.
-     **
-     * @param {string} noteId
-     * @return {Promise<FNote>}
-     */
-    this.getNote = async noteId => await froca.getNote(noteId);
-
-    /**
-     * Returns list of notes. If note is missing from cache, it's loaded.
-     *
-     * This is often used to bulk-fill the cache with notes which would have to be picked one by one
-     * otherwise (by e.g. createNoteLink())
-     *
-     * @param {string[]} noteIds
-     * @param {boolean} [silentNotFoundError] - don't report error if the note is not found
-     * @return {Promise<FNote[]>}
-     */
-    this.getNotes = async (noteIds, silentNotFoundError = false) => await froca.getNotes(noteIds, silentNotFoundError);
-
-    /**
-     * Update frontend tree (note) cache from the backend.
-     *
-     * @param {string[]} noteIds
-     * @method
-     */
-    this.reloadNotes = async noteIds => await froca.reloadNotes(noteIds);
-
-    /**
-     * Instance name identifies particular Trilium instance. It can be useful for scripts
-     * if some action needs to happen on only one specific instance.
-     *
-     * @return {string}
-     */
-    this.getInstanceName = () => window.glob.instanceName;
-
-    /**
-     * @method
-     * @param {Date} date
-     * @returns {string} date in YYYY-MM-DD format
-     */
-    this.formatDateISO = utils.formatDateISO;
-
-    /**
-     * @method
-     * @param {string} str
-     * @returns {Date} parsed object
-     */
-    this.parseDate = utils.parseDate;
-
-    /**
-     * Show info message to the user.
-     *
-     * @method
-     * @param {string} message
-     */
-    this.showMessage = toastService.showMessage;
-
-    /**
-     * Show error message to the user.
-     *
-     * @method
-     * @param {string} message
-     */
-    this.showError = toastService.showError;
-
-    /**
-     * Trigger command.
-     *
-     * @method
-     * @param {string} name
-     * @param {object} data
-     */
-    this.triggerCommand = (name, data) => appContext.triggerCommand(name, data);
-
-    /**
-     * Trigger event.
-     *
-     * @method
-     * @param {string} name
-     * @param {object} data
-     */
-    this.triggerEvent = (name, data) => appContext.triggerEvent(name, data);
-
-    /**
-     * @method
-     * @deprecated - this is now no-op since all the changes should be gracefully handled per widget
-     */
-    this.refreshTree = () => {};
-
-    /**
-     * Create note link (jQuery object) for given note.
-     *
-     * @method
-     * @param {string} notePath (or noteId)
-     * @param {object} [params]
-     * @param {boolean} [params.showTooltip=true] - enable/disable tooltip on the link
-     * @param {boolean} [params.showNotePath=false] - show also whole note's path as part of the link
-     * @param {boolean} [params.showNoteIcon=false] - show also note icon before the title
-     * @param {string} [params.title=] - custom link tile with note's title as default
-     */
-    this.createNoteLink = linkService.createNoteLink;
-
-    /**
-     * Adds given text to the editor cursor
-     *
-     * @deprecated use addTextToActiveContextEditor() instead
-     * @param {string} text - this must be clear text, HTML is not supported.
-     * @method
-     */
-    this.addTextToActiveTabEditor = text => {
-        console.warn("api.addTextToActiveTabEditor() is deprecated, use addTextToActiveContextEditor() instead.");
-
-        return appContext.triggerCommand('addTextToActiveEditor', {text});
-    };
-
-    /**
-     * Adds given text to the editor cursor
-     *
-     * @param {string} text - this must be clear text, HTML is not supported.
-     * @method
-     */
-    this.addTextToActiveContextEditor = text => appContext.triggerCommand('addTextToActiveEditor', {text});
-
-    /**
-     * @method
-     * @deprecated use getActiveContextNote() instead
-     * @returns {FNote} active note (loaded into right pane)
-     */
-    this.getActiveTabNote = () => {
-        console.warn("api.getActiveTabNote() is deprecated, use getActiveContextNote() instead.");
-
-        return appContext.tabManager.getActiveContextNote();
-    };
-
-    /**
-     * @method
-     * @returns {FNote} active note (loaded into right pane)
-     */
-    this.getActiveContextNote = () => appContext.tabManager.getActiveContextNote();
-
-    /**
-     * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance.
-     *
-     * @deprecated use getActiveContextTextEditor()
-     * @method
-     * @param [callback] - callback receiving "textEditor" instance
-     */
-    this.getActiveTabTextEditor = callback => {
-        console.warn("api.getActiveTabTextEditor() is deprecated, use getActiveContextTextEditor() instead.");
-
-        return appContext.tabManager.getActiveContext()?.getTextEditor(callback);
-    };
-
-    /**
-     * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance.
-     *
-     * @method
-     * @returns {Promise<CKEditor>} instance of CKEditor
-     */
-    this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContext()?.getTextEditor();
-
-    /**
-     * See https://codemirror.net/doc/manual.html#api
-     *
-     * @method
-     * @returns {Promise<CodeMirror>} instance of CodeMirror
-     */
-    this.getActiveContextCodeEditor = () => appContext.tabManager.getActiveContext()?.getCodeEditor();
-
-    /**
-     * Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the
-     * implementation of actual widget type.
-     *
-     * @method
-     * @returns {Promise<NoteDetailWidget>}
-     */
-    this.getActiveNoteDetailWidget = () => new Promise(resolve => appContext.triggerCommand('executeInActiveNoteDetailWidget', {callback: resolve}));
-
-    /**
-     * @method
-     * @deprecated use getActiveContextNotePath() instead
-     * @returns {Promise<string|null>} returns note path of active note or null if there isn't active note
-     */
-    this.getActiveTabNotePath = () => {
-        console.warn("api.getActiveTabNotePath() is deprecated, use getActiveContextNotePath() instead.");
-
-        return appContext.tabManager.getActiveContextNotePath();
-    };
-
-    /**
-     * @method
-     * @returns {Promise<string|null>} returns note path of active note or null if there isn't active note
-     */
-    this.getActiveContextNotePath = () => appContext.tabManager.getActiveContextNotePath();
-
-    /**
-     * Returns component which owns given DOM element (the nearest parent component in DOM tree)
-     *
-     * @method
-     * @param {Element} el - DOM element
-     * @returns {Component}
-     */
-    this.getComponentByEl = el => appContext.getComponentByEl(el);
-
-    /**
-     * @method
-     * @param {object} $el - jquery object on which to setup the tooltip
-     */
-    this.setupElementTooltip = noteTooltipService.setupElementTooltip;
-
-    /**
-     * @deprecated use protectNote and protectSubtree instead
-     * @method
-     */
-    this.protectActiveNote = async () => {
-        const activeNote = appContext.tabManager.getActiveContextNote();
-
-        await protectedSessionService.protectNote(activeNote.noteId, true, false);
-    };
-
-    /**
-     * @method
-     * @param {string} noteId
-     * @param {boolean} protect - true to protect note, false to unprotect
-     */
-    this.protectNote = async (noteId, protect) => {
-        await protectedSessionService.protectNote(noteId, protect, false);
-    };
-
-    /**
-     * @method
-     * @param {string} noteId
-     * @param {boolean} protect - true to protect subtree, false to unprotect
-     */
-    this.protectSubTree = async (noteId, protect) => {
-        await protectedSessionService.protectNote(noteId, protect, true);
-    };
-
-    /**
-     * Returns date-note for today. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @return {Promise<FNote>}
-     */
-    this.getTodayNote = dateNotesService.getTodayNote;
-
-    /**
-     * Returns day note for a given date. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @param {string} date - e.g. "2019-04-29"
-     * @return {Promise<FNote>}
-     * @deprecated use getDayNote instead
-     */
-    this.getDateNote = dateNotesService.getDayNote;
-
-    /**
-     * Returns day note for a given date. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @param {string} date - e.g. "2019-04-29"
-     * @return {Promise<FNote>}
-     */
-    this.getDayNote = dateNotesService.getDayNote;
-
-    /**
-     * Returns day note for the first date of the week of the given date. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @param {string} date - e.g. "2019-04-29"
-     * @return {Promise<FNote>}
-     */
-     this.getWeekNote = dateNotesService.getWeekNote;
-
-    /**
-     * Returns month-note. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @param {string} month - e.g. "2019-04"
-     * @return {Promise<FNote>}
-     */
-    this.getMonthNote = dateNotesService.getMonthNote;
-
-    /**
-     * Returns year-note. If it doesn't exist, it is automatically created.
-     *
-     * @method
-     * @param {string} year - e.g. "2019"
-     * @return {Promise<FNote>}
-     */
-    this.getYearNote = dateNotesService.getYearNote;
-
-    /**
-     * Hoist note in the current tab. See https://github.com/zadam/trilium/wiki/Note-hoisting
-     *
-     * @method
-     * @param {string} noteId - set hoisted note. 'root' will effectively unhoist
-     * @return {Promise}
-     */
-    this.setHoistedNoteId = (noteId) => {
-        const activeNoteContext = appContext.tabManager.getActiveContext();
-
-        if (activeNoteContext) {
-            activeNoteContext.setHoistedNoteId(noteId);
-        }
-    };
-
-    /**
-     * @method
-     * @param {string} keyboardShortcut - e.g. "ctrl+shift+a"
-     * @param {function} handler
-     * @param {string} [namespace] - specify namespace of the handler for the cases where call for bind may be repeated.
-     *                               If a handler with this ID exists, it's replaced by the new handler.
-     */
-    this.bindGlobalShortcut = shortcutService.bindGlobalShortcut;
-
-    /**
-     * Trilium runs in backend and frontend process, when something is changed on the backend from script,
-     * frontend will get asynchronously synchronized.
-     *
-     * This method returns a promise which resolves once all the backend -> frontend synchronization is finished.
-     * Typical use case is when new note has been created, we should wait until it is synced into frontend and only then activate it.
-     *
-     * @method
-     */
-    this.waitUntilSynced = ws.waitForMaxKnownEntityChangeId;
-
-    /**
-     * This will refresh all currently opened notes which have included note specified in the parameter
-     *
-     * @param includedNoteId - noteId of the included note
-     */
-    this.refreshIncludedNote = includedNoteId => appContext.triggerEvent('refreshIncludedNote', {noteId: includedNoteId});
-
-    /**
-     * Return randomly generated string of given length. This random string generation is NOT cryptographically secure.
-     *
-     * @method
-     * @param {number} length of the string
-     * @returns {string} random string
-     */
-    this.randomString = utils.randomString;
-
-    this.logMessages = {};
-    this.logSpacedUpdates = {};
-
-    /**
-     * Log given message to the log pane in UI
-     *
-     * @param message
-     */
-    this.log = message => {
-        const {noteId} = this.startNote;
-
-        message = `${utils.now()}: ${message}`;
-
-        console.log(`Script ${noteId}: ${message}`);
-
-        this.logMessages[noteId] = this.logMessages[noteId] || [];
-        this.logSpacedUpdates[noteId] = this.logSpacedUpdates[noteId] || new SpacedUpdate(() => {
-            const messages = this.logMessages[noteId];
-            this.logMessages[noteId] = [];
-
-            appContext.triggerEvent("apiLogMessages", {noteId, messages});
-        }, 100);
-
-        this.logMessages[noteId].push(message);
-        this.logSpacedUpdates[noteId].scheduleUpdate();
-    };
-}
-
-export default FrontendScriptApi;
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/frontend_api/widgets_collapsible_widget.js.html b/docs/frontend_api/widgets_collapsible_widget.js.html deleted file mode 100644 index 94ae6982e..000000000 --- a/docs/frontend_api/widgets_collapsible_widget.js.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - JSDoc: Source: widgets/collapsible_widget.js - - - - - - - - - - -
- -

Source: widgets/collapsible_widget.js

- - - - - - -
-
-
import NoteContextAwareWidget from "./note_context_aware_widget.js";
-
-const WIDGET_TPL = `
-<div class="card widget">
-    <div class="card-header"></div>
-
-    <div id="[to be set]" class="body-wrapper">
-        <div class="card-body"></div>
-    </div>
-</div>`;
-
-/**
- * TODO: rename, it's not collapsible anymore
- */
-export default class CollapsibleWidget extends NoteContextAwareWidget {
-    get widgetTitle() { return "Untitled widget"; }
-
-    get help() { return {}; }
-
-    doRender() {
-        this.$widget = $(WIDGET_TPL);
-        this.contentSized();
-        this.$widget.find('[data-target]').attr('data-target', `#${this.componentId}`);
-
-        this.$bodyWrapper = this.$widget.find('.body-wrapper');
-        this.$bodyWrapper.attr('id', this.componentId); // for toggle to work we need id
-
-        this.$body = this.$bodyWrapper.find('.card-body');
-
-        this.$title = this.$widget.find('.card-header');
-        this.$title.text(this.widgetTitle);
-
-        this.initialized = this.doRenderBody();
-    }
-
-    /** for overriding */
-    async doRenderBody() {}
-}
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/jsdoc-conf.json b/jsdoc-conf.json index c0451f5b4..3a20f8015 100644 --- a/jsdoc-conf.json +++ b/jsdoc-conf.json @@ -1,7 +1,8 @@ { "templates": { "default": { - "includeDate": false + "includeDate": false, + "outputSourceFiles": false } } } \ No newline at end of file diff --git a/package.json b/package.json index 875a99a34..9b355c140 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "switch-server": "rm -r ./node_modules/better-sqlite3 && npm install", "switch-electron": "rm -r ./node_modules/better-sqlite3 && npm install && ./node_modules/.bin/electron-rebuild", "build-backend-docs": "rm -r ./docs/backend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/becca/entities/*.js src/services/backend_script_api.js src/services/sql.js", - "build-frontend-docs": "rm -r ./docs/frontend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/collapsible_widget.js", + "build-frontend-docs": "rm -r ./docs/frontend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/right_panel_widget.js", "build-docs": "npm run build-backend-docs && npm run build-frontend-docs", "webpack": "npx webpack -c webpack-desktop.config.js && npx webpack -c webpack-mobile.config.js && npx webpack -c webpack-setup.config.js", "test-jasmine": "jasmine", diff --git a/src/becca/becca.js b/src/becca/becca.js index cbcbc1b03..b2fcf7f97 100644 --- a/src/becca/becca.js +++ b/src/becca/becca.js @@ -98,7 +98,7 @@ class Becca { return filteredNotes; } - /** @returns {Branch|null} */ + /** @returns {BBranch|null} */ getBranch(branchId) { return this.branches[branchId]; } @@ -108,7 +108,7 @@ class Becca { return this.attributes[attributeId]; } - /** @returns {Branch|null} */ + /** @returns {BBranch|null} */ getBranchFromChildAndParent(childNoteId, parentNoteId) { return this.childParentToBranch[`${childNoteId}-${parentNoteId}`]; } diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index 8936b976e..83ed8e4c6 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -89,7 +89,7 @@ class BNote extends AbstractBeccaEntity { } init() { - /** @type {Branch[]} + /** @type {BBranch[]} * @private */ this.parentBranches = []; /** @type {BNote[]} @@ -151,7 +151,7 @@ class BNote extends AbstractBeccaEntity { return this.isContentAvailable() ? this.title : '[protected]'; } - /** @returns {Branch[]} */ + /** @returns {BBranch[]} */ getParentBranches() { return this.parentBranches; } @@ -159,14 +159,14 @@ class BNote extends AbstractBeccaEntity { /** * Returns strong (as opposed to weak) parent branches. See isWeak for details. * - * @returns {Branch[]} + * @returns {BBranch[]} */ getStrongParentBranches() { return this.getParentBranches().filter(branch => !branch.isWeak); } /** - * @returns {Branch[]} + * @returns {BBranch[]} * @deprecated use getParentBranches() instead */ getBranches() { @@ -188,7 +188,7 @@ class BNote extends AbstractBeccaEntity { return this.children && this.children.length > 0; } - /** @returns {Branch[]} */ + /** @returns {BBranch[]} */ getChildBranches() { return this.children.map(childNote => this.becca.getBranchFromChildAndParent(childNote.noteId, this.noteId)); } diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index 3899d2f36..c936cd4a5 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -7,7 +7,7 @@ import noteTooltipService from './note_tooltip.js'; import protectedSessionService from './protected_session.js'; import dateNotesService from './date_notes.js'; import searchService from './search.js'; -import CollapsibleWidget from '../widgets/collapsible_widget.js'; +import RightPanelWidget from '../widgets/right_panel_widget.js'; import ws from "./ws.js"; import appContext from "../components/app_context.js"; import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js"; @@ -35,8 +35,14 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain // to keep consistency with backend API this.dayjs = dayjs; - /** @property {CollapsibleWidget} */ - this.CollapsibleWidget = CollapsibleWidget; + /** + * @property {RightPanelWidget} + * @deprecated use api.RightPanelWidget instead + */ + this.CollapsibleWidget = RightPanelWidget; + + /** @property {RightPanelWidget} */ + this.RightPanelWidget = RightPanelWidget; /** @property {NoteContextAwareWidget} */ this.NoteContextAwareWidget = NoteContextAwareWidget; @@ -123,22 +129,18 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain } }; - /** - * @typedef {Object} AddButtonToToolbarOptions - * @property {string} [id] - id of the button, used to identify the old instances of this button to be replaced - * ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only. - * @property {string} title - * @property {string} [icon] - name of the boxicon to be used (e.g. "time" for "bx-time" icon) - * @property {function} action - callback handling the click on the button - * @property {string} [shortcut] - keyboard shortcut for the button, e.g. "alt+t" - */ - /** * Adds a new launcher to the launchbar. If the launcher (id) already exists, it will be updated. * * @deprecated you can now create/modify launchers in the top-left Menu -> Configure Launchbar * for special needs there's also backend API's createOrUpdateLauncher() - * @param {AddButtonToToolbarOptions} opts + * @param {object} opts + * @property {string} [opts.id] - id of the button, used to identify the old instances of this button to be replaced + * ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only. + * @property {string} opts.title + * @property {string} [opts.icon] - name of the boxicon to be used (e.g. "time" for "bx-time" icon) + * @property {function} opts.action - callback handling the click on the button + * @property {string} [opts.shortcut] - keyboard shortcut for the button, e.g. "alt+t" */ this.addButtonToToolbar = async opts => { console.warn("api.addButtonToToolbar() has been deprecated since v0.58 and may be removed in the future. Use Menu -> Configure Launchbar to create/update launchers instead."); diff --git a/src/public/app/widgets/ribbon_widgets/edited_notes.js b/src/public/app/widgets/ribbon_widgets/edited_notes.js index a68450a47..1da61cca3 100644 --- a/src/public/app/widgets/ribbon_widgets/edited_notes.js +++ b/src/public/app/widgets/ribbon_widgets/edited_notes.js @@ -1,7 +1,7 @@ -import CollapsibleWidget from "../collapsible_widget.js"; import linkService from "../../services/link.js"; import server from "../../services/server.js"; import froca from "../../services/froca.js"; +import NoteContextAwareWidget from "../note_context_aware_widget.js"; const TPL = `
@@ -20,7 +20,7 @@ const TPL = `
`; -export default class EditedNotesWidget extends CollapsibleWidget { +export default class EditedNotesWidget extends NoteContextAwareWidget { get name() { return "editedNotes"; } diff --git a/src/public/app/widgets/collapsible_widget.js b/src/public/app/widgets/right_panel_widget.js similarity index 85% rename from src/public/app/widgets/collapsible_widget.js rename to src/public/app/widgets/right_panel_widget.js index 97f28c317..a173dc759 100644 --- a/src/public/app/widgets/collapsible_widget.js +++ b/src/public/app/widgets/right_panel_widget.js @@ -9,10 +9,7 @@ const WIDGET_TPL = ` `; -/** - * TODO: rename, it's not collapsible anymore - */ -export default class CollapsibleWidget extends NoteContextAwareWidget { +export default class RightPanelWidget extends NoteContextAwareWidget { get widgetTitle() { return "Untitled widget"; } get help() { return {}; } @@ -33,6 +30,6 @@ export default class CollapsibleWidget extends NoteContextAwareWidget { this.initialized = this.doRenderBody(); } - /** for overriding */ + /* for overriding */ async doRenderBody() {} } diff --git a/src/public/app/widgets/toc.js b/src/public/app/widgets/toc.js index 1e9dfeb4c..450bc6ded 100644 --- a/src/public/app/widgets/toc.js +++ b/src/public/app/widgets/toc.js @@ -15,7 +15,7 @@ */ import attributeService from "../services/attributes.js"; -import CollapsibleWidget from "./collapsible_widget.js"; +import RightPanelWidget from "./right_panel_widget.js"; import options from "../services/options.js"; const TPL = `
@@ -76,7 +76,7 @@ function findHeadingNodeByIndex(parent, headingIndex) { return headingNode; } -export default class TocWidget extends CollapsibleWidget { +export default class TocWidget extends RightPanelWidget { get widgetTitle() { return "Table of Contents"; } diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index 2d02c6896..fb9b96a0e 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -68,7 +68,7 @@ function BackendScriptApi(currentNote, apiParams) { /** * @method * @param {string} branchId - * @returns {Branch|null} + * @returns {BBranch|null} */ this.getBranch = branchId => becca.getBranch(branchId); @@ -171,20 +171,13 @@ function BackendScriptApi(currentNote, apiParams) { */ this.toggleNoteInParent = cloningService.toggleNoteInParent; - /** - * @typedef {object} CreateNoteAttribute - * @property {string} type - attribute type - label, relation etc. - * @property {string} name - attribute name - * @property {string} [value] - attribute value - */ - /** * Create text note. See also createNewNote() for more options. * * @param {string} parentNoteId * @param {string} title * @param {string} content - * @return {{note: BNote, branch: Branch}} - object having "note" and "branch" keys representing respective objects + * @return {{note: BNote, branch: BBranch}} - object having "note" and "branch" keys representing respective objects */ this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({ parentNoteId, @@ -200,7 +193,7 @@ function BackendScriptApi(currentNote, apiParams) { * @param {string} parentNoteId * @param {string} title * @param {object} content - * @return {{note: BNote, branch: Branch}} object having "note" and "branch" keys representing respective objects + * @return {{note: BNote, branch: BBranch}} object having "note" and "branch" keys representing respective objects */ this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({ parentNoteId, @@ -210,43 +203,23 @@ function BackendScriptApi(currentNote, apiParams) { mime: 'application/json' }); - /** - * @typedef {object} CreateNewNoteParams - * @property {string} parentNoteId - MANDATORY - * @property {string} title - MANDATORY - * @property {string|buffer} content - MANDATORY - * @property {string} type - text, code, file, image, search, book, relationMap, canvas - MANDATORY - * @property {string} mime - value is derived from default mimes for type - * @property {boolean} isProtected - default is false - * @property {boolean} isExpanded - default is false - * @property {string} prefix - default is empty string - * @property {int} notePosition - default is last existing notePosition in a parent + 10 - */ - /** * @method * - * @param {CreateNewNoteParams} [params] - * @returns {{note: BNote, branch: Branch}} object contains newly created entities note and branch + * @property {object} params + * @property {string} params.parentNoteId + * @property {string} params.title + * @property {string|buffer} params.content + * @property {string} params.type - text, code, file, image, search, book, relationMap, canvas + * @property {string} [params.mime] - value is derived from default mimes for type + * @property {boolean} [params.isProtected=false] + * @property {boolean} [params.isExpanded=false] + * @property {string} [params.prefix=''] + * @property {int} [params.notePosition] - default is last existing notePosition in a parent + 10 + * @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch */ this.createNewNote = noteService.createNewNote; - /** - * @typedef {object} CreateNoteAttribute - * @property {string} type - attribute type - label, relation etc. - * @property {string} name - attribute name - * @property {string} [value] - attribute value - */ - - /** - * @typedef {object} CreateNoteExtraOptions - * @property {boolean} [json=false] - should the note be JSON - * @property {boolean} [isProtected=false] - should the note be protected - * @property {string} [type='text'] - note type - * @property {string} [mime='text/html'] - MIME type of the note - * @property {CreateNoteAttribute[]} [attributes=[]] - attributes to be created for this note - */ - /** * @method * @deprecated please use createTextNote() with similar API for simpler use cases or createNewNote() for more complex needs @@ -254,8 +227,16 @@ function BackendScriptApi(currentNote, apiParams) { * @param {string} parentNoteId - create new note under this parent * @param {string} title * @param {string} [content=""] - * @param {CreateNoteExtraOptions} [extraOptions={}] - * @returns {{note: BNote, branch: Branch}} object contains newly created entities note and branch + * @param {object} [extraOptions={}] + * @property {boolean} [extraOptions.json=false] - should the note be JSON + * @property {boolean} [extraOptions.isProtected=false] - should the note be protected + * @property {string} [extraOptions.type='text'] - note type + * @property {string} [extraOptions.mime='text/html'] - MIME type of the note + * @property {object[]} [extraOptions.attributes=[]] - attributes to be created for this note + * @property {string} extraOptions.attributes.type - attribute type - label, relation etc. + * @property {string} extraOptions.attributes.name - attribute name + * @property {string} [extraOptions.attributes.value] - attribute value + * @returns {{note: BNote, branch: BBranch}} object contains newly created entities note and branch */ this.createNote = (parentNoteId, title, content = "", extraOptions= {}) => { extraOptions.parentNoteId = parentNoteId; @@ -398,20 +379,16 @@ function BackendScriptApi(currentNote, apiParams) { */ this.sortNotesByTitle = parentNoteId => treeService.sortNotes(parentNoteId); - /** - * @typedef {Object} SortConfig - * @property {string} [sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name - * see https://github.com/zadam/trilium/wiki/Sorting for details. - * @property {boolean} [reverse=false] - * @property {boolean} [foldersFirst=false] - */ - /** * Sort child notes of a given note. * * @method * @param {string} parentNoteId - this note's child notes will be sorted - * @param {SortConfig} [sortConfig] + * @param {object} [sortConfig] + * @property {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name + * see https://github.com/zadam/trilium/wiki/Sorting for details. + * @property {boolean} [sortConfig.reverse=false] + * @property {boolean} [sortConfig.foldersFirst=false] */ this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes( parentNoteId, @@ -484,27 +461,24 @@ function BackendScriptApi(currentNote, apiParams) { * @return {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version */ this.getAppInfo = () => appInfo - - /** - * @typedef {Object} CreateOrUpdateLauncher - * @property {string} id - id of the launcher, only alphanumeric at least 6 characters long - * @property {string} type - one of - * * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param) - * * "script" - activating the launcher will execute the script (specified in scriptNoteId param) - * * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param) - * @property {string} title - * @property {boolean} [isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers" - * @property {string} [icon] - name of the boxicon to be used (e.g. "bx-time") - * @property {string} [keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e" - * @property {string} [targetNoteId] - for type "note" - * @property {string} [scriptNoteId] - for type "script" - * @property {string} [widgetNoteId] - for type "customWidget" - */ - + /** * Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated. * - * @param {CreateOrUpdateLauncher} opts + * @param {object} opts + * @property {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long + * @property {string} opts.type - one of + * * "note" - activating the launcher will navigate to the target note (specified in targetNoteId param) + * * "script" - activating the launcher will execute the script (specified in scriptNoteId param) + * * "customWidget" - the launcher will be rendered with a custom widget (specified in widgetNoteId param) + * @property {string} opts.title + * @property {boolean} [opts.isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers" + * @property {string} [opts.icon] - name of the boxicon to be used (e.g. "bx-time") + * @property {string} [opts.keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e" + * @property {string} [opts.targetNoteId] - for type "note" + * @property {string} [opts.scriptNoteId] - for type "script" + * @property {string} [opts.widgetNoteId] - for type "customWidget" + * @returns {{note: BNote}} */ this.createOrUpdateLauncher = opts => { if (!opts.id) { throw new Error("ID is a mandatory parameter for api.createOrUpdateLauncher(opts)"); } @@ -561,6 +535,8 @@ function BackendScriptApi(currentNote, apiParams) { } else { launcherNote.removeLabel('keyboardShortcut'); } + + return {note: launcherNote}; }; /** diff --git a/src/services/export/zip.js b/src/services/export/zip.js index c1e48fcab..75429909b 100644 --- a/src/services/export/zip.js +++ b/src/services/export/zip.js @@ -19,7 +19,7 @@ const ValidationError = require("../../errors/validation_error"); /** * @param {TaskContext} taskContext - * @param {Branch} branch + * @param {BBranch} branch * @param {string} format - 'html' or 'markdown' */ async function exportToZip(taskContext, branch, format, res, setHeaders = true) {