mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	added date services to ETAPI
This commit is contained in:
		| @@ -36,7 +36,11 @@ export default class RootContainer extends FlexContainer { | ||||
|         this.refresh(); | ||||
|     } | ||||
|  | ||||
|     noteTypeMimeChangedEvent() { | ||||
|     entitiesReloadedEvent({loadResults}) { | ||||
|         const note = appContext.tabManager.getActiveContextNote(); | ||||
|          | ||||
|         if (note && loadResults.isNoteReloaded(note.noteId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,12 +3,12 @@ const utils = require("../../services/utils"); | ||||
| const noteService = require("../../services/notes"); | ||||
| const attributeService = require("../../services/attributes"); | ||||
| const Branch = require("../../becca/entities/branch"); | ||||
| const cls = require("../../services/cls.js"); | ||||
| const sql = require("../../services/sql.js"); | ||||
| const log = require("../../services/log.js"); | ||||
| const cls = require("../../services/cls"); | ||||
| const sql = require("../../services/sql"); | ||||
| const log = require("../../services/log"); | ||||
| const specialNotesService = require("../../services/special_notes"); | ||||
| const dateNotesService = require("../../services/date_notes"); | ||||
| const entityChangesService = require("../../services/entity_changes.js"); | ||||
| const sqlInit = require("../../services/sql_init.js"); | ||||
| const passwordService = require("../../services/password.js"); | ||||
|  | ||||
| const GENERIC_CODE = "GENERIC"; | ||||
|  | ||||
| @@ -23,21 +23,21 @@ function sendError(res, statusCode, code, message) { | ||||
|         })); | ||||
| } | ||||
|  | ||||
| function sendNoteNotFoundError(res, noteId) { | ||||
|     return sendError(res, 404, "NOTE_NOT_FOUND",`Note ${noteId} not found`); | ||||
| const sendNoteNotFoundError = (res, noteId) => sendError(res, 404, "NOTE_NOT_FOUND", `Note ${noteId} not found`); | ||||
| const sendBranchNotFoundError = (res, branchId) => sendError(res, 404, "BRANCH_NOT_FOUND", `Branch ${branchId} not found`); | ||||
| const sendAttributeNotFoundError = (res, attributeId) => sendError(res, 404, "ATTRIBUTE_NOT_FOUND", `Attribute ${attributeId} not found`); | ||||
| const sendDateInvalidError = (res, date) => sendError(res, 400, "DATE_INVALID", `Date "${date}" is not valid.`); | ||||
| const sendMonthInvalidError = (res, month) => sendError(res, 400, "MONTH_INVALID", `Month "${month}" is not valid.`); | ||||
| const sendYearInvalidError = (res, year) => sendError(res, 400, "YEAR_INVALID", `Year "${year}" is not valid.`); | ||||
|  | ||||
| function isValidDate(date) { | ||||
|     if (!/[0-9]{4}-[0-9]{2}-[0-9]{2}/.test(date)) { | ||||
|         return false; | ||||
|     } | ||||
|      | ||||
| function sendBranchNotFoundError(res, branchId) { | ||||
|     return sendError(res, 404, "BRANCH_NOT_FOUND",`Branch ${branchId} not found`); | ||||
|     return !!Date.parse(date); | ||||
| } | ||||
|  | ||||
| function sendAttributeNotFoundError(res, attributeId) { | ||||
|     return sendError(res, 404, "ATTRIBUTE_NOT_FOUND",`Attribute ${attributeId} not found`); | ||||
| } | ||||
|  | ||||
| // TODO: | ||||
| // * add date/month/year functions | ||||
|  | ||||
| function checkEtapiAuth(req, res, next) { | ||||
|     if (false) { | ||||
|         sendError(res, 401, "NOT_AUTHENTICATED", "Not authenticated"); | ||||
| @@ -71,6 +71,72 @@ function register(router) { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     route('get', '/etapi/inbox/:date', (req, res, next) => { | ||||
|         const {date} = req.params; | ||||
|          | ||||
|         if (!isValidDate(date)) { | ||||
|             return sendDateInvalidError(res, date); | ||||
|         } | ||||
|          | ||||
|         const note = specialNotesService.getInboxNote(date); | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|      | ||||
|     route('get', '/etapi/date/:date', (req, res, next) => { | ||||
|         const {date} = req.params; | ||||
|  | ||||
|         if (!isValidDate(date)) { | ||||
|             return sendDateInvalidError(res, date); | ||||
|         } | ||||
|  | ||||
|         const note = dateNotesService.getDateNote(date); | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|      | ||||
|     route('get', '/etapi/week/:date', (req, res, next) => { | ||||
|         const {date} = req.params; | ||||
|  | ||||
|         if (!isValidDate(date)) { | ||||
|             return sendDateInvalidError(res, date); | ||||
|         } | ||||
|  | ||||
|         const note = dateNotesService.getWeekNote(date); | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|      | ||||
|     route('get', '/etapi/month/:month', (req, res, next) => { | ||||
|         const {month} = req.params; | ||||
|  | ||||
|         if (!/[0-9]{4}-[0-9]{2}/.test(month)) { | ||||
|             return sendMonthInvalidError(res, month); | ||||
|         } | ||||
|  | ||||
|         const note = dateNotesService.getMonthNote(month); | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|      | ||||
|     route('get', '/etapi/year/:year', (req, res, next) => { | ||||
|         const {year} = req.params; | ||||
|  | ||||
|         if (!/[0-9]{4}/.test(year)) { | ||||
|             return sendYearInvalidError(res, year); | ||||
|         } | ||||
|  | ||||
|         const note = dateNotesService.getYearNote(year); | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|       | ||||
|     route('get', '/etapi/notes/:noteId', (req, res, next) => { | ||||
|         const {noteId} = req.params; | ||||
|         const note = becca.getNote(noteId); | ||||
|  | ||||
|         if (!note) { | ||||
|             return sendNoteNotFoundError(res, noteId); | ||||
|         } | ||||
|  | ||||
|         res.json(mapNoteToPojo(note)); | ||||
|     }); | ||||
|      | ||||
|     route('get', '/etapi/notes/:noteId', (req, res, next) => { | ||||
|         const {noteId} = req.params; | ||||
|         const note = becca.getNote(noteId); | ||||
| @@ -197,6 +263,16 @@ function register(router) { | ||||
|             return sendError(res, 400, GENERIC_CODE, e.message); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     route('post' ,'/etapi/refresh-note-ordering/:parentNoteId', (req, res, next) => { | ||||
|         const {parentNoteId} = req.params; | ||||
|          | ||||
|         if (!becca.getNote(parentNoteId)) { | ||||
|             return sendNoteNotFoundError(res, parentNoteId); | ||||
|         } | ||||
|          | ||||
|         entityChangesService.addNoteReorderingEntityChange(parentNoteId, "etapi"); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function mapNoteToPojo(note) { | ||||
|   | ||||
| @@ -49,7 +49,7 @@ function getRootCalendarNote() { | ||||
| } | ||||
|  | ||||
| /** @returns {Note} */ | ||||
| function getYearNote(dateStr, rootNote) { | ||||
| function getYearNote(dateStr, rootNote = null) { | ||||
|     if (!rootNote) { | ||||
|         rootNote = getRootCalendarNote(); | ||||
|     } | ||||
|   | ||||
| @@ -38,7 +38,7 @@ function initNotSyncedOptions(initialized, opts = {}) { | ||||
| const defaultOptions = [ | ||||
|     { name: 'noteRevisionSnapshotTimeInterval', value: '600', isSynced: true }, | ||||
|     { name: 'protectedSessionTimeout', value: '600', isSynced: true }, | ||||
|     { name: 'zoomFactor', value: '1.0', isSynced: false }, | ||||
|     { name: 'zoomFactor', value: process.platform === "win32" ? '0.9' : '1.0', isSynced: false }, | ||||
|     { name: 'overrideThemeFonts', value: 'false', isSynced: false }, | ||||
|     { name: 'mainFontFamily', value: 'theme', isSynced: false }, | ||||
|     { name: 'mainFontSize', value: '100', isSynced: false }, | ||||
|   | ||||
							
								
								
									
										91
									
								
								test-etapi/create-entities.http
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								test-etapi/create-entities.http
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| POST {{triliumHost}}/etapi/notes | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|   "parentNoteId": "root", | ||||
|   "title": "Hello", | ||||
|   "type": "text", | ||||
|   "content": "Hi there!" | ||||
| } | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|         client.assert(response.body.note.title == "Hello"); | ||||
|         client.assert(response.body.branch.parentNoteId == "root"); | ||||
|     }); | ||||
|  | ||||
|     client.log(`Created note "${createdNoteId}" and branch ${createdBranchId}`); | ||||
|      | ||||
|     client.global.set("createdNoteId", response.body.note.noteId); | ||||
|     client.global.set("createdBranchId", response.body.branch.branchId); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/notes/{{createdNoteId}} | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|         client.assert(response.body.noteId == client.global.get("createdNoteId")); | ||||
|         client.assert(response.body.title == "Hello"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/notes/{{createdNoteId}}/content | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|         client.assert(response.body == "Hi there!"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/branches/{{createdBranchId}} | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|         client.assert(response.body.branchId == client.global.get("createdBranchId")); | ||||
|         client.assert(response.body.parentNoteId == "root"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| POST {{triliumHost}}/etapi/attributes | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|   "noteId": "{{createdNoteId}}", | ||||
|   "type": "label", | ||||
|   "name": "mylabel", | ||||
|   "value": "val", | ||||
|   "isInheritable": "true" | ||||
| } | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
|  | ||||
|     client.log(`Created attribute ${response.body.attributeId}`); | ||||
|      | ||||
|     client.global.set("createdAttributeId", response.body.attributeId); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/attributes/{{createdAttributeId}} | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|         client.assert(response.body.attributeId == client.global.get("createdAttributeId")); | ||||
|     }); | ||||
| %} | ||||
| @@ -1,39 +0,0 @@ | ||||
| POST {{triliumHost}}/etapi/notes | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|   "parentNoteId": "root", | ||||
|   "title": "Hello", | ||||
|   "type": "text", | ||||
|   "content": "Hi there!" | ||||
| } | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
|  | ||||
|     client.global.set("createdNoteId", response.body.note.noteId); | ||||
|     client.global.set("createdBranchId", response.body.note.branchId); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| POST {{triliumHost}}/etapi/attributes | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|   "noteId": "{{createdNoteId}}", | ||||
|   "type": "label", | ||||
|   "name": "mylabel", | ||||
|   "value": "val", | ||||
|   "isInheritable": "true" | ||||
| } | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
|  | ||||
|     client.global.set("createdAttributeId", response.body.attributeId); | ||||
| %} | ||||
							
								
								
									
										94
									
								
								test-etapi/get-date-notes.http
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								test-etapi/get-date-notes.http
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| GET {{triliumHost}}/etapi/inbox/2022-01-01 | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/date/2022-01-01 | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/date/2022-1 | ||||
|  | ||||
| > {% | ||||
|     client.test("Correct error handling", function() { | ||||
|         client.assert(response.status === 400, "Response status is not 400"); | ||||
|         client.assert(response.body.code == "DATE_INVALID"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/week/2022-01-01 | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/week/2022-1 | ||||
|  | ||||
| > {% | ||||
|     client.test("Correct error handling", function() { | ||||
|         client.assert(response.status === 400, "Response status is not 400"); | ||||
|         client.assert(response.body.code == "DATE_INVALID"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/month/2022-01 | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/month/2022-1 | ||||
|  | ||||
| > {% | ||||
|     client.test("Correct error handling", function() { | ||||
|         client.assert(response.status === 400, "Response status is not 400"); | ||||
|         client.assert(response.body.code == "MONTH_INVALID"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/year/2022 | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{triliumHost}}/etapi/year/202 | ||||
|  | ||||
| > {% | ||||
|     client.test("Correct error handling", function() { | ||||
|         client.assert(response.status === 400, "Response status is not 400"); | ||||
|         client.assert(response.body.code == "YEAR_INVALID"); | ||||
|     }); | ||||
| %} | ||||
|  | ||||
| ### | ||||
|  | ||||
							
								
								
									
										7
									
								
								test-etapi/other.http
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test-etapi/other.http
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| POST {{triliumHost}}/etapi/refresh-note-ordering/root | ||||
|  | ||||
| > {% | ||||
|     client.test("Request executed successfully", function() { | ||||
|         client.assert(response.status === 200, "Response status is not 200"); | ||||
|     }); | ||||
| %} | ||||
		Reference in New Issue
	
	Block a user