mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
ETAPI search endpoint
This commit is contained in:
parent
c5366abf75
commit
c33bc7e12c
@ -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);
|
||||||
|
%}
|
Loading…
x
Reference in New Issue
Block a user