mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01:00 
			
		
		
		
	ETAPI search endpoint
This commit is contained in:
		@@ -5,8 +5,24 @@ const mappers = require("./mappers");
 | 
			
		||||
const noteService = require("../services/notes");
 | 
			
		||||
const TaskContext = require("../services/task_context");
 | 
			
		||||
const validators = require("./validators");
 | 
			
		||||
const searchService = require("../services/search/services/search");
 | 
			
		||||
 | 
			
		||||
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) => {
 | 
			
		||||
        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 = {
 | 
			
		||||
    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