From d3730ac1a953e3b07b9e61b9d1ef7e4cf7021d2e Mon Sep 17 00:00:00 2001 From: Zack Rauen Date: Mon, 21 Aug 2023 04:15:53 -0400 Subject: [PATCH] Fix and improve JSDoc for APIs --- package.json | 2 +- src/becca/entities/battachment.js | 10 +- src/becca/entities/battribute.js | 8 +- src/becca/entities/bnote.js | 24 +++- src/public/app/entities/fattachment.js | 9 +- src/public/app/entities/fattribute.js | 7 +- src/public/app/entities/fnote.js | 39 +++++-- .../app/services/frontend_script_api.js | 64 ++++++++--- src/public/app/widgets/basic_widget.js | 16 ++- .../app/widgets/note_context_aware_widget.js | 13 ++- src/public/app/widgets/right_panel_widget.js | 19 +++- src/services/backend_script_api.js | 105 +++++++++++------- 12 files changed, 238 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index 303bbe782..9ff348e93 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "switch-server": "rm -rf ./node_modules/better-sqlite3 && npm install", "switch-electron": "./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-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-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/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js", "build-docs": "npm run build-backend-docs && npm run build-frontend-docs", "webpack": "webpack -c webpack.config.js", "test-jasmine": "jasmine", diff --git a/src/becca/entities/battachment.js b/src/becca/entities/battachment.js index 9da0835f9..2906ef2fe 100644 --- a/src/becca/entities/battachment.js +++ b/src/becca/entities/battachment.js @@ -38,7 +38,10 @@ class BAttachment extends AbstractBeccaEntity { /** @type {string} */ this.attachmentId = row.attachmentId; - /** @type {string} either noteId or revisionId to which this attachment belongs */ + /** + * either noteId or revisionId to which this attachment belongs + * @type {string} + */ this.ownerId = row.ownerId; /** @type {string} */ this.role = row.role; @@ -59,7 +62,10 @@ class BAttachment extends AbstractBeccaEntity { /** @type {string} */ this.utcDateScheduledForErasureSince = row.utcDateScheduledForErasureSince; - /** @type {int} optionally added to the entity */ + /** + * optionally added to the entity + * @type {int} + */ this.contentLength = row.contentLength; this.decrypt(); diff --git a/src/becca/entities/battribute.js b/src/becca/entities/battribute.js index 41046b7e1..d09020269 100644 --- a/src/becca/entities/battribute.js +++ b/src/becca/entities/battribute.js @@ -7,6 +7,12 @@ const dateUtils = require("../../services/date_utils"); const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser"); const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name"); + +/** + * There are currently only two types of attributes, labels or relations. + * @typedef {"label" | "relation"} AttributeType + */ + /** * Attribute is an abstract concept which has two real uses - label (key - value pair) * and relation (representing named relationship between source and target note) @@ -47,7 +53,7 @@ class BAttribute extends AbstractBeccaEntity { this.attributeId = attributeId; /** @type {string} */ this.noteId = noteId; - /** @type {string} */ + /** @type {AttributeType} */ this.type = type; /** @type {string} */ this.name = name; diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index 050fdd08d..4a827aafb 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -17,6 +17,21 @@ dayjs.extend(utc); const LABEL = 'label'; const RELATION = 'relation'; +/** + * There are many different Note types, some of which are entirely opaque to the + * end user. Those types should be used only for checking against, they are + * not for direct use. + * @typedef {"file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code"} NoteType + */ + +/** + * @typedef {Object} NotePathRecord + * @property {boolean} isArchived + * @property {boolean} isInHoistedSubTree + * @property {Array} notePath + * @property {boolean} isHidden + */ + /** * Trilium's main entity, which can represent text note, image, code note, file attachment etc. * @@ -60,7 +75,7 @@ class BNote extends AbstractBeccaEntity { this.noteId = noteId; /** @type {string} */ this.title = title; - /** @type {string} */ + /** @type {NoteType} */ this.type = type; /** @type {string} */ this.mime = mime; @@ -76,7 +91,10 @@ class BNote extends AbstractBeccaEntity { 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) */ + /** + * set during the deletion operation, before it is completed (removed from becca completely) + * @type {boolean} + */ this.isBeingDeleted = false; // ------ Derived attributes ------ @@ -1166,7 +1184,7 @@ class BNote extends AbstractBeccaEntity { /** * @param {string} [hoistedNoteId='root'] - * @return {Array<{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array, isHidden: boolean}>} + * @return {Array} */ getSortedNotePathRecords(hoistedNoteId = 'root') { const isHoistedRoot = hoistedNoteId === 'root'; diff --git a/src/public/app/entities/fattachment.js b/src/public/app/entities/fattachment.js index 85148abb3..e0c698e96 100644 --- a/src/public/app/entities/fattachment.js +++ b/src/public/app/entities/fattachment.js @@ -1,3 +1,7 @@ +/** + * Attachment is a file directly tied into a note without + * being a hidden child. + */ class FAttachment { constructor(froca, row) { /** @type {Froca} */ @@ -24,7 +28,10 @@ class FAttachment { /** @type {string} */ this.utcDateScheduledForErasureSince = row.utcDateScheduledForErasureSince; - /** @type {int} optionally added to the entity */ + /** + * optionally added to the entity + * @type {int} + */ this.contentLength = row.contentLength; this.froca.attachments[this.attachmentId] = this; diff --git a/src/public/app/entities/fattribute.js b/src/public/app/entities/fattribute.js index cd8ccc4fa..5e36c873f 100644 --- a/src/public/app/entities/fattribute.js +++ b/src/public/app/entities/fattribute.js @@ -1,5 +1,10 @@ import promotedAttributeDefinitionParser from '../services/promoted_attribute_definition_parser.js'; +/** + * There are currently only two types of attributes, labels or relations. + * @typedef {"label" | "relation"} AttributeType + */ + /** * Attribute is an abstract concept which has two real uses - label (key - value pair) * and relation (representing named relationship between source and target note) @@ -17,7 +22,7 @@ class FAttribute { this.attributeId = row.attributeId; /** @type {string} */ this.noteId = row.noteId; - /** @type {string} */ + /** @type {AttributeType} */ this.type = row.type; /** @type {string} */ this.name = row.name; diff --git a/src/public/app/entities/fnote.js b/src/public/app/entities/fnote.js index 848243fd6..01c3cefe5 100644 --- a/src/public/app/entities/fnote.js +++ b/src/public/app/entities/fnote.js @@ -25,6 +25,25 @@ const NOTE_TYPE_ICONS = { "contentWidget": "bx bxs-widget" }; +/** + * There are many different Note types, some of which are entirely opaque to the + * end user. Those types should be used only for checking against, they are + * not for direct use. + * @typedef {"file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code"} NoteType + */ + +/** + * @typedef {Object} NotePathRecord + * @property {boolean} isArchived + * @property {boolean} isInHoistedSubTree + * @property {boolean} isSearch + * @property {Array} notePath + * @property {boolean} isHidden + */ + +/** + * Note is the main node and concept in Trilium. + */ class FNote { /** * @param {Froca} froca @@ -65,8 +84,8 @@ class FNote { /** @type {boolean} */ this.isProtected = !!row.isProtected; /** - * one of 'text', 'code', 'file' or 'render' - * @type {string} + * See {@see NoteType} for info on values. + * @type {NoteType} */ this.type = row.type; /** @@ -371,7 +390,7 @@ class FNote { /** * @param {string} [hoistedNoteId='root'] - * @return {Array<{isArchived: boolean, isInHoistedSubTree: boolean, isSearch: boolean, notePath: Array, isHidden: boolean}>} + * @return {Array} */ getSortedNotePathRecords(hoistedNoteId = 'root') { const isHoistedRoot = hoistedNoteId === 'root'; @@ -450,7 +469,7 @@ class FNote { /** * @param {FAttribute[]} attributes - * @param {string} type + * @param {AttributeType} type * @param {string} name * @return {FAttribute[]} * @private @@ -579,7 +598,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} 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) */ @@ -590,7 +609,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} 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) */ @@ -599,7 +618,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} type - attribute type (label, relation, etc.) * @param {string} name - attribute name * @returns {FAttribute} attribute of the given type and name. If there are more such attributes, first is returned. Returns null if there's no such attribute belonging to this note. */ @@ -610,7 +629,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} type - attribute type (label, relation, etc.) * @param {string} name - attribute name * @returns {FAttribute} attribute of the given type and name. If there are more such attributes, first is returned. Returns null if there's no such attribute belonging to this note. */ @@ -621,7 +640,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} type - attribute type (label, relation, etc.) * @param {string} name - attribute name * @returns {string} attribute value of the given type and name or null if no such attribute exists. */ @@ -632,7 +651,7 @@ class FNote { } /** - * @param {string} type - attribute type (label, relation, etc.) + * @param {AttributeType} type - attribute type (label, relation, etc.) * @param {string} name - attribute name * @returns {string} attribute value of the given type and name or null if no such attribute exists. */ diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index 6272c28e9..4c6807e6e 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -15,6 +15,18 @@ import BasicWidget from "../widgets/basic_widget.js"; import SpacedUpdate from "./spaced_update.js"; import shortcutService from "./shortcuts.js"; + +/** + * A whole number + * @typedef {number} int + */ + +/** + * An instance of the frontend api available globally. + * @global + * @var {FrontendScriptApi} api + */ + /** *

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. api.showMessage(api.startNote.title);

@@ -22,26 +34,44 @@ import shortcutService from "./shortcuts.js"; * @constructor */ function FrontendScriptApi(startNote, currentNote, originEntity = null, $container = null) { - /** @property {jQuery} container of all the rendered script content */ + /** + * Container of all the rendered script content + * @type {jQuery} + * */ this.$container = $container; - /** @property {object} note where the script started executing */ + /** + * Note where the script started executing + * @type {FNote} + */ this.startNote = startNote; - /** @property {object} note where the script is currently executing */ + + /** + * Note where the script is currently executing + * @type {FNote} + */ this.currentNote = currentNote; - /** @property {object|null} entity whose event triggered this execution */ + /** + * Entity whose event triggered this execution + * @type {object|null} + */ this.originEntity = originEntity; - /** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */ + /** + * day.js library for date manipulation. + * See {@link https://day.js.org} for documentation + * @see https://day.js.org + * @type {dayjs} + */ this.dayjs = dayjs; - /** @property {RightPanelWidget} */ + /** @type {RightPanelWidget} */ this.RightPanelWidget = RightPanelWidget; - /** @property {NoteContextAwareWidget} */ + /** @type {NoteContextAwareWidget} */ this.NoteContextAwareWidget = NoteContextAwareWidget; - /** @property {BasicWidget} */ + /** @type {BasicWidget} */ this.BasicWidget = BasicWidget; /** @@ -114,12 +144,12 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @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 {object} opts - * @property {string} [opts.id] - id of the button, used to identify the old instances of this button to be replaced + * @param {string} opts.title + * @param {function} opts.action - callback handling the click on the button + * @param {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" + * @param {string} [opts.icon] - name of the boxicon to be used (e.g. "time" for "bx-time" icon) + * @param {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."); @@ -150,9 +180,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * 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 {Array.} params - list of parameters to the anonymous function to be sent to backend - * @returns {Promise<*>} return value of the executed function on the backend + * @param {string|Function} script - script to be executed on the backend + * @param {Array} params - list of parameters to the anonymous function to be sent to backend + * @returns {Promise} return value of the executed function on the backend */ this.runOnBackend = async (script, params = []) => { if (typeof script === "function") { @@ -300,7 +330,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @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 + * @param {string} [params.title] - custom link tile with note's title as default */ this.createLink = linkService.createLink; diff --git a/src/public/app/widgets/basic_widget.js b/src/public/app/widgets/basic_widget.js index f7de3088a..25145c38f 100644 --- a/src/public/app/widgets/basic_widget.js +++ b/src/public/app/widgets/basic_widget.js @@ -1,5 +1,11 @@ import Component from "../components/component.js"; + +/** + * This is the base widget for all other widgets. + * + * For information on using widgets, see the tutorial {@tutorial widget_basics}. + */ class BasicWidget extends Component { constructor() { super(); @@ -64,6 +70,11 @@ class BasicWidget extends Component { return this; } + /** + * Accepts a string of CSS to add with the widget. + * @param {string} block + * @returns {this} for chaining + */ cssBlock(block) { this.cssEl = block; return this; @@ -112,7 +123,10 @@ class BasicWidget extends Component { } /** - * for overriding + * Method used for rendering the widget. + * + * Your class should override this method. + * @returns {JQuery} Your widget. */ doRender() {} diff --git a/src/public/app/widgets/note_context_aware_widget.js b/src/public/app/widgets/note_context_aware_widget.js index 753edfaa1..1fb7e5de8 100644 --- a/src/public/app/widgets/note_context_aware_widget.js +++ b/src/public/app/widgets/note_context_aware_widget.js @@ -1,7 +1,11 @@ import BasicWidget from "./basic_widget.js"; import appContext from "../components/app_context.js"; -export default class NoteContextAwareWidget extends BasicWidget { +/** + * This widget allows for changing and updating depending on the active note. + * @extends {BasicWidget} + */ +class NoteContextAwareWidget extends BasicWidget { isNoteContext(ntxId) { if (Array.isArray(ntxId)) { return this.noteContext && ntxId.includes(this.noteContext.ntxId); @@ -43,6 +47,9 @@ export default class NoteContextAwareWidget extends BasicWidget { return this.noteContext?.ntxId; } + /** + * @returns {boolean} true when an active note exists + */ isEnabled() { return !!this.note; } @@ -58,6 +65,8 @@ export default class NoteContextAwareWidget extends BasicWidget { } /** + * Override this method to be able to refresh your + * widget with each note. * @param {FNote} note * @returns {Promise} */ @@ -109,3 +118,5 @@ export default class NoteContextAwareWidget extends BasicWidget { await this.refresh(); } } + +export default NoteContextAwareWidget; diff --git a/src/public/app/widgets/right_panel_widget.js b/src/public/app/widgets/right_panel_widget.js index a173dc759..12e3c71a0 100644 --- a/src/public/app/widgets/right_panel_widget.js +++ b/src/public/app/widgets/right_panel_widget.js @@ -9,11 +9,19 @@ const WIDGET_TPL = ` `; -export default class RightPanelWidget extends NoteContextAwareWidget { +/** + * This widget manages rendering panels in the right-hand pane. + * @extends {NoteContextAwareWidget} + */ +class RightPanelWidget extends NoteContextAwareWidget { + /** Title to show in the panel. */ get widgetTitle() { return "Untitled widget"; } get help() { return {}; } + /** + * Do not override this method unless you know what you're doing. + */ doRender() { this.$widget = $(WIDGET_TPL); this.contentSized(); @@ -30,6 +38,13 @@ export default class RightPanelWidget extends NoteContextAwareWidget { this.initialized = this.doRenderBody(); } - /* for overriding */ + /** + * Method used for rendering the body of the widget. + * + * Your class should override this method. + * @returns {JQuery} The body of your widget. + */ async doRenderBody() {} } + +export default RightPanelWidget; \ No newline at end of file diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js index ed0e0902c..1b5c52c25 100644 --- a/src/services/backend_script_api.js +++ b/src/services/backend_script_api.js @@ -20,6 +20,18 @@ const specialNotesService = require("./special_notes"); const branchService = require("./branches"); const exportService = require("./export/zip"); + +/** + * A whole number + * @typedef {number} int + */ + +/** + * An instance of the frontend api available globally. + * @global + * @var {BackendScriptApi} api + */ + /** *

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. api.log(api.startNote.title);

@@ -27,11 +39,20 @@ const exportService = require("./export/zip"); * @constructor */ function BackendScriptApi(currentNote, apiParams) { - /** @property {BNote} note where the script started executing */ + /** + * Note where the script started executing + * @type {BNote} + */ this.startNote = apiParams.startNote; - /** @property {BNote} note where the script is currently executing. Don't mix this up with the concept of active note */ + /** + * Note where the script is currently executing. Don't mix this up with the concept of active note + * @type {BNote} + */ this.currentNote = currentNote; - /** @property {AbstractBeccaEntity} entity whose event triggered this execution */ + /** + * Entity whose event triggered this execution + * @type {AbstractBeccaEntity} + */ this.originEntity = apiParams.originEntity; for (const key in apiParams) { @@ -39,13 +60,20 @@ function BackendScriptApi(currentNote, apiParams) { } /** - * @property {axios} Axios library for HTTP requests. See {@link https://axios-http.com} for documentation + * Axios library for HTTP requests. See {@link https://axios-http.com} for documentation + * @type {axios} * @deprecated use native (browser compatible) fetch() instead */ this.axios = axios; - /** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */ + /** + * day.js library for date manipulation. See {@link https://day.js.org} for documentation + * @type {dayjs} + */ this.dayjs = dayjs; - /** @property {axios} xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation */ + /** + * xml2js library for XML parsing. See {@link https://github.com/Leonidas-from-XIV/node-xml2js} for documentation + * @type {xml2js} + */ this.xml2js = xml2js; /** @@ -206,16 +234,16 @@ function BackendScriptApi(currentNote, apiParams) { /** * @method * - * @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 + * @param {object} params + * @param {string} params.parentNoteId + * @param {string} params.title + * @param {string|Buffer} params.content + * @param {NoteType} params.type - text, code, file, image, search, book, relationMap, canvas + * @param {string} [params.mime] - value is derived from default mimes for type + * @param {boolean} [params.isProtected=false] + * @param {boolean} [params.isExpanded=false] + * @param {string} [params.prefix=''] + * @param {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; @@ -228,14 +256,14 @@ function BackendScriptApi(currentNote, apiParams) { * @param {string} title * @param {string} [content=""] * @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 + * @param {boolean} [extraOptions.json=false] - should the note be JSON + * @param {boolean} [extraOptions.isProtected=false] - should the note be protected + * @param {string} [extraOptions.type='text'] - note type + * @param {string} [extraOptions.mime='text/html'] - MIME type of the note + * @param {object[]} [extraOptions.attributes=[]] - attributes to be created for this note + * @param {AttributeType} extraOptions.attributes.type - attribute type - label, relation etc. + * @param {string} extraOptions.attributes.name - attribute name + * @param {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= {}) => { @@ -370,10 +398,10 @@ function BackendScriptApi(currentNote, apiParams) { * @method * @param {string} parentNoteId - this note's child notes will be sorted * @param {object} [sortConfig] - * @property {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name + * @param {string} [sortConfig.sortBy=title] - 'title', 'dateCreated', 'dateModified' or a label name * See {@link https://github.com/zadam/trilium/wiki/Sorting} for details. - * @property {boolean} [sortConfig.reverse=false] - * @property {boolean} [sortConfig.foldersFirst=false] + * @param {boolean} [sortConfig.reverse=false] + * @param {boolean} [sortConfig.foldersFirst=false] * @returns {void} */ this.sortNotes = (parentNoteId, sortConfig = {}) => treeService.sortNotes( @@ -404,7 +432,7 @@ function BackendScriptApi(currentNote, apiParams) { * * @method * @param {function} func - * @returns {?} result of func callback + * @returns {any} result of func callback */ this.transactional = sql.transactional; @@ -432,7 +460,8 @@ function BackendScriptApi(currentNote, apiParams) { this.unescapeHtml = utils.unescapeHtml; /** - * @property {module:sql} sql + * sql + * @type {module:sql} */ this.sql = sql; @@ -447,18 +476,18 @@ function BackendScriptApi(currentNote, apiParams) { * * @method * @param {object} opts - * @property {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long - * @property {string} opts.type - one of + * @param {string} opts.id - id of the launcher, only alphanumeric at least 6 characters long + * @param {"note" | "script" | "customWidget"} 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" + * @param {string} opts.title + * @param {boolean} [opts.isVisible=false] - if true, will be created in the "Visible launchers", otherwise in "Available launchers" + * @param {string} [opts.icon] - name of the boxicon to be used (e.g. "bx-time") + * @param {string} [opts.keyboardShortcut] - will activate the target note/script upon pressing, e.g. "ctrl+e" + * @param {string} [opts.targetNoteId] - for type "note" + * @param {string} [opts.scriptNoteId] - for type "script" + * @param {string} [opts.widgetNoteId] - for type "customWidget" * @returns {{note: BNote}} */ this.createOrUpdateLauncher = opts => {