mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	ETAPI search endpoint
This commit is contained in:
		| @@ -5,8 +5,24 @@ const mappers = require("./mappers"); | |||||||
| const noteService = require("../services/notes"); | const noteService = require("../services/notes"); | ||||||
| const TaskContext = require("../services/task_context"); | const TaskContext = require("../services/task_context"); | ||||||
| const validators = require("./validators"); | const validators = require("./validators"); | ||||||
|  | const searchService = require("../services/search/services/search"); | ||||||
|  |  | ||||||
| function register(router) { | function register(router) { | ||||||
|  |     ru.route(router, 'get', '/etapi/notes', (req, res, next) => { | ||||||
|  |         const {search} = req.query; | ||||||
|  |  | ||||||
|  |         if (!search?.trim()) { | ||||||
|  |             throw new ru.EtapiError(400, 'SEARCH_QUERY_PARAM_MANDATORY', "'search' query parameter is mandatory"); | ||||||
|  |         } | ||||||
|  |         const searchParams = parseSearchParams(req); | ||||||
|  |  | ||||||
|  |         const foundNotes = searchService.searchNotes(search, searchParams); | ||||||
|  |  | ||||||
|  |         console.log(foundNotes.map(note => mappers.mapNoteToPojo(note))); | ||||||
|  |  | ||||||
|  |         res.json(foundNotes.map(note => mappers.mapNoteToPojo(note))); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     ru.route(router, 'get', '/etapi/notes/:noteId', (req, res, next) => { |     ru.route(router, 'get', '/etapi/notes/:noteId', (req, res, next) => { | ||||||
|         const note = ru.getAndCheckNote(req.params.noteId); |         const note = ru.getAndCheckNote(req.params.noteId); | ||||||
|  |  | ||||||
| @@ -85,6 +101,71 @@ function register(router) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function parseSearchParams(req) { | ||||||
|  |     const rawSearchParams = { | ||||||
|  |         'fastSearch': parseBoolean(req.query, 'fastSearch'), | ||||||
|  |         'includeArchivedNotes': parseBoolean(req.query, 'includeArchivedNotes'), | ||||||
|  |         'ancestorNoteId': req.query['ancestorNoteId'], | ||||||
|  |         'ancestorDepth': parseInteger(req.query, 'ancestorDepth'), | ||||||
|  |         'orderBy': req.query['orderBy'], | ||||||
|  |         'orderDirection': parseOrderDirection(req.query, 'orderDirection'), | ||||||
|  |         'limit': parseInteger(req.query, 'limit'), | ||||||
|  |         'debug': parseBoolean(req.query, 'debug') | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const searchParams = {}; | ||||||
|  |  | ||||||
|  |     for (const paramName of Object.keys(rawSearchParams)) { | ||||||
|  |         if (rawSearchParams[paramName] !== undefined) { | ||||||
|  |             searchParams[paramName] = rawSearchParams[paramName]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return searchParams; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const SEARCH_PARAM_ERROR = "SEARCH_PARAM_VALIDATION_ERROR"; | ||||||
|  |  | ||||||
|  | function parseBoolean(obj, name) { | ||||||
|  |     if (!(name in obj)) { | ||||||
|  |         return undefined; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!['true', 'false'].includes(obj[name])) { | ||||||
|  |         throw new ru.EtapiError(400, SEARCH_PARAM_ERROR, `Cannot parse boolean '${name}' value '${obj[name]}, allowed values are 'true' and 'false'`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return obj[name] === 'true'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function parseInteger(obj, name) { | ||||||
|  |     if (!(name in obj)) { | ||||||
|  |         return undefined; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const integer = parseInt(obj[name]); | ||||||
|  |  | ||||||
|  |     if (!['asc', 'desc'].includes(obj[name])) { | ||||||
|  |         throw new ru.EtapiError(400, SEARCH_PARAM_ERROR, `Cannot parse order direction value '${obj[name]}, allowed values are 'asc' and 'desc'`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return integer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function parseOrderDirection(obj, name) { | ||||||
|  |     if (!(name in obj)) { | ||||||
|  |         return undefined; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const integer = parseInt(obj[name]); | ||||||
|  |  | ||||||
|  |     if (Number.isNaN(integer)) { | ||||||
|  |         throw new ru.EtapiError(400, SEARCH_PARAM_ERROR, `Cannot parse integer '${name}' value '${obj[name]}`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return integer; | ||||||
|  | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     register |     register | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								test-etapi/search.http
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								test-etapi/search.http
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | POST {{triliumHost}}/etapi/create-note | ||||||
|  | Content-Type: application/json | ||||||
|  |  | ||||||
|  | { | ||||||
|  |   "parentNoteId": "root", | ||||||
|  |   "title": "title", | ||||||
|  |   "type": "text", | ||||||
|  |   "content": "{{$uuid}}" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | > {% client.global.set("createdNoteId", response.body.note.noteId); %} | ||||||
|  |  | ||||||
|  | ### | ||||||
|  |  | ||||||
|  | GET {{triliumHost}}/etapi/notes/{{createdNoteId}}/content | ||||||
|  |  | ||||||
|  | > {% client.global.set("content", response.body); %} | ||||||
|  |  | ||||||
|  | ### | ||||||
|  |  | ||||||
|  | GET {{triliumHost}}/etapi/notes?search={{content}} | ||||||
|  |  | ||||||
|  | > {% | ||||||
|  | client.assert(response.status === 200); | ||||||
|  | client.assert(response.body.length === 1); | ||||||
|  | %} | ||||||
|  |  | ||||||
|  | ### Same but with fast search which doesn't look in the content so 0 notes should be found | ||||||
|  |  | ||||||
|  | GET {{triliumHost}}/etapi/notes?search={{content}}&fastSearch=true | ||||||
|  |  | ||||||
|  | > {% | ||||||
|  | client.assert(response.status === 200); | ||||||
|  | client.assert(response.body.length === 0); | ||||||
|  | %} | ||||||
		Reference in New Issue
	
	Block a user