mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	backend script API documentation
This commit is contained in:
		| @@ -20,7 +20,8 @@ | ||||
|     "start-forge": "electron-forge start", | ||||
|     "package-forge": "electron-forge package", | ||||
|     "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": { | ||||
|     "async-mutex": "^0.1.3", | ||||
|   | ||||
| @@ -29,18 +29,16 @@ const BUILTIN_ATTRIBUTES = [ | ||||
| ]; | ||||
|  | ||||
| async function getNotesWithLabel(name, value) { | ||||
|     let notes; | ||||
|     let valueCondition = ""; | ||||
|     let params = [name]; | ||||
|  | ||||
|     if (value !== undefined) { | ||||
|         notes = await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)  | ||||
|           WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, 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]); | ||||
|         valueCondition = " AND attributes.value = ?"; | ||||
|         params.push(value); | ||||
|     } | ||||
|  | ||||
|     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) { | ||||
|   | ||||
							
								
								
									
										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 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'); | ||||
| const BackendScriptApi = require('./backend_script_api'); | ||||
|  | ||||
| function ScriptContext(startNote, allNotes, originEntity = null) { | ||||
|     this.modules = {}; | ||||
|     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 => { | ||||
|         return moduleName => { | ||||
|             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; | ||||
| @@ -111,6 +111,7 @@ async function setNoteToParent(noteId, prefix, parentNoteId) { | ||||
|         } | ||||
|         else { | ||||
|             branch.parentNoteId = parentNoteId; | ||||
|             branch.prefix = prefix; | ||||
|         } | ||||
|  | ||||
|         await branch.save(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user