improvements in API docs generation

This commit is contained in:
zadam 2023-01-05 23:38:41 +01:00
parent 19f4870280
commit d7cae7d5bb
30 changed files with 189 additions and 138 deletions

16
bin/build-api-docs.sh Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
rm -rf ./tmp/api_docs/backend_api
rm -rf ./tmp/api_docs/frontend_api
./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./tmp/api_docs/backend_api src/becca/entities/*.js \
src/services/backend_script_api.js src/services/sql.js
./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./tmp/api_docs/frontend_api src/public/app/entities/*.js \
src/public/app/services/frontend_script_api.js src/public/app/widgets/right_panel_widget.js
rm -rf ./docs/api_docs/backend_api ./docs/api_docs/frontend_api
node src/transform_api_docs.js
rm -rf ./docs/api_docs/fonts ./docs/api_docs/styles ./docs/api_docs/scripts ./docs/api_docs/backend_api/index.html ./docs/api_docs/frontend_api/index.html

View File

@ -19,9 +19,7 @@
"start-electron-no-dir": "cross-env TRILIUM_ENV=dev electron --inspect=5858 .", "start-electron-no-dir": "cross-env TRILIUM_ENV=dev electron --inspect=5858 .",
"switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install", "switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install",
"switch-electron": "rm -rf ./node_modules/better-sqlite3 && npm install && ./node_modules/.bin/electron-rebuild", "switch-electron": "rm -rf ./node_modules/better-sqlite3 && npm install && ./node_modules/.bin/electron-rebuild",
"build-backend-docs": "rm -rf ./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-api-docs": "./bin/build-api-docs.sh",
"build-frontend-docs": "rm -rf ./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", "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", "test-jasmine": "jasmine",
"test-es6": "node -r esm spec-es6/attribute_parser.spec.js ", "test-es6": "node -r esm spec-es6/attribute_parser.spec.js ",

View File

@ -36,7 +36,7 @@ class Becca {
return this.getNote('root'); return this.getNote('root');
} }
/** @returns {Attribute[]} */ /** @returns {BAttribute[]} */
findAttributes(type, name) { findAttributes(type, name) {
name = name.trim().toLowerCase(); name = name.trim().toLowerCase();
@ -47,7 +47,7 @@ class Becca {
return this.attributeIndex[`${type}-${name}`] || []; return this.attributeIndex[`${type}-${name}`] || [];
} }
/** @returns {Attribute[]} */ /** @returns {BAttribute[]} */
findAttributesWithPrefix(type, name) { findAttributesWithPrefix(type, name) {
const resArr = []; const resArr = [];
const key = `${type}-${name}`; const key = `${type}-${name}`;
@ -103,7 +103,7 @@ class Becca {
return this.branches[branchId]; return this.branches[branchId];
} }
/** @returns {Attribute|null} */ /** @returns {BAttribute|null} */
getAttribute(attributeId) { getAttribute(attributeId) {
return this.attributes[attributeId]; return this.attributes[attributeId];
} }

View File

@ -39,7 +39,7 @@ function isArchived(noteId) {
/** /**
* @param {string} noteId * @param {string} noteId
* @param {string} ancestorNoteId * @param {string} ancestorNoteId
* @return {boolean} - true if given noteId has ancestorNoteId in any of its paths (even archived) * @returns {boolean} - true if given noteId has ancestorNoteId in any of its paths (even archived)
*/ */
function isInAncestor(noteId, ancestorNoteId) { function isInAncestor(noteId, ancestorNoteId) {
if (ancestorNoteId === 'root' || ancestorNoteId === noteId) { if (ancestorNoteId === 'root' || ancestorNoteId === noteId) {

View File

@ -152,7 +152,7 @@ class BAttribute extends AbstractBeccaEntity {
} }
/** /**
* @return {boolean} * @returns {boolean}
*/ */
isDefinition() { isDefinition() {
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:')); return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));

View File

@ -140,7 +140,7 @@ class BBranch extends AbstractBeccaEntity {
* @param {string} [deleteId] - optional delete identified * @param {string} [deleteId] - optional delete identified
* @param {TaskContext} [taskContext] * @param {TaskContext} [taskContext]
* *
* @return {boolean} - true if note has been deleted, false otherwise * @returns {boolean} - true if note has been deleted, false otherwise
*/ */
deleteBranch(deleteId, taskContext) { deleteBranch(deleteId, taskContext) {
if (!deleteId) { if (!deleteId) {

View File

@ -98,18 +98,18 @@ class BNote extends AbstractBeccaEntity {
/** @type {BNote[]} /** @type {BNote[]}
* @private*/ * @private*/
this.children = []; this.children = [];
/** @type {Attribute[]} /** @type {BAttribute[]}
* @private */ * @private */
this.ownedAttributes = []; this.ownedAttributes = [];
/** @type {Attribute[]|null} /** @type {BAttribute[]|null}
* @private */ * @private */
this.__attributeCache = null; this.__attributeCache = null;
/** @type {Attribute[]|null} /** @type {BAttribute[]|null}
* @private*/ * @private*/
this.inheritableAttributeCache = null; this.inheritableAttributeCache = null;
/** @type {Attribute[]} /** @type {BAttribute[]}
* @private*/ * @private*/
this.targetRelations = []; this.targetRelations = [];
@ -369,7 +369,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [type] - (optional) attribute type to filter * @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter * @param {string} [name] - (optional) attribute name to filter
* @returns {Attribute[]} all note's attributes, including inherited ones * @returns {BAttribute[]} all note's attributes, including inherited ones
*/ */
getAttributes(type, name) { getAttributes(type, name) {
this.__validateTypeName(type, name); this.__validateTypeName(type, name);
@ -449,7 +449,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @private * @private
* @returns {Attribute[]} * @returns {BAttribute[]}
*/ */
__getInheritableAttributes(path) { __getInheritableAttributes(path) {
if (path.includes(this.noteId)) { if (path.includes(this.noteId)) {
@ -536,25 +536,25 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} name - label name * @param {string} name - label name
* @returns {Attribute|null} label if it exists, null otherwise * @returns {BAttribute|null} label if it exists, null otherwise
*/ */
getLabel(name) { return this.getAttribute(LABEL, name); } getLabel(name) { return this.getAttribute(LABEL, name); }
/** /**
* @param {string} name - label name * @param {string} name - label name
* @returns {Attribute|null} label if it exists, null otherwise * @returns {BAttribute|null} label if it exists, null otherwise
*/ */
getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); } getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); }
/** /**
* @param {string} name - relation name * @param {string} name - relation name
* @returns {Attribute|null} relation if it exists, null otherwise * @returns {BAttribute|null} relation if it exists, null otherwise
*/ */
getRelation(name) { return this.getAttribute(RELATION, name); } getRelation(name) { return this.getAttribute(RELATION, name); }
/** /**
* @param {string} name - relation name * @param {string} name - relation name
* @returns {Attribute|null} relation if it exists, null otherwise * @returns {BAttribute|null} relation if it exists, null otherwise
*/ */
getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); } getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); }
@ -595,7 +595,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} type - attribute type (label, relation, etc.) * @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name * @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. * @returns {BAttribute} 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) { getAttribute(type, name) {
const attributes = this.getAttributes(); const attributes = this.getAttributes();
@ -627,7 +627,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [name] - label name to filter * @param {string} [name] - label name to filter
* @returns {Attribute[]} all note's labels (attributes with type label), including inherited ones * @returns {BAttribute[]} all note's labels (attributes with type label), including inherited ones
*/ */
getLabels(name) { getLabels(name) {
return this.getAttributes(LABEL, name); return this.getAttributes(LABEL, name);
@ -643,7 +643,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [name] - label name to filter * @param {string} [name] - label name to filter
* @returns {Attribute[]} all note's labels (attributes with type label), excluding inherited ones * @returns {BAttribute[]} all note's labels (attributes with type label), excluding inherited ones
*/ */
getOwnedLabels(name) { getOwnedLabels(name) {
return this.getOwnedAttributes(LABEL, name); return this.getOwnedAttributes(LABEL, name);
@ -659,7 +659,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [name] - relation name to filter * @param {string} [name] - relation name to filter
* @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones * @returns {BAttribute[]} all note's relations (attributes with type relation), including inherited ones
*/ */
getRelations(name) { getRelations(name) {
return this.getAttributes(RELATION, name); return this.getAttributes(RELATION, name);
@ -667,7 +667,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [name] - relation name to filter * @param {string} [name] - relation name to filter
* @returns {Attribute[]} all note's relations (attributes with type relation), excluding inherited ones * @returns {BAttribute[]} all note's relations (attributes with type relation), excluding inherited ones
*/ */
getOwnedRelations(name) { getOwnedRelations(name) {
return this.getOwnedAttributes(RELATION, name); return this.getOwnedAttributes(RELATION, name);
@ -677,7 +677,7 @@ class BNote extends AbstractBeccaEntity {
* @param {string|null} [type] - (optional) attribute type to filter * @param {string|null} [type] - (optional) attribute type to filter
* @param {string|null} [name] - (optional) attribute name to filter * @param {string|null} [name] - (optional) attribute name to filter
* @param {string|null} [value] - (optional) attribute value to filter * @param {string|null} [value] - (optional) attribute value to filter
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones * @returns {BAttribute[]} note's "owned" attributes - excluding inherited ones
*/ */
getOwnedAttributes(type = null, name = null, value = null) { getOwnedAttributes(type = null, name = null, value = null) {
this.__validateTypeName(type, name); this.__validateTypeName(type, name);
@ -700,7 +700,7 @@ class BNote extends AbstractBeccaEntity {
} }
/** /**
* @returns {Attribute} attribute belonging to this specific note (excludes inherited attributes) * @returns {BAttribute} attribute belonging to this specific note (excludes inherited attributes)
* *
* This method can be significantly faster than the getAttribute() * This method can be significantly faster than the getAttribute()
*/ */
@ -735,7 +735,7 @@ class BNote extends AbstractBeccaEntity {
* - fast searching * - fast searching
* - note similarity evaluation * - note similarity evaluation
* *
* @return {string} - returns flattened textual representation of note, prefixes and attributes * @returns {string} - returns flattened textual representation of note, prefixes and attributes
*/ */
getFlatText() { getFlatText() {
if (!this.flatTextCache) { if (!this.flatTextCache) {
@ -863,7 +863,7 @@ class BNote extends AbstractBeccaEntity {
return Array.from(set); return Array.from(set);
} }
/** @return {BNote[]} */ /** @returns {BNote[]} */
getSearchResultNotes() { getSearchResultNotes() {
if (this.type !== 'search') { if (this.type !== 'search') {
return []; return [];
@ -1088,7 +1088,7 @@ class BNote extends AbstractBeccaEntity {
} }
/** /**
* @return {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path) * @returns {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path)
*/ */
getAllNotePaths() { getAllNotePaths() {
if (this.noteId === 'root') { if (this.noteId === 'root') {
@ -1109,7 +1109,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param ancestorNoteId * @param ancestorNoteId
* @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths * @returns {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
*/ */
isDescendantOfNote(ancestorNoteId) { isDescendantOfNote(ancestorNoteId) {
const notePaths = this.getAllNotePaths(); const notePaths = this.getAllNotePaths();
@ -1174,7 +1174,7 @@ class BNote extends AbstractBeccaEntity {
* @param {string} [value] - value of the attribute - text for labels, target note ID for relations; optional. * @param {string} [value] - value of the attribute - text for labels, target note ID for relations; optional.
* @param {boolean} [isInheritable=false] * @param {boolean} [isInheritable=false]
* @param {int} [position] * @param {int} [position]
* @return {Attribute} * @returns {BAttribute}
*/ */
addAttribute(type, name, value = "", isInheritable = false, position = 1000) { addAttribute(type, name, value = "", isInheritable = false, position = 1000) {
const BAttribute = require("./battribute"); const BAttribute = require("./battribute");
@ -1195,7 +1195,7 @@ class BNote extends AbstractBeccaEntity {
* @param {string} name - name of the label, not including the leading # * @param {string} name - name of the label, not including the leading #
* @param {string} [value] - text value of the label; optional * @param {string} [value] - text value of the label; optional
* @param {boolean} [isInheritable=false] * @param {boolean} [isInheritable=false]
* @return {Attribute} * @returns {BAttribute}
*/ */
addLabel(name, value = "", isInheritable = false) { addLabel(name, value = "", isInheritable = false) {
return this.addAttribute(LABEL, name, value, isInheritable); return this.addAttribute(LABEL, name, value, isInheritable);
@ -1208,7 +1208,7 @@ class BNote extends AbstractBeccaEntity {
* @param {string} name - name of the relation, not including the leading ~ * @param {string} name - name of the relation, not including the leading ~
* @param {string} targetNoteId * @param {string} targetNoteId
* @param {boolean} [isInheritable=false] * @param {boolean} [isInheritable=false]
* @return {Attribute} * @returns {BAttribute}
*/ */
addRelation(name, targetNoteId, isInheritable = false) { addRelation(name, targetNoteId, isInheritable = false) {
return this.addAttribute(RELATION, name, targetNoteId, isInheritable); return this.addAttribute(RELATION, name, targetNoteId, isInheritable);
@ -1359,7 +1359,7 @@ class BNote extends AbstractBeccaEntity {
} }
/** /**
* @return {BNoteRevision|null} * @returns {BNoteRevision|null}
*/ */
saveNoteRevision() { saveNoteRevision() {
const content = this.getContent(); const content = this.getContent();

View File

@ -88,12 +88,12 @@ class AppContext extends Component {
this.triggerEvent('initialRenderComplete'); this.triggerEvent('initialRenderComplete');
} }
/** @returns {Promise} */ /** @returns {Promise<void>} */
triggerEvent(name, data) { triggerEvent(name, data) {
return this.handleEvent(name, data); return this.handleEvent(name, data);
} }
/** @returns {Promise} */ /** @returns {Promise<*>} */
triggerCommand(name, data = {}) { triggerCommand(name, data = {}) {
for (const executor of this.components) { for (const executor of this.components) {
const fun = executor[`${name}Command`]; const fun = executor[`${name}Command`];

View File

@ -40,7 +40,7 @@ export default class Component {
return this; return this;
} }
/** @returns {Promise} */ /** @returns {Promise<void>} */
handleEvent(name, data) { handleEvent(name, data) {
try { try {
const callMethodPromise = this.initialized const callMethodPromise = this.initialized
@ -61,12 +61,12 @@ export default class Component {
} }
} }
/** @returns {Promise} */ /** @returns {Promise<void>} */
triggerEvent(name, data) { triggerEvent(name, data) {
return this.parent.triggerEvent(name, data); return this.parent.triggerEvent(name, data);
} }
/** @returns {Promise} */ /** @returns {Promise<void>} */
handleEventInChildren(name, data) { handleEventInChildren(name, data) {
const promises = []; const promises = [];
@ -82,7 +82,7 @@ export default class Component {
return promises.length > 0 ? Promise.all(promises) : null; return promises.length > 0 ? Promise.all(promises) : null;
} }
/** @returns {Promise} */ /** @returns {Promise<*>} */
triggerCommand(name, data = {}) { triggerCommand(name, data = {}) {
const fun = this[`${name}Command`]; const fun = this[`${name}Command`];

View File

@ -738,7 +738,7 @@ class FNote {
/** /**
* Return note complement which is most importantly note's content * Return note complement which is most importantly note's content
* *
* @return {Promise<FNoteComplement>} * @returns {Promise<FNoteComplement>}
*/ */
async getNoteComplement() { async getNoteComplement() {
return await this.froca.getNoteComplement(this.noteId); return await this.froca.getNoteComplement(this.noteId);

View File

@ -22,7 +22,7 @@ async function removeAttributeById(noteId, attributeId) {
} }
/** /**
* @return {boolean} - returns true if this attribute has the potential to influence the note in the argument. * @returns {boolean} - returns true if this attribute has the potential to influence the note in the argument.
* That can happen in multiple ways: * That can happen in multiple ways:
* 1. attribute is owned by the note * 1. attribute is owned by the note
* 2. attribute is owned by the template of the note * 2. attribute is owned by the template of the note

View File

@ -310,7 +310,7 @@ class Froca {
} }
/** /**
* @return {Promise<FNoteComplement>} * @returns {Promise<FNoteComplement>}
*/ */
async getNoteComplement(noteId) { async getNoteComplement(noteId) {
if (!this.noteComplementPromises[noteId]) { if (!this.noteComplementPromises[noteId]) {

View File

@ -16,10 +16,10 @@ import SpacedUpdate from "./spaced_update.js";
import shortcutService from "./shortcuts.js"; import shortcutService from "./shortcuts.js";
/** /**
* This is the main frontend API interface for scripts. It's published in the local "api" object. * <p>This is the main frontend API interface for scripts. All the properties and methods are published in the "api" object
* available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.startNote.title);</code></p>
* *
* @constructor * @constructor
* @hideconstructor
*/ */
function FrontendScriptApi(startNote, currentNote, originEntity = null, $container = null) { function FrontendScriptApi(startNote, currentNote, originEntity = null, $container = null) {
/** @property {jQuery} container of all the rendered script content */ /** @property {jQuery} container of all the rendered script content */
@ -32,7 +32,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** @property {object|null} entity whose event triggered this execution */ /** @property {object|null} entity whose event triggered this execution */
this.originEntity = originEntity; this.originEntity = originEntity;
// to keep consistency with backend API /** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */
this.dayjs = dayjs; this.dayjs = dayjs;
/** /**
@ -83,7 +83,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced. * Activates newly created note. Compared to this.activateNote() also makes sure that frontend has been fully synced.
* *
* @param {string} notePath (or noteId) * @param {string} notePath (or noteId)
* @return {Promise<void>} * @returns {Promise<void>}
*/ */
this.activateNewNote = async notePath => { this.activateNewNote = async notePath => {
await ws.waitForMaxKnownEntityChangeId(); await ws.waitForMaxKnownEntityChangeId();
@ -95,9 +95,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Open a note in a new tab. * Open a note in a new tab.
* *
* @method
* @param {string} notePath (or noteId) * @param {string} notePath (or noteId)
* @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab * @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab
* @return {Promise<void>} * @returns {Promise<void>}
*/ */
this.openTabWithNote = async (notePath, activate) => { this.openTabWithNote = async (notePath, activate) => {
await ws.waitForMaxKnownEntityChangeId(); await ws.waitForMaxKnownEntityChangeId();
@ -112,9 +113,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Open a note in a new split. * Open a note in a new split.
* *
* @method
* @param {string} notePath (or noteId) * @param {string} notePath (or noteId)
* @param {boolean} activate - set to true to activate the new split, false to stay on the current split * @param {boolean} activate - set to true to activate the new split, false to stay on the current split
* @return {Promise<void>} * @returns {Promise<void>}
*/ */
this.openSplitWithNote = async (notePath, activate) => { this.openSplitWithNote = async (notePath, activate) => {
await ws.waitForMaxKnownEntityChangeId(); await ws.waitForMaxKnownEntityChangeId();
@ -132,6 +134,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Adds a new launcher to the launchbar. If the launcher (id) already exists, it will be updated. * Adds a new launcher to the launchbar. If the launcher (id) already exists, it will be updated.
* *
* @method
* @deprecated you can now create/modify launchers in the top-left Menu -> Configure Launchbar * @deprecated you can now create/modify launchers in the top-left Menu -> Configure Launchbar
* for special needs there's also backend API's createOrUpdateLauncher() * for special needs there's also backend API's createOrUpdateLauncher()
* @param {object} opts * @param {object} opts
@ -170,9 +173,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Executes given anonymous function on the backend. * Executes given anonymous function on the backend.
* Internally this serializes the anonymous function into string and sends it to backend via AJAX. * Internally this serializes the anonymous function into string and sends it to backend via AJAX.
* *
* @method
* @param {string} script - script to be executed on the backend * @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 * @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 * @returns {Promise<*>} return value of the executed function on the backend
*/ */
this.runOnBackend = async (script, params = []) => { this.runOnBackend = async (script, params = []) => {
if (typeof script === "function") { if (typeof script === "function") {
@ -233,8 +237,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Returns note by given noteId. If note is missing from cache, it's loaded. * Returns note by given noteId. If note is missing from cache, it's loaded.
** **
* @method
* @param {string} noteId * @param {string} noteId
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getNote = async noteId => await froca.getNote(noteId); this.getNote = async noteId => await froca.getNote(noteId);
@ -244,17 +249,18 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* This is often used to bulk-fill the cache with notes which would have to be picked one by one * 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()) * otherwise (by e.g. createNoteLink())
* *
* @method
* @param {string[]} noteIds * @param {string[]} noteIds
* @param {boolean} [silentNotFoundError] - don't report error if the note is not found * @param {boolean} [silentNotFoundError] - don't report error if the note is not found
* @return {Promise<FNote[]>} * @returns {Promise<FNote[]>}
*/ */
this.getNotes = async (noteIds, silentNotFoundError = false) => await froca.getNotes(noteIds, silentNotFoundError); this.getNotes = async (noteIds, silentNotFoundError = false) => await froca.getNotes(noteIds, silentNotFoundError);
/** /**
* Update frontend tree (note) cache from the backend. * Update frontend tree (note) cache from the backend.
* *
* @param {string[]} noteIds
* @method * @method
* @param {string[]} noteIds
*/ */
this.reloadNotes = async noteIds => await froca.reloadNotes(noteIds); this.reloadNotes = async noteIds => await froca.reloadNotes(noteIds);
@ -262,7 +268,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Instance name identifies particular Trilium instance. It can be useful for scripts * Instance name identifies particular Trilium instance. It can be useful for scripts
* if some action needs to happen on only one specific instance. * if some action needs to happen on only one specific instance.
* *
* @return {string} * @method
* @returns {string}
*/ */
this.getInstanceName = () => window.glob.instanceName; this.getInstanceName = () => window.glob.instanceName;
@ -316,7 +323,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* @method * @method
* @deprecated - this is now no-op since all the changes should be gracefully handled per widget * @deprecated this is now no-op since all the changes should be gracefully handled per widget
*/ */
this.refreshTree = () => {}; this.refreshTree = () => {};
@ -336,9 +343,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Adds given text to the editor cursor * Adds given text to the editor cursor
* *
* @method
* @deprecated use addTextToActiveContextEditor() instead * @deprecated use addTextToActiveContextEditor() instead
* @param {string} text - this must be clear text, HTML is not supported. * @param {string} text - this must be clear text, HTML is not supported.
* @method
*/ */
this.addTextToActiveTabEditor = text => { this.addTextToActiveTabEditor = text => {
console.warn("api.addTextToActiveTabEditor() is deprecated, use addTextToActiveContextEditor() instead."); console.warn("api.addTextToActiveTabEditor() is deprecated, use addTextToActiveContextEditor() instead.");
@ -349,8 +356,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* Adds given text to the editor cursor * Adds given text to the editor cursor
* *
* @param {string} text - this must be clear text, HTML is not supported.
* @method * @method
* @param {string} text - this must be clear text, HTML is not supported.
*/ */
this.addTextToActiveContextEditor = text => appContext.triggerCommand('addTextToActiveEditor', {text}); this.addTextToActiveContextEditor = text => appContext.triggerCommand('addTextToActiveEditor', {text});
@ -374,8 +381,8 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. * 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 * @method
* @deprecated use getActiveContextTextEditor()
* @param [callback] - callback receiving "textEditor" instance * @param [callback] - callback receiving "textEditor" instance
*/ */
this.getActiveTabTextEditor = callback => { this.getActiveTabTextEditor = callback => {
@ -437,13 +444,15 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** /**
* @method * @method
* @param {object} $el - jquery object on which to setup the tooltip * @param {object} $el - jquery object on which to set up the tooltip
* @returns {Promise<void>}
*/ */
this.setupElementTooltip = noteTooltipService.setupElementTooltip; this.setupElementTooltip = noteTooltipService.setupElementTooltip;
/** /**
* @deprecated use protectNote and protectSubtree instead
* @method * @method
* @deprecated use protectNote and protectSubtree instead
* @returns {Promise<void>}
*/ */
this.protectActiveNote = async () => { this.protectActiveNote = async () => {
const activeNote = appContext.tabManager.getActiveContextNote(); const activeNote = appContext.tabManager.getActiveContextNote();
@ -455,6 +464,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* @method * @method
* @param {string} noteId * @param {string} noteId
* @param {boolean} protect - true to protect note, false to unprotect * @param {boolean} protect - true to protect note, false to unprotect
* @returns {Promise<void>}
*/ */
this.protectNote = async (noteId, protect) => { this.protectNote = async (noteId, protect) => {
await protectedSessionService.protectNote(noteId, protect, false); await protectedSessionService.protectNote(noteId, protect, false);
@ -464,6 +474,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* @method * @method
* @param {string} noteId * @param {string} noteId
* @param {boolean} protect - true to protect subtree, false to unprotect * @param {boolean} protect - true to protect subtree, false to unprotect
* @returns {Promise<void>}
*/ */
this.protectSubTree = async (noteId, protect) => { this.protectSubTree = async (noteId, protect) => {
await protectedSessionService.protectNote(noteId, protect, true); await protectedSessionService.protectNote(noteId, protect, true);
@ -473,7 +484,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Returns date-note for today. If it doesn't exist, it is automatically created. * Returns date-note for today. If it doesn't exist, it is automatically created.
* *
* @method * @method
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getTodayNote = dateNotesService.getTodayNote; this.getTodayNote = dateNotesService.getTodayNote;
@ -482,7 +493,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} date - e.g. "2019-04-29" * @param {string} date - e.g. "2019-04-29"
* @return {Promise<FNote>} * @returns {Promise<FNote>}
* @deprecated use getDayNote instead * @deprecated use getDayNote instead
*/ */
this.getDateNote = dateNotesService.getDayNote; this.getDateNote = dateNotesService.getDayNote;
@ -492,7 +503,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} date - e.g. "2019-04-29" * @param {string} date - e.g. "2019-04-29"
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getDayNote = dateNotesService.getDayNote; this.getDayNote = dateNotesService.getDayNote;
@ -501,7 +512,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} date - e.g. "2019-04-29" * @param {string} date - e.g. "2019-04-29"
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getWeekNote = dateNotesService.getWeekNote; this.getWeekNote = dateNotesService.getWeekNote;
@ -510,7 +521,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} month - e.g. "2019-04" * @param {string} month - e.g. "2019-04"
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getMonthNote = dateNotesService.getMonthNote; this.getMonthNote = dateNotesService.getMonthNote;
@ -519,7 +530,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} year - e.g. "2019" * @param {string} year - e.g. "2019"
* @return {Promise<FNote>} * @returns {Promise<FNote>}
*/ */
this.getYearNote = dateNotesService.getYearNote; this.getYearNote = dateNotesService.getYearNote;
@ -528,7 +539,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* *
* @method * @method
* @param {string} noteId - set hoisted note. 'root' will effectively unhoist * @param {string} noteId - set hoisted note. 'root' will effectively unhoist
* @return {Promise} * @returns {Promise<void>}
*/ */
this.setHoistedNoteId = (noteId) => { this.setHoistedNoteId = (noteId) => {
const activeNoteContext = appContext.tabManager.getActiveContext(); const activeNoteContext = appContext.tabManager.getActiveContext();
@ -544,6 +555,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* @param {function} handler * @param {function} handler
* @param {string} [namespace] - specify namespace of the handler for the cases where call for bind may be repeated. * @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. * If a handler with this ID exists, it's replaced by the new handler.
* @returns {Promise<void>}
*/ */
this.bindGlobalShortcut = shortcutService.bindGlobalShortcut; this.bindGlobalShortcut = shortcutService.bindGlobalShortcut;
@ -555,6 +567,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Typical use case is when new note has been created, we should wait until it is synced into frontend and only then activate it. * 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 * @method
* @returns {Promise<void>}
*/ */
this.waitUntilSynced = ws.waitForMaxKnownEntityChangeId; this.waitUntilSynced = ws.waitForMaxKnownEntityChangeId;
@ -562,6 +575,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* This will refresh all currently opened notes which have included note specified in the parameter * This will refresh all currently opened notes which have included note specified in the parameter
* *
* @param includedNoteId - noteId of the included note * @param includedNoteId - noteId of the included note
* @returns {Promise<void>}
*/ */
this.refreshIncludedNote = includedNoteId => appContext.triggerEvent('refreshIncludedNote', {noteId: includedNoteId}); this.refreshIncludedNote = includedNoteId => appContext.triggerEvent('refreshIncludedNote', {noteId: includedNoteId});
@ -581,6 +595,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* Log given message to the log pane in UI * Log given message to the log pane in UI
* *
* @param message * @param message
* @returns {void}
*/ */
this.log = message => { this.log = message => {
const {noteId} = this.startNote; const {noteId} = this.startNote;

View File

@ -115,7 +115,7 @@ export default class LoadResults {
} }
/** /**
* @return {boolean} true if there are changes which could affect the attributes (including inherited ones) * @returns {boolean} true if there are changes which could affect the attributes (including inherited ones)
* notably changes in note itself should not have any effect on attributes * notably changes in note itself should not have any effect on attributes
*/ */
hasAttributeRelatedChanges() { hasAttributeRelatedChanges() {

View File

@ -6,7 +6,7 @@ import hoistedNoteService from '../services/hoisted_note.js';
import appContext from "../components/app_context.js"; import appContext from "../components/app_context.js";
/** /**
* @return {string|null} * @returns {string|null}
*/ */
async function resolveNotePath(notePath, hoistedNoteId = 'root') { async function resolveNotePath(notePath, hoistedNoteId = 'root') {
const runPath = await resolveNotePathToSegments(notePath, hoistedNoteId); const runPath = await resolveNotePathToSegments(notePath, hoistedNoteId);
@ -19,7 +19,7 @@ async function resolveNotePath(notePath, hoistedNoteId = 'root') {
* notePath as possible. Part of the path might not be valid because of note moving (which causes * notePath as possible. Part of the path might not be valid because of note moving (which causes
* path change) or other corruption, in that case this will try to get some other valid path to the correct note. * path change) or other corruption, in that case this will try to get some other valid path to the correct note.
* *
* @return {string[]} * @returns {string[]}
*/ */
async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) { async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) {
utils.assertArguments(notePath); utils.assertArguments(notePath);

View File

@ -850,7 +850,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
collapseTreeEvent() { this.collapseTree(); } collapseTreeEvent() { this.collapseTree(); }
/** /**
* @return {FancytreeNode|null} * @returns {FancytreeNode|null}
*/ */
getActiveNode() { getActiveNode() {
return this.tree.getActiveNode(); return this.tree.getActiveNode();
@ -859,7 +859,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
/** /**
* focused & not active node can happen during multiselection where the node is selected * focused & not active node can happen during multiselection where the node is selected
* but not activated (its content is not displayed in the detail) * but not activated (its content is not displayed in the detail)
* @return {FancytreeNode|null} * @returns {FancytreeNode|null}
*/ */
getFocusedNode() { getFocusedNode() {
return this.tree.getFocusNode(); return this.tree.getFocusNode();

View File

@ -40,7 +40,7 @@ function getNoteRevision(req) {
/** /**
* @param {BNoteRevision} noteRevision * @param {BNoteRevision} noteRevision
* @return {string} * @returns {string}
*/ */
function getRevisionFilename(noteRevision) { function getRevisionFilename(noteRevision) {
let filename = utils.formatDownloadTitle(noteRevision.title, noteRevision.type, noteRevision.mime); let filename = utils.formatDownloadTitle(noteRevision.title, noteRevision.type, noteRevision.mime);

View File

@ -21,28 +21,28 @@ const branchService = require("./branches");
const exportService = require("./export/zip"); const exportService = require("./export/zip");
/** /**
* This is the main backend API interface for scripts. It's published in the local "api" object. * <p>This is the main backend API interface for scripts. All the properties and methods are published in the "api" object
* available in the JS backend notes. You can use e.g. <code>api.log(api.startNote.title);</code></p>
* *
* @constructor * @constructor
* @hideconstructor
*/ */
function BackendScriptApi(currentNote, apiParams) { function BackendScriptApi(currentNote, apiParams) {
/** @property {BNote} note where script started executing */ /** @property {BNote} note where script started executing */
this.startNote = apiParams.startNote; this.startNote = apiParams.startNote;
/** @property {BNote} note where script is currently executing. Don't mix this up with concept of active note */ /** @property {BNote} note where script is currently executing. Don't mix this up with concept of active note */
this.currentNote = currentNote; this.currentNote = currentNote;
/** @property {Entity} entity whose event triggered this executions */ /** @property {AbstractBeccaEntity} entity whose event triggered this executions */
this.originEntity = apiParams.originEntity; this.originEntity = apiParams.originEntity;
for (const key in apiParams) { for (const key in apiParams) {
this[key] = apiParams[key]; this[key] = apiParams[key];
} }
/** @property {axios} Axios library for HTTP requests. See https://axios-http.com/ for documentation */ /** @property {axios} Axios library for HTTP requests. See {@link https://axios-http.com} for documentation */
this.axios = axios; this.axios = axios;
/** @property {dayjs} day.js library for date manipulation. See https://day.js.org/ for documentation */ /** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */
this.dayjs = dayjs; this.dayjs = dayjs;
/** @property {axios} xml2js library for XML parsing. See https://github.com/Leonidas-from-XIV/node-xml2js for documentation */ /** @property {axios} xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation */
this.xml2js = xml2js; this.xml2js = xml2js;
// DEPRECATED - use direct api.unescapeHtml // DEPRECATED - use direct api.unescapeHtml
@ -75,13 +75,13 @@ function BackendScriptApi(currentNote, apiParams) {
/** /**
* @method * @method
* @param {string} attributeId * @param {string} attributeId
* @returns {Attribute|null} * @returns {BAttribute|null}
*/ */
this.getAttribute = attributeId => becca.getAttribute(attributeId); this.getAttribute = attributeId => becca.getAttribute(attributeId);
/** /**
* This is a powerful search method - you can search by attributes and their values, e.g.: * 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 * "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options
* *
* @method * @method
* @param {string} query * @param {string} query
@ -105,7 +105,7 @@ function BackendScriptApi(currentNote, apiParams) {
/** /**
* This is a powerful search method - you can search by attributes and their values, e.g.: * 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 * "#dateModified =* MONTH AND #log". See {@link https://github.com/zadam/trilium/wiki/Search} for full documentation for all options
* *
* @method * @method
* @param {string} query * @param {string} query
@ -174,10 +174,11 @@ function BackendScriptApi(currentNote, apiParams) {
/** /**
* Create text note. See also createNewNote() for more options. * Create text note. See also createNewNote() for more options.
* *
* @method
* @param {string} parentNoteId * @param {string} parentNoteId
* @param {string} title * @param {string} title
* @param {string} content * @param {string} content
* @return {{note: BNote, branch: BBranch}} - object having "note" and "branch" keys representing respective objects * @returns {{note: BNote, branch: BBranch}} - object having "note" and "branch" keys representing respective objects
*/ */
this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({ this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({
parentNoteId, parentNoteId,
@ -190,10 +191,11 @@ function BackendScriptApi(currentNote, apiParams) {
* Create data note - data in this context means object serializable to JSON. Created note will be of type 'code' and * 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. * JSON MIME type. See also createNewNote() for more options.
* *
* @method
* @param {string} parentNoteId * @param {string} parentNoteId
* @param {string} title * @param {string} title
* @param {object} content * @param {object} content
* @return {{note: BNote, branch: BBranch}} object having "note" and "branch" keys representing respective objects * @returns {{note: BNote, branch: BBranch}} object having "note" and "branch" keys representing respective objects
*/ */
this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({ this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({
parentNoteId, parentNoteId,
@ -280,7 +282,9 @@ function BackendScriptApi(currentNote, apiParams) {
/** /**
* Log given message to trilium logs and log pane in UI * Log given message to trilium logs and log pane in UI
* *
* @method
* @param message * @param message
* @returns {void}
*/ */
this.log = message => { this.log = message => {
log.info(message); log.info(message);
@ -316,7 +320,7 @@ function BackendScriptApi(currentNote, apiParams) {
* *
* @method * @method
* @param {string} date in YYYY-MM-DD format * @param {string} date in YYYY-MM-DD format
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
* @deprecated use getDayNote instead * @deprecated use getDayNote instead
*/ */
@ -327,7 +331,7 @@ function BackendScriptApi(currentNote, apiParams) {
* *
* @method * @method
* @param {string} date in YYYY-MM-DD format * @param {string} date in YYYY-MM-DD format
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
*/ */
this.getDayNote = dateNoteService.getDayNote; this.getDayNote = dateNoteService.getDayNote;
@ -336,7 +340,7 @@ function BackendScriptApi(currentNote, apiParams) {
* Returns today's day note. If such note doesn't exist, it is created. * Returns today's day note. If such note doesn't exist, it is created.
* *
* @method * @method
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
*/ */
this.getTodayNote = dateNoteService.getTodayNote; this.getTodayNote = dateNoteService.getTodayNote;
@ -346,8 +350,9 @@ function BackendScriptApi(currentNote, apiParams) {
* *
* @method * @method
* @param {string} date in YYYY-MM-DD format * @param {string} date in YYYY-MM-DD format
* @param {object} [options] - "startOfTheWeek" - either "monday" (default) or "sunday" * @param {object} [options]
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {string} [options.startOfTheWeek=monday] - either "monday" (default) or "sunday"
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
*/ */
this.getWeekNote = dateNoteService.getWeekNote; this.getWeekNote = dateNoteService.getWeekNote;
@ -357,7 +362,7 @@ function BackendScriptApi(currentNote, apiParams) {
* *
* @method * @method
* @param {string} date in YYYY-MM format * @param {string} date in YYYY-MM format
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
*/ */
this.getMonthNote = dateNoteService.getMonthNote; this.getMonthNote = dateNoteService.getMonthNote;
@ -367,15 +372,16 @@ function BackendScriptApi(currentNote, apiParams) {
* *
* @method * @method
* @param {string} year in YYYY format * @param {string} year in YYYY format
* @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use default calendar * @param {BNote} [rootNote] - specify calendar root note, normally leave empty to use the default calendar
* @returns {BNote|null} * @returns {BNote|null}
*/ */
this.getYearNote = dateNoteService.getYearNote; this.getYearNote = dateNoteService.getYearNote;
/** /**
* @method * @method
* @deprecated - use sortNotes instead * @deprecated use sortNotes instead
* @param {string} parentNoteId - this note's child notes will be sorted * @param {string} parentNoteId - this note's child notes will be sorted
* @returns {void}
*/ */
this.sortNotesByTitle = parentNoteId => treeService.sortNotes(parentNoteId); this.sortNotesByTitle = parentNoteId => treeService.sortNotes(parentNoteId);
@ -386,9 +392,10 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} parentNoteId - this note's child notes will be sorted * @param {string} parentNoteId - this note's child notes will be sorted
* @param {object} [sortConfig] * @param {object} [sortConfig]
* @property {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name * @property {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name
* see https://github.com/zadam/trilium/wiki/Sorting for details. * See {@link https://github.com/zadam/trilium/wiki/Sorting} for details.
* @property {boolean} [sortConfig.reverse=false] * @property {boolean} [sortConfig.reverse=false]
* @property {boolean} [sortConfig.foldersFirst=false] * @property {boolean} [sortConfig.foldersFirst=false]
* @returns {void}
*/ */
this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes( this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes(
parentNoteId, parentNoteId,
@ -404,10 +411,11 @@ function BackendScriptApi(currentNote, apiParams) {
* This method looks similar to toggleNoteInParent() but differs because we're looking up branch by prefix. * This method looks similar to toggleNoteInParent() but differs because we're looking up branch by prefix.
* *
* @method * @method
* @deprecated - this method is pretty confusing and serves specialized purpose only * @deprecated this method is pretty confusing and serves specialized purpose only
* @param {string} noteId * @param {string} noteId
* @param {string} prefix * @param {string} prefix
* @param {string|null} parentNoteId * @param {string|null} parentNoteId
* @returns {void}
*/ */
this.setNoteToParent = treeService.setNoteToParent; this.setNoteToParent = treeService.setNoteToParent;
@ -451,20 +459,23 @@ function BackendScriptApi(currentNote, apiParams) {
/** /**
* @method * @method
* @deprecated - this is now no-op since all the changes should be gracefully handled per widget * @deprecated this is now no-op since all the changes should be gracefully handled per widget
* @returns {void}
*/ */
this.refreshTree = () => { this.refreshTree = () => {
console.warn("api.refreshTree() is a NO-OP and can be removed from your script.") 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 * @method
* @returns {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version
*/ */
this.getAppInfo = () => appInfo this.getAppInfo = () => appInfo
/** /**
* Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated. * Creates a new launcher to the launchbar. If the launcher (id) already exists, it will be updated.
* *
* @method
* @param {object} opts * @param {object} opts
* @property {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long * @property {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long
* @property {string} opts.type - one of * @property {string} opts.type - one of
@ -544,7 +555,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} noteId * @param {string} noteId
* @param {string} format - either 'html' or 'markdown' * @param {string} format - either 'html' or 'markdown'
* @param {string} zipFilePath * @param {string} zipFilePath
* @returns {Promise} * @returns {Promise<void>}
*/ */
this.exportSubtreeToZipFile = async (noteId, format, zipFilePath) => await exportService.exportToZipFile(noteId, format, zipFilePath); this.exportSubtreeToZipFile = async (noteId, format, zipFilePath) => await exportService.exportToZipFile(noteId, format, zipFilePath);

View File

@ -9,7 +9,7 @@ const htmlSanitizer = require('../html_sanitizer');
* @param {TaskContext} taskContext * @param {TaskContext} taskContext
* @param {Buffer} fileBuffer * @param {Buffer} fileBuffer
* @param {BNote} parentNote * @param {BNote} parentNote
* @return {Promise<*[]|*>} * @returns {Promise<*[]|*>}
*/ */
async function importOpml(taskContext, fileBuffer, parentNote) { async function importOpml(taskContext, fileBuffer, parentNote) {
const xml = await new Promise(function(resolve, reject) const xml = await new Promise(function(resolve, reject)

View File

@ -19,7 +19,7 @@ const becca = require("../../becca/becca");
* @param {TaskContext} taskContext * @param {TaskContext} taskContext
* @param {Buffer} fileBuffer * @param {Buffer} fileBuffer
* @param {BNote} importRootNote * @param {BNote} importRootNote
* @return {Promise<*>} * @returns {Promise<*>}
*/ */
async function importZip(taskContext, fileBuffer, importRootNote) { async function importZip(taskContext, fileBuffer, importRootNote) {
// maps from original noteId (in ZIP file) to newly generated noteId // maps from original noteId (in ZIP file) to newly generated noteId

View File

@ -130,7 +130,7 @@ function getAndValidateParent(params) {
* - {integer} notePosition - default is last existing notePosition in a parent + 10 * - {integer} notePosition - default is last existing notePosition in a parent + 10
* *
* @param params * @param params
* @return {{note: BNote, branch: BBranch}} * @returns {{note: BNote, branch: BBranch}}
*/ */
function createNewNote(params) { function createNewNote(params) {
const parentNote = getAndValidateParent(params); const parentNote = getAndValidateParent(params);
@ -674,7 +674,7 @@ function undeleteBranch(branchId, deleteId, taskContext) {
} }
/** /**
* @return return deleted branchIds of an undeleted parent note * @returns return deleted branchIds of an undeleted parent note
*/ */
function getUndeletedParentBranchIds(noteId, deleteId) { function getUndeletedParentBranchIds(noteId, deleteId) {
return sql.getColumn(` return sql.getColumn(`

View File

@ -25,7 +25,7 @@ function getOption(name) {
} }
/** /**
* @return {number} * @returns {number}
*/ */
function getOptionInt(name) { function getOptionInt(name) {
const val = getOption(name); const val = getOption(name);
@ -40,7 +40,7 @@ function getOptionInt(name) {
} }
/** /**
* @return {boolean} * @returns {boolean}
*/ */
function getOptionBool(name) { function getOptionBool(name) {
const val = getOption(name); const val = getOption(name);

View File

@ -9,7 +9,7 @@ class Expression {
* @param {NoteSet} inputNoteSet * @param {NoteSet} inputNoteSet
* @param {object} executionContext * @param {object} executionContext
* @param {SearchContext} searchContext * @param {SearchContext} searchContext
* @return {NoteSet} * @returns {NoteSet}
*/ */
execute(inputNoteSet, executionContext, searchContext) {} execute(inputNoteSet, executionContext, searchContext) {}
} }

View File

@ -123,7 +123,7 @@ class NoteFlatTextExp extends Expression {
* Returns noteIds which have at least one matching tokens * Returns noteIds which have at least one matching tokens
* *
* @param {NoteSet} noteSet * @param {NoteSet} noteSet
* @return {BNote[]} * @returns {BNote[]}
*/ */
getCandidateNotes(noteSet) { getCandidateNotes(noteSet) {
const candidateNotes = []; const candidateNotes = [];

View File

@ -138,7 +138,7 @@ function loadNeededInfoFromDatabase() {
/** /**
* @param {Expression} expression * @param {Expression} expression
* @param {SearchContext} searchContext * @param {SearchContext} searchContext
* @return {SearchResult[]} * @returns {SearchResult[]}
*/ */
function findResultsWithExpression(expression, searchContext) { function findResultsWithExpression(expression, searchContext) {
if (searchContext.dbLoadNeeded) { if (searchContext.dbLoadNeeded) {
@ -230,7 +230,7 @@ function parseQueryToExpression(query, searchContext) {
/** /**
* @param {string} query * @param {string} query
* @return {BNote[]} * @returns {BNote[]}
*/ */
function searchNotes(query, params = {}) { function searchNotes(query, params = {}) {
const searchResults = findResultsWithQuery(query, new SearchContext(params)); const searchResults = findResultsWithQuery(query, new SearchContext(params));
@ -241,7 +241,7 @@ function searchNotes(query, params = {}) {
/** /**
* @param {string} query * @param {string} query
* @param {SearchContext} searchContext * @param {SearchContext} searchContext
* @return {SearchResult[]} * @returns {SearchResult[]}
*/ */
function findResultsWithQuery(query, searchContext) { function findResultsWithQuery(query, searchContext) {
query = query || ""; query = query || "";
@ -259,7 +259,7 @@ function findResultsWithQuery(query, searchContext) {
/** /**
* @param {string} query * @param {string} query
* @param {SearchContext} searchContext * @param {SearchContext} searchContext
* @return {BNote|null} * @returns {BNote|null}
*/ */
function findFirstNoteWithQuery(query, searchContext) { function findFirstNoteWithQuery(query, searchContext) {
const searchResults = findResultsWithQuery(query, searchContext); const searchResults = findResultsWithQuery(query, searchContext);

View File

@ -303,7 +303,7 @@ module.exports = {
* @method * @method
* @param {string} query - SQL query with ? used as parameter placeholder * @param {string} query - SQL query with ? used as parameter placeholder
* @param {object[]} [params] - array of params if needed * @param {object[]} [params] - array of params if needed
* @return [object] - single value * @returns [object] - single value
*/ */
getValue, getValue,
@ -313,7 +313,7 @@ module.exports = {
* @method * @method
* @param {string} query - SQL query with ? used as parameter placeholder * @param {string} query - SQL query with ? used as parameter placeholder
* @param {object[]} [params] - array of params if needed * @param {object[]} [params] - array of params if needed
* @return {object} - map of column name to column value * @returns {object} - map of column name to column value
*/ */
getRow, getRow,
getRowOrNull, getRowOrNull,
@ -324,7 +324,7 @@ module.exports = {
* @method * @method
* @param {string} query - SQL query with ? used as parameter placeholder * @param {string} query - SQL query with ? used as parameter placeholder
* @param {object[]} [params] - array of params if needed * @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 * @returns {object[]} - array of all rows, each row is a map of column name to column value
*/ */
getRows, getRows,
getRawRows, getRawRows,
@ -337,7 +337,7 @@ module.exports = {
* @method * @method
* @param {string} query - SQL query with ? used as parameter placeholder * @param {string} query - SQL query with ? used as parameter placeholder
* @param {object[]} [params] - array of params if needed * @param {object[]} [params] - array of params if needed
* @return {object} - map of first column to second column * @returns {object} - map of first column to second column
*/ */
getMap, getMap,
@ -347,7 +347,7 @@ module.exports = {
* @method * @method
* @param {string} query - SQL query with ? used as parameter placeholder * @param {string} query - SQL query with ? used as parameter placeholder
* @param {object[]} [params] - array of params if needed * @param {object[]} [params] - array of params if needed
* @return {object[]} - array of first column of all returned rows * @returns {object[]} - array of first column of all returned rows
*/ */
getColumn, getColumn,

View File

@ -229,7 +229,7 @@ function sortNotesIfNeeded(parentNoteId) {
} }
/** /**
* @deprecated - this will be removed in the future * @deprecated this will be removed in the future
*/ */
function setNoteToParent(noteId, prefix, parentNoteId) { function setNoteToParent(noteId, prefix, parentNoteId) {
const parentNote = becca.getNote(parentNoteId); const parentNote = becca.getNote(parentNoteId);

View File

@ -38,17 +38,17 @@ class SBranch extends AbstractShacaEntity {
this.shaca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this; this.shaca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this;
} }
/** @return {SNote} */ /** @returns {SNote} */
get childNote() { get childNote() {
return this.shaca.notes[this.noteId]; return this.shaca.notes[this.noteId];
} }
/** @return {SNote} */ /** @returns {SNote} */
getNote() { getNote() {
return this.childNote; return this.childNote;
} }
/** @return {SNote} */ /** @returns {SNote} */
get parentNote() { get parentNote() {
return this.shaca.notes[this.parentNoteId]; return this.shaca.notes[this.parentNoteId];
} }

View File

@ -200,7 +200,7 @@ class SNote extends AbstractShacaEntity {
return this.__attributeCache; return this.__attributeCache;
} }
/** @return {SAttribute[]} */ /** @returns {SAttribute[]} */
__getInheritableAttributes(path) { __getInheritableAttributes(path) {
if (path.includes(this.noteId)) { if (path.includes(this.noteId)) {
return []; return [];

View File

@ -1,13 +1,14 @@
const sanitizeHtml = require('sanitize-html'); const sanitizeHtml = require('sanitize-html');
function transform(content) { function transform(content) {
return sanitizeHtml(content, { const result = sanitizeHtml(content, {
allowedTags: [ allowedTags: [
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div', 'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div',
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'section', 'img', 'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'section', 'img',
'figure', 'figcaption', 'span', 'label', 'input', 'figure', 'figcaption', 'span', 'label', 'input',
], ],
nonTextTags: [ 'style', 'script', 'textarea', 'option', 'h1', 'h2', 'h3', 'nav' ],
allowedAttributes: { allowedAttributes: {
'a': [ 'href', 'class', 'data-note-path' ], 'a': [ 'href', 'class', 'data-note-path' ],
'img': [ 'src' ], 'img': [ 'src' ],
@ -22,19 +23,27 @@ function transform(content) {
'en-media': [ 'hash' ] 'en-media': [ 'hash' ]
}, },
allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'evernote'], allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'evernote'],
// transformTags: { transformTags: {
// 'h1': (tagName, attribs) => { // 'h5': sanitizeHtml.simpleTransform('strong', {}, false),
// return { 'table': sanitizeHtml.simpleTransform('table', {}, false)
// tagName: '<span>', },
// // text: 'ddd'
// };
// }
// },
}); });
return result.replace(/<table>/gi, '<figure class="table"><table>')
.replace(/<\/table>/gi, '</table></figure>')
.replace(/<div><\/div>/gi, '')
.replace(/<h5>/gi, '<p><strong>')
.replace(/<\/h5>/gi, '</strong></p>')
.replace(/<h4>/gi, '<h2>')
.replace(/<\/h4>/gi, '</h2>')
.replace(/<span class="signature-attributes">opt<\/span>/gi, '')
.replace(/<h2>.*new (BackendScriptApi|FrontendScriptApi).*<\/h2>/gi, '')
;
} }
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const html = require("html");
let sourceFiles = []; let sourceFiles = [];
const getFilesRecursively = (directory) => { const getFilesRecursively = (directory) => {
@ -43,24 +52,26 @@ const getFilesRecursively = (directory) => {
const absolute = path.join(directory, file); const absolute = path.join(directory, file);
if (fs.statSync(absolute).isDirectory()) { if (fs.statSync(absolute).isDirectory()) {
getFilesRecursively(absolute); getFilesRecursively(absolute);
} else { } else if (file.endsWith('.html')) {
sourceFiles.push(absolute); sourceFiles.push(absolute);
} }
} }
}; };
getFilesRecursively('./docs'); getFilesRecursively('./tmp/api_docs');
for (const sourcePath of sourceFiles) { for (const sourcePath of sourceFiles) {
console.log("Transforming file", sourcePath); const content = fs.readFileSync(sourcePath).toString();
const content = fs.readFileSync(sourcePath);
const transformedContent = transform(content); const transformedContent = transform(content);
const prettifiedContent = html.prettyPrint(transformedContent, {indent_size: 2});
const filteredContent = prettifiedContent
.replace(/<br \/>Documentation generated by <a href="https:\/\/github.com\/jsdoc\/jsdoc">[^<]+<\/a>/gi, '')
.replace(/JSDoc: (Class|Module): [a-z]+/gi, '');
const destPath = sourcePath.replaceAll("docs", "docs/transformed"); const destPath = sourcePath.replaceAll("tmp", "docs");
fs.mkdirSync(path.dirname(destPath), {recursive: true}); fs.mkdirSync(path.dirname(destPath), {recursive: true});
fs.writeFileSync(destPath, transformedContent); fs.writeFileSync(destPath, filteredContent.trim());
console.log(destPath); console.log(destPath);
} }