You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	API: Add ability to search by folder or tag title
This commit is contained in:
		| @@ -131,6 +131,23 @@ class Command extends BaseCommand { | ||||
| 		lines.push(''); | ||||
| 		lines.push('Call **GET /search?query=YOUR_QUERY** to search for notes. This end-point supports the `field` parameter which is recommended to use so that you only get the data that you need. The query syntax is as described in the main documentation: https://joplinapp.org/#searching'); | ||||
| 		lines.push(''); | ||||
| 		lines.push('To retrieve non-notes items, such as notebooks or tags, add a `type` parameter and set it to the required [item type name](#item-type-id). In that case, full text search will not be used - instead it will be a simple case-insensitive search. You can also use `*` as a wildcard. This is convenient for example to retrieve notebooks or tags by title.'); | ||||
| 		lines.push(''); | ||||
| 		lines.push('For example, to retrieve the notebook named "recipes": **GET /search?query=recipes&type=folder**'); | ||||
| 		lines.push('To retrieve all the tags that start with "project-": **GET /search?query=project-*&type=tag**'); | ||||
| 		lines.push(''); | ||||
|  | ||||
| 		lines.push('# Item type IDs'); | ||||
| 		lines.push(''); | ||||
| 		lines.push('Item type IDs might be refered to in certain object you will retrieve from the API. This is the correspondance between name and ID:'); | ||||
| 		lines.push(''); | ||||
| 		lines.push('Name | Value'); | ||||
| 		lines.push('---- | -----'); | ||||
| 		for (const t of BaseModel.typeEnum_) { | ||||
| 			const value = t[1]; | ||||
| 			lines.push(`${BaseModel.modelTypeToName(value)} | ${value}   `); | ||||
| 		} | ||||
| 		lines.push(''); | ||||
|  | ||||
| 		for (let i = 0; i < models.length; i++) { | ||||
| 			const model = models[i]; | ||||
|   | ||||
| @@ -1190,6 +1190,39 @@ class Application extends BaseApplication { | ||||
| 		return cssString; | ||||
| 	} | ||||
|  | ||||
| 	// async createManyNotes() { | ||||
| 	// 	return; | ||||
| 	// 	const folderIds = []; | ||||
|  | ||||
| 	// 	const randomFolderId = (folderIds) => { | ||||
| 	// 		if (!folderIds.length) return ''; | ||||
| 	// 		const idx = Math.floor(Math.random() * folderIds.length); | ||||
| 	// 		if (idx > folderIds.length - 1) throw new Error('Invalid index ' + idx + ' / ' + folderIds.length); | ||||
| 	// 		return folderIds[idx]; | ||||
| 	// 	} | ||||
|  | ||||
| 	// 	let rootFolderCount = 0; | ||||
| 	// 	let folderCount = 100; | ||||
|  | ||||
| 	// 	for (let i = 0; i < folderCount; i++) { | ||||
| 	// 		let parentId = ''; | ||||
|  | ||||
| 	// 		if (Math.random() >= 0.9 || rootFolderCount >= folderCount / 10) { | ||||
| 	// 			parentId = randomFolderId(folderIds); | ||||
| 	// 		} else { | ||||
| 	// 			rootFolderCount++; | ||||
| 	// 		} | ||||
|  | ||||
| 	// 		const folder = await Folder.save({ title: 'folder' + i, parent_id: parentId }); | ||||
| 	// 		folderIds.push(folder.id); | ||||
| 	// 	} | ||||
|  | ||||
| 	// 	for (let i = 0; i < 10000; i++) { | ||||
| 	// 		const parentId = randomFolderId(folderIds); | ||||
| 	// 		Note.save({ title: 'note' + i, parent_id: parentId }); | ||||
| 	// 	} | ||||
| 	// } | ||||
|  | ||||
| 	async start(argv) { | ||||
| 		const electronIsDev = require('electron-is-dev'); | ||||
|  | ||||
|   | ||||
							
								
								
									
										62
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										62
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -654,8 +654,7 @@ | ||||
|             "ansi-regex": { | ||||
|               "version": "2.1.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "aproba": { | ||||
|               "version": "1.2.0", | ||||
| @@ -676,14 +675,12 @@ | ||||
|             "balanced-match": { | ||||
|               "version": "1.0.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "brace-expansion": { | ||||
|               "version": "1.1.11", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "balanced-match": "^1.0.0", | ||||
|                 "concat-map": "0.0.1" | ||||
| @@ -698,20 +695,17 @@ | ||||
|             "code-point-at": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "concat-map": { | ||||
|               "version": "0.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "console-control-strings": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "core-util-is": { | ||||
|               "version": "1.0.2", | ||||
| @@ -828,8 +822,7 @@ | ||||
|             "inherits": { | ||||
|               "version": "2.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "ini": { | ||||
|               "version": "1.3.5", | ||||
| @@ -841,7 +834,6 @@ | ||||
|               "version": "1.0.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "number-is-nan": "^1.0.0" | ||||
|               } | ||||
| @@ -856,7 +848,6 @@ | ||||
|               "version": "3.0.4", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "brace-expansion": "^1.1.7" | ||||
|               } | ||||
| @@ -864,14 +855,12 @@ | ||||
|             "minimist": { | ||||
|               "version": "0.0.8", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "minipass": { | ||||
|               "version": "2.3.5", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "safe-buffer": "^5.1.2", | ||||
|                 "yallist": "^3.0.0" | ||||
| @@ -890,7 +879,6 @@ | ||||
|               "version": "0.5.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "minimist": "0.0.8" | ||||
|               } | ||||
| @@ -971,8 +959,7 @@ | ||||
|             "number-is-nan": { | ||||
|               "version": "1.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "object-assign": { | ||||
|               "version": "4.1.1", | ||||
| @@ -984,7 +971,6 @@ | ||||
|               "version": "1.4.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "wrappy": "1" | ||||
|               } | ||||
| @@ -1070,8 +1056,7 @@ | ||||
|             "safe-buffer": { | ||||
|               "version": "5.1.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "safer-buffer": { | ||||
|               "version": "2.1.2", | ||||
| @@ -1107,7 +1092,6 @@ | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "code-point-at": "^1.0.0", | ||||
|                 "is-fullwidth-code-point": "^1.0.0", | ||||
| @@ -1127,7 +1111,6 @@ | ||||
|               "version": "3.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "ansi-regex": "^2.0.0" | ||||
|               } | ||||
| @@ -1171,14 +1154,12 @@ | ||||
|             "wrappy": { | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "yallist": { | ||||
|               "version": "3.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
| @@ -1196,15 +1177,13 @@ | ||||
|           "version": "1.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", | ||||
|           "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|           "dev": true | ||||
|         }, | ||||
|         "is-glob": { | ||||
|           "version": "2.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", | ||||
|           "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "is-extglob": "^1.0.0" | ||||
|           } | ||||
| @@ -1606,8 +1585,7 @@ | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.0.tgz", | ||||
|       "integrity": "sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ==", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|       "dev": true | ||||
|     }, | ||||
|     "boxen": { | ||||
|       "version": "3.2.0", | ||||
| @@ -3531,15 +3509,13 @@ | ||||
|           "version": "1.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", | ||||
|           "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|           "dev": true | ||||
|         }, | ||||
|         "is-glob": { | ||||
|           "version": "2.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", | ||||
|           "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "is-extglob": "^1.0.0" | ||||
|           } | ||||
| @@ -5119,7 +5095,6 @@ | ||||
|       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", | ||||
|       "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", | ||||
|       "dev": true, | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "remove-trailing-separator": "^1.0.1" | ||||
|       } | ||||
| @@ -5438,8 +5413,7 @@ | ||||
|           "version": "1.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", | ||||
|           "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|           "dev": true | ||||
|         }, | ||||
|         "is-glob": { | ||||
|           "version": "2.0.1", | ||||
| @@ -6009,15 +5983,13 @@ | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", | ||||
|       "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|       "dev": true | ||||
|     }, | ||||
|     "repeat-element": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", | ||||
|       "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|       "dev": true | ||||
|     }, | ||||
|     "repeat-string": { | ||||
|       "version": "1.6.1", | ||||
|   | ||||
| @@ -77,6 +77,15 @@ class BaseModel { | ||||
| 		throw new Error(`Unknown model type: ${type}`); | ||||
| 	} | ||||
|  | ||||
| 	static modelNameToType(name) { | ||||
| 		for (let i = 0; i < BaseModel.typeEnum_.length; i++) { | ||||
| 			const e = BaseModel.typeEnum_[i]; | ||||
| 			const eName = e[0].substr(5).toLowerCase(); | ||||
| 			if (eName === name) return e[1]; | ||||
| 		} | ||||
| 		throw new Error(`Unknown model name: ${name}`); | ||||
| 	} | ||||
|  | ||||
| 	static hasField(name) { | ||||
| 		let fields = this.fieldNames(); | ||||
| 		return fields.indexOf(name) >= 0; | ||||
| @@ -192,8 +201,15 @@ class BaseModel { | ||||
| 		if (!options) options = {}; | ||||
| 		if (!options.fields) options.fields = '*'; | ||||
|  | ||||
| 		let q = this.applySqlOptions(options, `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``); | ||||
| 		return this.modelSelectAll(q.sql); | ||||
| 		let sql = `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``; | ||||
| 		let params = []; | ||||
| 		if (options.where) { | ||||
| 			sql += ` WHERE ${options.where}`; | ||||
| 			if (options.whereParams) params = params.concat(options.whereParams); | ||||
| 		} | ||||
|  | ||||
| 		let q = this.applySqlOptions(options, sql, params); | ||||
| 		return this.modelSelectAll(q.sql, q.params); | ||||
| 	} | ||||
|  | ||||
| 	static async byIds(ids, options = null) { | ||||
|   | ||||
| @@ -162,6 +162,7 @@ class ClipperServer { | ||||
| 					const msg = []; | ||||
| 					if (httpCode >= 500) msg.push('Internal Server Error'); | ||||
| 					if (error.message) msg.push(error.message); | ||||
| 					if (error.stack) msg.push(`\n\n${error.stack}`); | ||||
|  | ||||
| 					writeResponse(httpCode, { error: msg.join(': ') }); | ||||
| 				} | ||||
|   | ||||
| @@ -247,7 +247,21 @@ class Api { | ||||
| 		const query = request.query.query; | ||||
| 		if (!query) throw new ErrorBadRequest('Missing "query" parameter'); | ||||
|  | ||||
| 		return await SearchEngineUtils.notesForQuery(query, this.notePreviewsOptions_(request)); | ||||
| 		const queryType = request.query.type ? BaseModel.modelNameToType(request.query.type) : BaseModel.TYPE_NOTE; | ||||
|  | ||||
| 		if (queryType !== BaseItem.TYPE_NOTE) { | ||||
| 			const ModelClass = BaseItem.getClassByItemType(queryType); | ||||
| 			const options = {}; | ||||
| 			const fields = this.fields_(request, []); | ||||
| 			if (fields.length) options.fields = fields; | ||||
| 			const sqlQueryPart = query.replace(/\*/g, '%'); | ||||
| 			options.where = 'title LIKE ?'; | ||||
| 			options.whereParams = [sqlQueryPart]; | ||||
| 			options.caseInsensitive = true; | ||||
| 			return await ModelClass.all(options); | ||||
| 		} else { | ||||
| 			return await SearchEngineUtils.notesForQuery(query, this.notePreviewsOptions_(request)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async action_folders(request, id = null, link = null) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user