mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
			v0.56.0-be
			...
			v0.56.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f6ad1c6aa7 | ||
|  | c1127ec429 | ||
|  | 867f7f3f59 | ||
|  | 1c52303bb3 | ||
|  | 876e6caa23 | ||
|  | 34f07b4376 | ||
|  | ffc28c8485 | ||
|  | 913e9ef6e0 | ||
|  | 14fb9c76b0 | ||
|  | c5435009d7 | ||
|  | 1d3132e447 | ||
|  | 63eb22c7ac | ||
|  | c11cf41f30 | ||
|  | 01910d3231 | 
| @@ -1,6 +1,13 @@ | ||||
| #!/bin/sh | ||||
| if wget --spider -S "127.0.0.1:8080/api/health-check" 2>&1 | awk 'NR==2' | grep -w "HTTP/1.1 200 OK" ; then | ||||
|     exit 0 | ||||
| else | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| # Try connecting to /api/health-check using both http and https. | ||||
| # TODO: we should only be connecting with the actual protocol that is enabled | ||||
| # TODO: this assumes we use the default port 8080 | ||||
|  | ||||
| for proto in http https; do | ||||
|     if wget --spider -S "$proto://127.0.0.1:8080/api/health-check" 2>&1 | awk 'NR==2' | grep -w "HTTP/1.1 200 OK" ; then | ||||
|         exit 0 | ||||
|     fi | ||||
| done | ||||
|  | ||||
| exit 1 | ||||
|   | ||||
| @@ -17,21 +17,27 @@ VERSION_DATE=$(git log -1 --format=%aI "v${VERSION}" | cut -c -10) | ||||
| VERSION_COMMIT=$(git rev-list -n 1 "v${VERSION}") | ||||
|  | ||||
| # expecting the directory at a specific path | ||||
| cd ~/trilium-flathub | ||||
| cd ~/trilium-flathub || exit | ||||
|  | ||||
| if ! git diff-index --quiet HEAD --; then | ||||
|     echo "There are uncommitted changes" | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| BASE_BRANCH=master | ||||
|  | ||||
| if [[ "$VERSION" == *"beta"* ]]; then | ||||
|     git switch beta | ||||
| else | ||||
|     git switch master | ||||
|     BASE_BRANCH=beta | ||||
| fi | ||||
|  | ||||
| git switch "${BASE_BRANCH}" | ||||
| git pull | ||||
|  | ||||
| BRANCH=b${VERSION} | ||||
|  | ||||
| git branch "${BRANCH}" | ||||
| git switch "${BRANCH}" | ||||
|  | ||||
| echo "Updating files with version ${VERSION}, date ${VERSION_DATE} and commit ${VERSION_COMMIT}" | ||||
|  | ||||
| flatpak-node-generator npm ../trilium/package-lock.json | ||||
| @@ -45,4 +51,7 @@ git add ./com.github.zadam.trilium.metainfo.xml | ||||
| git add ./com.github.zadam.trilium.yml | ||||
|  | ||||
| git commit -m "release $VERSION" | ||||
| git push | ||||
| git push --set-upstream origin "${BRANCH}" | ||||
|  | ||||
| gh pr create --fill -B "${BASE_BRANCH}" | ||||
| gh pr merge --auto --merge --delete-branch | ||||
|   | ||||
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|   "name": "trilium", | ||||
|   "version": "0.55.1", | ||||
|   "version": "0.56.0-beta", | ||||
|   "lockfileVersion": 2, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "name": "trilium", | ||||
|       "version": "0.55.1", | ||||
|       "version": "0.56.0-beta", | ||||
|       "hasInstallScript": true, | ||||
|       "license": "AGPL-3.0-only", | ||||
|       "dependencies": { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   "name": "trilium", | ||||
|   "productName": "Trilium Notes", | ||||
|   "description": "Trilium Notes", | ||||
|   "version": "0.56.0-beta", | ||||
|   "version": "0.56.1", | ||||
|   "license": "AGPL-3.0-only", | ||||
|   "main": "electron.js", | ||||
|   "bin": { | ||||
| @@ -21,9 +21,9 @@ | ||||
|     "build-frontend-docs": "rm -r ./docs/frontend_api && ./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/collapsible_widget.js", | ||||
|     "build-docs": "npm run build-backend-docs && npm run build-frontend-docs", | ||||
|     "webpack": "npx webpack -c webpack-desktop.config.js && npx webpack -c webpack-mobile.config.js && npx webpack -c webpack-setup.config.js", | ||||
|     "test": "jasmine", | ||||
|     "test-jasmine": "jasmine", | ||||
|     "test-es6": "node -r esm spec-es6/attribute_parser.spec.js ", | ||||
|     "test-all": "npm run test && npm run test-es6", | ||||
|     "test": "npm run test-jasmine && npm run test-es6", | ||||
|     "postinstall": "rimraf ./node_modules/canvas" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|   | ||||
| @@ -210,7 +210,7 @@ const ATTR_HELP = { | ||||
|         "workspaceTemplate": "This note will appear in the selection of available template when creating new note, but only when hoisted into a workspace containing this template", | ||||
|         "searchHome": "new search notes will be created as children of this note", | ||||
|         "hoistedSearchHome": "new search notes will be created as children of this note when hoisted to some ancestor of this note", | ||||
|         "inbox": "default inbox location for new notes", | ||||
|         "inbox": "default inbox location for new notes - when you create a note using \"new note\" button in the sidebar, notes will be created as child notes in the note marked as with <code>#inbox</code> label.", | ||||
|         "hoistedInbox": "default inbox location for new notes when hoisted to some ancestor of this note", | ||||
|         "sqlConsoleHome": "default location of SQL console notes", | ||||
|         "bookmarked": "note with this label will appear in bookmarks", | ||||
| @@ -240,15 +240,15 @@ const ATTR_HELP = { | ||||
|         "keyboardShortcut": "Defines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect." | ||||
|     }, | ||||
|     "relation": { | ||||
|         "runOnNoteCreation": "executes when note is created on backend", | ||||
|         "runOnNoteCreation": "executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script.", | ||||
|         "runOnChildNoteCreation": "executes when new note is created under the note where this relation is defined", | ||||
|         "runOnNoteTitleChange": "executes when note title is changed (includes note creation as well)", | ||||
|         "runOnNoteChange": "executes when note is changed (includes note creation as well)", | ||||
|         "runOnNoteDeletion": "executes when note is being deleted", | ||||
|         "runOnBranchCreation": "executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note.", | ||||
|         "runOnBranchDeletion": "executes when a branch is deleted. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted).", | ||||
|         "runOnChildNoteCreation": "executes when new note is created under this note", | ||||
|         "runOnAttributeCreation": "executes when new attribute is created under this note", | ||||
|         "runOnAttributeChange": "executes when attribute is changed under this note", | ||||
|         "runOnAttributeCreation": "executes when new attribute is created for the note which defines this relation", | ||||
|         "runOnAttributeChange": " executes when the attribute is changed of a note which defines this relation. This is triggered also when the attribute is deleted", | ||||
|         "template": "attached note's attributes will be inherited even without parent-child relationship. See template for details.", | ||||
|         "renderNote": 'notes of type "render HTML note" will be rendered using a code note (HTML or script) and it is necessary to point using this relation to which note should be rendered', | ||||
|         "widget": "target of this relation will be executed and rendered as a widget in the sidebar", | ||||
|   | ||||
| @@ -86,7 +86,7 @@ export default class BacklinksWidget extends NoteContextAwareWidget { | ||||
|         this.clearItems(); | ||||
|  | ||||
|         // can't use froca since that would count only relations from loaded notes | ||||
|         const resp = await server.get(`notes/${this.noteId}/backlink-count`); | ||||
|         const resp = await server.get(`note-map/${this.noteId}/backlink-count`); | ||||
|  | ||||
|         if (!resp || !resp.count) { | ||||
|             this.toggle(false); | ||||
|   | ||||
| @@ -69,7 +69,7 @@ export default class EmptyTypeWidget extends TypeWidget { | ||||
|     } | ||||
|  | ||||
|     async doRefresh(note) { | ||||
|         const workspaceNotes = await searchService.searchForNotes('#workspace'); | ||||
|         const workspaceNotes = await searchService.searchForNotes('#workspace #!template'); | ||||
|  | ||||
|         this.$workspaceNotes.empty(); | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,10 @@ | ||||
| @media print | ||||
| { | ||||
|     html body { | ||||
|         /* https://github.com/zadam/trilium/issues/3202 */ | ||||
|         color: black; | ||||
|     } | ||||
|  | ||||
|     .no-print, .no-print * | ||||
|     { | ||||
|         display: none !important; | ||||
| @@ -8,4 +13,4 @@ | ||||
|     .relation-map-wrapper { | ||||
|         height: 100vh !important; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -287,6 +287,27 @@ function findExcerpts(sourceNote, referencedNoteId) { | ||||
|     return excerpts; | ||||
| } | ||||
|  | ||||
| function getFilteredBacklinks(note) { | ||||
|     return note.getTargetRelations() | ||||
|         // search notes have "ancestor" relations which are not interesting | ||||
|         .filter(note => note.getNote().type !== 'search'); | ||||
| } | ||||
|  | ||||
| function getBacklinkCount(req) { | ||||
|     const {noteId} = req.params; | ||||
|  | ||||
|     const note = becca.getNote(noteId); | ||||
|  | ||||
|     if (!note) { | ||||
|         return [404, "Not found"]; | ||||
|     } | ||||
|     else { | ||||
|         return { | ||||
|             count: getFilteredBacklinks(note).length | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getBacklinks(req) { | ||||
|     const {noteId} = req.params; | ||||
|     const note = becca.getNote(noteId); | ||||
| @@ -295,11 +316,9 @@ function getBacklinks(req) { | ||||
|         return [404, `Note ${noteId} was not found`]; | ||||
|     } | ||||
|  | ||||
|     let backlinks = note.getTargetRelations(); | ||||
|  | ||||
|     let backlinksWithExcerptCount = 0; | ||||
|  | ||||
|     return backlinks.filter(note => !note.getNote().hasLabel('excludeFromNoteMap')).map(backlink => { | ||||
|     return getFilteredBacklinks(note).map(backlink => { | ||||
|         const sourceNote = backlink.note; | ||||
|  | ||||
|         if (sourceNote.type !== 'text' || backlinksWithExcerptCount > 50) { | ||||
| @@ -323,5 +342,6 @@ function getBacklinks(req) { | ||||
| module.exports = { | ||||
|     getLinkMap, | ||||
|     getTreeMap, | ||||
|     getBacklinkCount, | ||||
|     getBacklinks | ||||
| }; | ||||
|   | ||||
| @@ -305,21 +305,6 @@ function uploadModifiedFile(req) { | ||||
|     note.setContent(fileContent); | ||||
| } | ||||
|  | ||||
| function getBacklinkCount(req) { | ||||
|     const {noteId} = req.params; | ||||
|  | ||||
|     const note = becca.getNote(noteId); | ||||
|  | ||||
|     if (!note) { | ||||
|         return [404, "Not found"]; | ||||
|     } | ||||
|     else { | ||||
|         return { | ||||
|             count: note.getTargetRelations().filter(note => !note.getNote().hasLabel('excludeFromNoteMap')).length | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     getNote, | ||||
|     updateNoteContent, | ||||
| @@ -334,6 +319,5 @@ module.exports = { | ||||
|     duplicateSubtree, | ||||
|     eraseDeletedNotesNow, | ||||
|     getDeleteNotesPreview, | ||||
|     uploadModifiedFile, | ||||
|     getBacklinkCount | ||||
|     uploadModifiedFile | ||||
| }; | ||||
|   | ||||
| @@ -264,7 +264,6 @@ function register(app) { | ||||
|     apiRoute(DELETE, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.eraseNoteRevision); | ||||
|     route(GET, '/api/notes/:noteId/revisions/:noteRevisionId/download', [auth.checkApiAuthOrElectron], noteRevisionsApiRoute.downloadNoteRevision); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/restore-revision/:noteRevisionId', noteRevisionsApiRoute.restoreNoteRevision); | ||||
|     apiRoute(GET, '/api/notes/:noteId/backlink-count', notesApiRoute.getBacklinkCount); | ||||
|     apiRoute(POST, '/api/notes/relation-map', notesApiRoute.getRelationMap); | ||||
|     apiRoute(POST, '/api/notes/erase-deleted-notes-now', notesApiRoute.eraseDeletedNotesNow); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/title', notesApiRoute.changeTitle); | ||||
| @@ -306,6 +305,7 @@ function register(app) { | ||||
|  | ||||
|     apiRoute(POST, '/api/note-map/:noteId/tree', noteMapRoute.getTreeMap); | ||||
|     apiRoute(POST, '/api/note-map/:noteId/link', noteMapRoute.getLinkMap); | ||||
|     apiRoute(GET, '/api/note-map/:noteId/backlink-count', noteMapRoute.getBacklinkCount); | ||||
|     apiRoute(GET, '/api/note-map/:noteId/backlinks', noteMapRoute.getBacklinks); | ||||
|  | ||||
|     apiRoute(GET, '/api/special-notes/inbox/:date', specialNotesRoute.getInboxNote); | ||||
|   | ||||
| @@ -28,11 +28,17 @@ function installLocalAppIcon() { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (!fs.existsSync(path.resolve(ELECTRON_APP_ROOT_DIR, "trilium-portable.sh"))) { | ||||
|         // simple heuristic to detect ".tar.xz" linux build (i.e. not flatpak, not debian) | ||||
|         // only in such case it's necessary to create an icon | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const desktopDir = path.resolve(os.homedir(), '.local/share/applications'); | ||||
|  | ||||
|     fs.stat(desktopDir, function (err, stats) { | ||||
|         if (err) { | ||||
|             // Directory doesn't exist so we won't attempt to create the .desktop file | ||||
|             // Directory doesn't exist, so we won't attempt to create the .desktop file | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -64,4 +70,4 @@ function getExePath() { | ||||
|  | ||||
| module.exports = { | ||||
|     installLocalAppIcon | ||||
| }; | ||||
| }; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| module.exports = { buildDate:"2022-10-15T12:49:56+02:00", buildRevision: "70c929241391a465a1e818dcb41af30dd176bc34" }; | ||||
| module.exports = { buildDate:"2022-10-22T23:07:24+02:00", buildRevision: "c1127ec4293143e9ff6080cbe9c14a8366a132bd" }; | ||||
|   | ||||
| @@ -40,6 +40,10 @@ function disableEntityEvents() { | ||||
|     namespace.set('disableEntityEvents', true); | ||||
| } | ||||
|  | ||||
| function enableEntityEvents() { | ||||
|     namespace.set('disableEntityEvents', false); | ||||
| } | ||||
|  | ||||
| function isEntityEventsDisabled() { | ||||
|     return !!namespace.get('disableEntityEvents'); | ||||
| } | ||||
| @@ -83,6 +87,7 @@ module.exports = { | ||||
|     getComponentId, | ||||
|     getLocalNowDateTime, | ||||
|     disableEntityEvents, | ||||
|     enableEntityEvents, | ||||
|     isEntityEventsDisabled, | ||||
|     reset, | ||||
|     getAndClearEntityChangeIds, | ||||
|   | ||||
| @@ -33,10 +33,6 @@ function getNewNotePosition(parentNoteId) { | ||||
|     return maxNotePos + 10; | ||||
| } | ||||
|  | ||||
| function triggerChildNoteCreated(childNote, parentNote) { | ||||
|     eventService.emit(eventService.CHILD_NOTE_CREATED, { childNote, parentNote }); | ||||
| } | ||||
|  | ||||
| function triggerNoteTitleChanged(note) { | ||||
|     eventService.emit(eventService.NOTE_TITLE_CHANGED, note); | ||||
| } | ||||
| @@ -140,24 +136,43 @@ function createNewNote(params) { | ||||
|     } | ||||
|  | ||||
|     return sql.transactional(() => { | ||||
|         const note = new Note({ | ||||
|             noteId: params.noteId, // optionally can force specific noteId | ||||
|             title: params.title, | ||||
|             isProtected: !!params.isProtected, | ||||
|             type: params.type, | ||||
|             mime: deriveMime(params.type, params.mime) | ||||
|         }).save(); | ||||
|         let note, branch, isEntityEventsDisabled; | ||||
|  | ||||
|         note.setContent(params.content); | ||||
|         try { | ||||
|             isEntityEventsDisabled = cls.isEntityEventsDisabled(); | ||||
|  | ||||
|         const branch = new Branch({ | ||||
|             branchId: params.branchId, | ||||
|             noteId: note.noteId, | ||||
|             parentNoteId: params.parentNoteId, | ||||
|             notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId), | ||||
|             prefix: params.prefix, | ||||
|             isExpanded: !!params.isExpanded | ||||
|         }).save(); | ||||
|             if (!isEntityEventsDisabled) { | ||||
|                 // it doesn't make sense to run note creation events on a partially constructed note, so | ||||
|                 // defer them until note creation is completed | ||||
|                 cls.disableEntityEvents(); | ||||
|             } | ||||
|  | ||||
|             note = new Note({ | ||||
|                 noteId: params.noteId, // optionally can force specific noteId | ||||
|                 title: params.title, | ||||
|                 isProtected: !!params.isProtected, | ||||
|                 type: params.type, | ||||
|                 mime: deriveMime(params.type, params.mime) | ||||
|             }).save(); | ||||
|  | ||||
|             note.setContent(params.content); | ||||
|  | ||||
|             branch = new Branch({ | ||||
|                 branchId: params.branchId, | ||||
|                 noteId: note.noteId, | ||||
|                 parentNoteId: params.parentNoteId, | ||||
|                 notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId), | ||||
|                 prefix: params.prefix, | ||||
|                 isExpanded: !!params.isExpanded | ||||
|             }).save(); | ||||
|         } | ||||
|         finally { | ||||
|             if (!isEntityEventsDisabled) { | ||||
|                 // re-enable entity events only if there were previously enabled | ||||
|                 // (they can be disabled in case of import) | ||||
|                 cls.enableEntityEvents(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         scanForLinks(note); | ||||
|  | ||||
| @@ -175,7 +190,21 @@ function createNewNote(params) { | ||||
|         } | ||||
|  | ||||
|         triggerNoteTitleChanged(note); | ||||
|         triggerChildNoteCreated(note, parentNote); | ||||
|  | ||||
|         eventService.emit(eventService.ENTITY_CREATED, { | ||||
|             entityName: 'notes', | ||||
|             entity: note | ||||
|         }); | ||||
|  | ||||
|         eventService.emit(eventService.ENTITY_CREATED, { | ||||
|             entityName: 'branches', | ||||
|             entity: branch | ||||
|         }); | ||||
|  | ||||
|         eventService.emit(eventService.CHILD_NOTE_CREATED, { | ||||
|             childNote: note, | ||||
|             parentNote: parentNote | ||||
|         }); | ||||
|  | ||||
|         log.info(`Created new note '${note.noteId}', branch '${branch.branchId}' of type '${note.type}', mime '${note.mime}'`); | ||||
|  | ||||
|   | ||||
| @@ -39,12 +39,25 @@ function getFulltext(tokens, searchContext) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| const OPERATORS = [ | ||||
|     "=", | ||||
|     "!=", | ||||
|     "*=*", | ||||
|     "*=", | ||||
|     "=*", | ||||
|     ">", | ||||
|     ">=", | ||||
|     "<", | ||||
|     "<=", | ||||
|     "%=" | ||||
| ]; | ||||
|  | ||||
| function isOperator(token) { | ||||
|     if (Array.isArray(token)) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     return token.token.match(/^[!=<>*%]+$/); | ||||
|     return OPERATORS.includes(token.token); | ||||
| } | ||||
|  | ||||
| function getExpression(tokens, searchContext, level = 0) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user