mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	backend script API documentation
This commit is contained in:
		| @@ -20,7 +20,8 @@ | |||||||
|     "start-forge": "electron-forge start", |     "start-forge": "electron-forge start", | ||||||
|     "package-forge": "electron-forge package", |     "package-forge": "electron-forge package", | ||||||
|     "make-forge": "electron-forge make", |     "make-forge": "electron-forge make", | ||||||
|     "publish-forge": "electron-forge publish" |     "publish-forge": "electron-forge publish", | ||||||
|  |     "build-docs": "jsdoc src/entities/*.js src/services/backend_script_api.js" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "async-mutex": "^0.1.3", |     "async-mutex": "^0.1.3", | ||||||
|   | |||||||
| @@ -29,18 +29,16 @@ const BUILTIN_ATTRIBUTES = [ | |||||||
| ]; | ]; | ||||||
|  |  | ||||||
| async function getNotesWithLabel(name, value) { | async function getNotesWithLabel(name, value) { | ||||||
|     let notes; |     let valueCondition = ""; | ||||||
|  |     let params = [name]; | ||||||
|  |  | ||||||
|     if (value !== undefined) { |     if (value !== undefined) { | ||||||
|         notes = await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)  |         valueCondition = " AND attributes.value = ?"; | ||||||
|           WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]); |         params.push(value); | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         notes = await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)  |  | ||||||
|           WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ?`, [name]); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return notes; |     return await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)  | ||||||
|  |           WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ? ${valueCondition} ORDER BY position`, params); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function getNoteWithLabel(name, value) { | async function getNoteWithLabel(name, value) { | ||||||
|   | |||||||
							
								
								
									
										219
									
								
								src/services/backend_script_api.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								src/services/backend_script_api.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | |||||||
|  | const log = require('./log'); | ||||||
|  | const noteService = require('./notes'); | ||||||
|  | const sql = require('./sql'); | ||||||
|  | const utils = require('./utils'); | ||||||
|  | const dateUtils = require('./date_utils'); | ||||||
|  | const attributeService = require('./attributes'); | ||||||
|  | const dateNoteService = require('./date_notes'); | ||||||
|  | const treeService = require('./tree'); | ||||||
|  | const config = require('./config'); | ||||||
|  | const repository = require('./repository'); | ||||||
|  | const axios = require('axios'); | ||||||
|  | const cloningService = require('./cloning'); | ||||||
|  | const messagingService = require('./messaging'); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @constructor | ||||||
|  |  * @hideconstructor | ||||||
|  |  */ | ||||||
|  | function BackendScriptApi(startNote, currentNote, originEntity) { | ||||||
|  |     /** @param {Note} */ | ||||||
|  |     this.startNote = startNote; | ||||||
|  |     /** @param {Note} */ | ||||||
|  |     this.currentNote = currentNote; | ||||||
|  |     /** @param {Entity} */ | ||||||
|  |     this.originEntity = originEntity; | ||||||
|  |  | ||||||
|  |     this.axios = axios; | ||||||
|  |  | ||||||
|  |     this.utils = { | ||||||
|  |         unescapeHtml: utils.unescapeHtml, | ||||||
|  |         isoDateTimeStr: dateUtils.dateStr, | ||||||
|  |         isoDateStr: date => dateUtils.dateStr(date).substr(0, 10) | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Instance name identifies particular Trilium instance. It can be useful for scripts | ||||||
|  |      * if some action needs to happen on only one specific instance. | ||||||
|  |      * | ||||||
|  |      * @returns {string|null} | ||||||
|  |      */ | ||||||
|  |     this.getInstanceName = () => config.General ? config.General.instanceName : null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} noteId | ||||||
|  |      * @returns {Promise<Note|null>} | ||||||
|  |      */ | ||||||
|  |     this.getNote = repository.getNote; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} branchId | ||||||
|  |      * @returns {Promise<Branch|null>} | ||||||
|  |      */ | ||||||
|  |     this.getBranch = repository.getBranch; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} attributeId | ||||||
|  |      * @returns {Promise<Attribute|null>} | ||||||
|  |      */ | ||||||
|  |     this.getAttribute = repository.getAttribute; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} imageId | ||||||
|  |      * @returns {Promise<Image|null>} | ||||||
|  |      */ | ||||||
|  |     this.getImage = repository.getImage; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Retrieves first entity from the SQL's result set. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} SQL query | ||||||
|  |      * @param {Array.<*>} array of params | ||||||
|  |      * @returns {Promise<Entity|null>} | ||||||
|  |      */ | ||||||
|  |     this.getEntity = repository.getEntity; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} SQL query | ||||||
|  |      * @param {Array.<*>} array of params | ||||||
|  |      * @returns {Promise<Array.<Entity>>} | ||||||
|  |      */ | ||||||
|  |     this.getEntities = repository.getEntities; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Retrieves notes with given label name & value | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} name - attribute name | ||||||
|  |      * @param {string} [value] - attribute value | ||||||
|  |      * @returns {Promise<Array.<Note>>} | ||||||
|  |      */ | ||||||
|  |     this.getNotesWithLabel = attributeService.getNotesWithLabel; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Retrieves first note with given label name & value | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} name - attribute name | ||||||
|  |      * @param {string} [value] - attribute value | ||||||
|  |      * @returns {Promise<Note|null>} | ||||||
|  |      */ | ||||||
|  |     this.getNoteWithLabel = attributeService.getNoteWithLabel; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * If there's no branch between note and parent note, create one. Otherwise do nothing. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} noteId | ||||||
|  |      * @param {string} parentNoteId | ||||||
|  |      * @param {string} prefix - if branch will be create between note and parent note, set this prefix | ||||||
|  |      * @returns {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * If there's a branch between note and parent note, remove it. Otherwise do nothing. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} noteId | ||||||
|  |      * @param {string} parentNoteId | ||||||
|  |      * @returns {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.ensureNoteIsAbsentFromParent = cloningService.ensureNoteIsAbsentFromParent; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Based on the value, either create or remove branch between note and parent note. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {boolean} present - true if we want the branch to exist, false if we want it gone | ||||||
|  |      * @param {string} noteId | ||||||
|  |      * @param {string} parentNoteId | ||||||
|  |      * @param {string} prefix - if branch will be create between note and parent note, set this prefix | ||||||
|  |      * @returns {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.toggleNoteInParent = cloningService.toggleNoteInParent; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * | ||||||
|  |      * @param {string} parentNoteId - create new note under this parent | ||||||
|  |      * @param {string} title | ||||||
|  |      * @param {string} [content] | ||||||
|  |      * @params {object} [extraOptions] | ||||||
|  |      * @returns {Promise<Object>} object contains attributes "note" and "branch" which contain newly created entities | ||||||
|  |      */ | ||||||
|  |     this.createNote = noteService.createNote; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Log given message to trilium logs. | ||||||
|  |      * | ||||||
|  |      * @param message | ||||||
|  |      */ | ||||||
|  |     this.log = message => log.info(`Script "${currentNote.title}" (${currentNote.noteId}): ${message}`); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns root note of the calendar. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @returns {Promise<Note|null>} | ||||||
|  |      */ | ||||||
|  |     this.getRootCalendarNote = dateNoteService.getRootCalendarNote; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns day note for given date (YYYY-MM-DD format). If such note doesn't exist, it is created. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} date | ||||||
|  |      * @returns {Promise<Note|null>} | ||||||
|  |      */ | ||||||
|  |     this.getDateNote = dateNoteService.getDateNote; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @method | ||||||
|  |      * @param {string} parentNoteId - this note's child notes will be sorted | ||||||
|  |      * @returns Promise<void> | ||||||
|  |      */ | ||||||
|  |     this.sortNotesAlphabetically = treeService.sortNotesAlphabetically; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * This method finds note by its noteId and prefix and either sets it to the given parentNoteId | ||||||
|  |      * or removes the branch (if parentNoteId is not given). | ||||||
|  |      * | ||||||
|  |      * This method looks similar to toggleNoteInParent() but differs because we're looking up branch by prefix. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @param {string} noteId | ||||||
|  |      * @param {string} prefix | ||||||
|  |      * @param {string} [parentNoteId] | ||||||
|  |      */ | ||||||
|  |     this.setNoteToParent = treeService.setNoteToParent; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * This functions wraps code which is supposed to be running in transaction. If transaction already | ||||||
|  |      * exists, then we'll use that transaction. | ||||||
|  |      * | ||||||
|  |      * This method is required only when script has label manualTransactionHandling, all other scripts are | ||||||
|  |      * transactional by default. | ||||||
|  |      * | ||||||
|  |      * @method | ||||||
|  |      * @params {function} func | ||||||
|  |      * @returns {Promise<?>} result of func callback | ||||||
|  |      */ | ||||||
|  |     this.transactional = sql.transactional; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Trigger tree refresh in all connected clients. This is required when some tree change happens in | ||||||
|  |      * the backend. | ||||||
|  |      * | ||||||
|  |      * @returns {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.refreshTree = () => messagingService.sendMessageToAllClients({ type: 'refresh-tree' }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = BackendScriptApi; | ||||||
| @@ -1,21 +1,10 @@ | |||||||
| const log = require('./log'); |  | ||||||
| const noteService = require('./notes'); |  | ||||||
| const sql = require('./sql'); |  | ||||||
| const utils = require('./utils'); | const utils = require('./utils'); | ||||||
| const dateUtils = require('./date_utils'); | const BackendScriptApi = require('./backend_script_api'); | ||||||
| const attributeService = require('./attributes'); |  | ||||||
| const dateNoteService = require('./date_notes'); |  | ||||||
| const treeService = require('./tree'); |  | ||||||
| const config = require('./config'); |  | ||||||
| const repository = require('./repository'); |  | ||||||
| const axios = require('axios'); |  | ||||||
| const cloningService = require('./cloning'); |  | ||||||
| const messagingService = require('./messaging'); |  | ||||||
|  |  | ||||||
| function ScriptContext(startNote, allNotes, originEntity = null) { | function ScriptContext(startNote, allNotes, originEntity = null) { | ||||||
|     this.modules = {}; |     this.modules = {}; | ||||||
|     this.notes = utils.toObject(allNotes, note => [note.noteId, note]); |     this.notes = utils.toObject(allNotes, note => [note.noteId, note]); | ||||||
|     this.apis = utils.toObject(allNotes, note => [note.noteId, new ScriptApi(startNote, note, originEntity)]); |     this.apis = utils.toObject(allNotes, note => [note.noteId, new BackendScriptApi(startNote, note, originEntity)]); | ||||||
|     this.require = moduleNoteIds => { |     this.require = moduleNoteIds => { | ||||||
|         return moduleName => { |         return moduleName => { | ||||||
|             const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId)); |             const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId)); | ||||||
| @@ -30,51 +19,4 @@ function ScriptContext(startNote, allNotes, originEntity = null) { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| function ScriptApi(startNote, currentNote, originEntity) { |  | ||||||
|     this.startNote = startNote; |  | ||||||
|     this.currentNote = currentNote; |  | ||||||
|     this.originEntity = originEntity; |  | ||||||
|  |  | ||||||
|     this.axios = axios; |  | ||||||
|  |  | ||||||
|     this.utils = { |  | ||||||
|         unescapeHtml: utils.unescapeHtml, |  | ||||||
|         isoDateTimeStr: dateUtils.dateStr, |  | ||||||
|         isoDateStr: date => dateUtils.dateStr(date).substr(0, 10) |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     this.getInstanceName = () => config.General ? config.General.instanceName : null; |  | ||||||
|  |  | ||||||
|     this.getNote = repository.getNote; |  | ||||||
|     this.getBranch = repository.getBranch; |  | ||||||
|     this.getAttribute = repository.getAttribute; |  | ||||||
|     this.getImage = repository.getImage; |  | ||||||
|     this.getEntity = repository.getEntity; |  | ||||||
|     this.getEntities = repository.getEntities; |  | ||||||
|  |  | ||||||
|     this.createAttribute = attributeService.createAttribute; |  | ||||||
|     this.getNotesWithLabel = attributeService.getNotesWithLabel; |  | ||||||
|     this.getNoteWithLabel = attributeService.getNoteWithLabel; |  | ||||||
|  |  | ||||||
|     this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent; |  | ||||||
|     this.ensureNoteIsAbsentFromParent = cloningService.ensureNoteIsAbsentFromParent; |  | ||||||
|  |  | ||||||
|     this.toggleNoteInParent = cloningService.toggleNoteInParent; |  | ||||||
|  |  | ||||||
|     this.createNote = noteService.createNote; |  | ||||||
|  |  | ||||||
|     this.log = message => log.info(`Script ${currentNote.noteId}: ${message}`); |  | ||||||
|  |  | ||||||
|     this.getRootCalendarNote = dateNoteService.getRootCalendarNote; |  | ||||||
|     this.getDateNote = dateNoteService.getDateNote; |  | ||||||
|  |  | ||||||
|     this.sortNotesAlphabetically = treeService.sortNotesAlphabetically; |  | ||||||
|  |  | ||||||
|     this.setNoteToParent = treeService.setNoteToParent; |  | ||||||
|  |  | ||||||
|     this.transactional = sql.transactional; |  | ||||||
|  |  | ||||||
|     this.refreshTree = () => messagingService.sendMessageToAllClients({ type: 'refresh-tree' }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = ScriptContext; | module.exports = ScriptContext; | ||||||
| @@ -111,6 +111,7 @@ async function setNoteToParent(noteId, prefix, parentNoteId) { | |||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             branch.parentNoteId = parentNoteId; |             branch.parentNoteId = parentNoteId; | ||||||
|  |             branch.prefix = prefix; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await branch.save(); |         await branch.save(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user